-1

The below example looks cool, but invoking enum methods like that does not work. Why? Can you point me to relevant reference docs, workarounds?

class Scratch {
    enum MyEnum {
        ONE{
            void test1 (String v1, String v2){}
        },
        TWO{
            void test2(int v3){}
        }
    }

    public static void main(String[] args) {
        MyEnum.ONE.test1("a","b");
        MyEnum.TWO.test2(0);
    }
}
starball
  • 20,030
  • 7
  • 43
  • 238
Hristo Stoyanov
  • 1,508
  • 3
  • 15
  • 24
  • 2
    Does this answer your question? [What are enums and why are they useful?](https://stackoverflow.com/questions/4709175/what-are-enums-and-why-are-they-useful) – AztecCodes Jul 27 '23 at 17:39
  • 1
    @AztecCodes: I agree completely: `You should always use enums when a variable (especially a method parameter) can only take one out of a small set of possible values....If you use enums instead of integers (or String codes), you increase compile-time checking and avoid errors from passing in invalid constants, and you document which values are legal to use.`. Personally, I liked Pascal [enumeration types](https://wiki.freepascal.org/Enum_Type). And personally, I think what the OP is trying to do is a bit of an "overreach" ... and I'm unsurprised it "doesn't work". Q: Why not just a "class"? – paulsm4 Jul 27 '23 at 17:59
  • 1
    Use a _class_ with _nested classes_, to achieve what you're looking to do here. – Reilas Jul 27 '23 at 18:03
  • You can, and should, edit this question to improve it. You said that the example "does not work". If you got a compiler error, please include a copy of the error message. If you ran the code, please include the expected result and actual result. – Old Dog Programmer Jul 27 '23 at 19:41
  • @AztecCodes - not really. – Hristo Stoyanov Jul 28 '23 at 23:14
  • @Relias - yes, I could do that in several other ways. But I am curious why enums do not allow it. – Hristo Stoyanov Jul 28 '23 at 23:14
  • @OldDogProgrammer - it does not compile, pretty easy to run it yourself and see. – Hristo Stoyanov Jul 28 '23 at 23:14
  • @stuartmarks Any opinion on that? – Hristo Stoyanov Jul 28 '23 at 23:29
  • 1
    @HristoStoyanov, Yes. But, part of writing a good question is not just saying something "does not work". Writing a good question includes something about *why* it doesn't (seem) to work. It is *your* responsibility to include that in the question. – Old Dog Programmer Jul 28 '23 at 23:39
  • what would be the point of creating an enum like this? if the methods are individual to each enum, then just implement them as separate methods on a class. you gain nothing by putting them on an enum. what are you trying to accomplish? – jtahlborn Jul 29 '23 at 02:02

1 Answers1

3

Those methods are methods of each individual enum instance, similar to a method declared within an anonymous class, and just like an anonymous class, the methods are not visible to variables of the parent type. Since ONE and TWO are instances of the MyEnum enum, the only methods visible to them are the ones declared in the enum itself, and also, of course, any inherited methods from the parent of all enums, java.lang.Enum.

To make the method visible, it must be declared as a method of the enum itself:

class Scratch {
    enum MyEnum {
        ONE {
            public void test1(String v1, String v2) { }
        },
        TWO {
            public void test2(int v3) { }
        };

        public void test1(String v1, String v2) { }

        public void test2(int v3) { }
    }

    public static void main(String[] args) {
        MyEnum.ONE.test1("a", "b");
        MyEnum.ONE.test2(0);

        // remember that an enum variable can be re-assigned, and so 
        // all visible methods should be methods of the MyEnum type
        MyEnum foo = MyEnum.ONE;
        foo = MyEnum.TWO;
    }
}

Remember that an enum variable can be re-assigned, and any enum variable should be able to potentially call the same methods.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • I know that putting the 2 methods at the MyEnum level works, but is is awkward and does not scale - test1() might no work for TWO at all, do I have to throw runtime exceptions? I deliberately made the test1() and test2() with different signature to avoid that trap of thinking. You assignment example makes sense, but only in the cases where you want to treat all MyEnums equally. In my example, I deliberately pick specific enums, so to show that I do not care about the common MyEnum. – Hristo Stoyanov Jul 28 '23 at 23:18
  • btw, i had my example wrong, so you answer is somewhat correct for the wrong example. Sorry! – Hristo Stoyanov Jul 28 '23 at 23:33
  • What you're looking for isn't what Java enums are. You may instead want something like a base class with a private constructor, and the nested classes that extend it (the private constructor means that only those nested classes can invoke that constructor, meaning they're the only classes that can extend that base class). – yshavit Jul 28 '23 at 23:41