How to create a getter method for an abstract method that is inside an enum in Java?

Tags:



I have an enum that contains an non-public abstract method and I can not change the visibility of this abstract method. The abstract method is implemented for every single unit inside the enum.

I am trying to access this method from another package for the purposes of unit testing, but I can not because it is not visible in the other package. Is there a way where I can create a getter method for an abstract method?

Is there a different way to do the unit test in a way that does not involve using a getter method or changing the visibility of the abstract method?

Here is an example of the code I am working with:

public enum random {
    A{
    someFunction() {
        System.out.println("A");
    }
    }
    B{
    someFunction() {
    System.out.println("B");
    }
    }
    C{
    someFunction() {
    System.out.println("C");
    }
    }

    abstract void someFunction();
};

Answer

There are two ways you can do this. One way, like you suggested in your question, is to use a public method to expose your package-private method. Here’s a short example of such a program:

public enum MyEnum {
    A {
        @Override
        void someFunction() {
            System.out.println("A");
        }
    },
    B {
        @Override
        void someFunction() {
            System.out.println("B");
        }
    },
    C {
        @Override
        void someFunction() {
            System.out.println("C");
        }
    };

    abstract void someFunction();

    public void someFunctionPublic() {
        // Here I'm just calling the package-private method from a public method:
        someFunction();
    }
}
public class Other {
    public static void main(String[] args) {
        // Here I call my public method:
        MyEnum.A.someFunctionPublic();
    }
}

Output will be:

A

The other way is to use something called reflection. You mentioned that you wanted a way to access the method without creating a getter method. This is how you can do just that:

// This is exactly how you had it, no changes:
public enum MyEnum {
    A {
        @Override
        void someFunction() {
            System.out.println("A");
        }
    },
    B {
        @Override
        void someFunction() {
            System.out.println("B");
        }
    },
    C {
        @Override
        void someFunction() {
            System.out.println("C");
        }
    };

    abstract void someFunction();
}
public class Other {
    // Note the throws clauses, this is important because I call methods that throw checked exceptions:
    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        // Get a handle on the method:
        Method method = MyEnum.class.getDeclaredMethod("someFunction");

        // Set it to be accessible (since you specified it to be package-private):
        method.setAccessible(true);

        // Invoke it using the implementation in MyEnum.A:
        method.invoke(MyEnum.A);
    }
}

Output will be:

A

Please note that reflection can get out of hand quite quickly, especially if you start renaming methods and/or changing the method headers. Useful for testing, yes, but I would keep it out of production code. Also, a small terminology thing, you refer to “methods” as “functions” in your question. A method is a function that belongs to an Object, so since Java is entirely object-oriented, there are no functions in Java.



Source: stackoverflow