10

I can create an empty Java enum type, but when i want to add some methods : i get a "syntax error" (into Eclipse). I found no official documentation about this, so my question is : is it just impossible (so where is it clearly mentioned?) or is it just the compiler which is wrong ?

cedric
  • 103
  • 1
  • 1
  • 4

4 Answers4

19

Yes it's possible. You just need to add a ; to terminate the (empty) list of enum constants:

enum TestEnum {
    ;                         // doesn't compile without this.
    public void hello() {
        System.out.println("Hello World");
    }
}

JLS Syntax Definition for enums

(Note that without any instances, you'll only be able to call the static methods of the Enum.)

Related:

Graham
  • 7,431
  • 18
  • 59
  • 84
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • The hello method would be impossible to call, wouldn't it? I fail to see the point of such a construct. – JB Nizet Sep 06 '11 at 10:00
  • As it stands yes. Perhaps his methods are `static`, I don't know. But yes, I agree with you. It seems a bit awkward. – aioobe Sep 06 '11 at 10:02
  • 3
    Thanks @aioobe for the answer and the link. I want to do this because i think it is a natural, and very easy/understandable, way to implement a non-instanciable class (typically a utility class with only static methods by defintion) : for me it is more natural to say "a non-instanciable class is an enum with no element" (i.e. permitting to use no instance of itself) than to say "it should be implemented with a private constructor throwing an AssertionError" (cf. Effective Java #4). But it is only my point of view, so don't hesitate to challenge me if i'm wrong... – cedric Sep 06 '11 at 13:03
  • NO! You can call the methods on any instance of the Enum. I show an example on this page of doing so by forcing reflection to create such an abomination. – ggb667 Feb 15 '13 at 17:55
6

Of course you can! "Ia! Ia! Cthulhu Fthagn! Ph'nglui mglw'nfah Cthulhu R'lyeh wgah'nagl fhtagn!!"

Original idea: "http://www.theserverside.com/news/thread.tss?thread_id=50190"

Destroy reality at your own risk.

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

enum ThingsThatShouldNotBe {
;
public void HelloWorld() {
    System.out.println(this.name() + " Says Hello!");
}
public static void main(String[] args) throws Exception {
    Constructor<?> con = ThingsThatShouldNotBe.class.getDeclaredConstructors()[0];
    Method[] methods = con.getClass().getDeclaredMethods();
    for (Method m : methods) {
        if (m.getName().equals("acquireConstructorAccessor")) {
            m.setAccessible(true);
            m.invoke(con, new Object[0]);
        }
    }
    Field[] fields = con.getClass().getDeclaredFields();
    Object ca = null;
    for (Field f : fields) {
        if (f.getName().equals("constructorAccessor")) {
            f.setAccessible(true);
            ca = f.get(con);
        }
    }
    Method m = ca.getClass().getMethod("newInstance",
        new Class[] { Object[].class });
    m.setAccessible(true);
    ThingsThatShouldNotBe v = (ThingsThatShouldNotBe) m.invoke(ca, new Object[] { new Object[] { "Cthulhu",
            Integer.MAX_VALUE } });
    System.out.println(v.getClass() + ":" + v.name() + ":" + v.ordinal());
    System.out.println("Say hello Cthulhu!");
    v.HelloWorld();
}
}

Mwu HA HA HA HA HA HA.

If you really need an Enum and you want it to have instance methods, and you have resolved to summon the elder gods of reflection to force this abomination upon the world, then it is useful.

This will definitely confuse the heck out of other developers later.

ggb667
  • 1,881
  • 2
  • 20
  • 44
  • It seems that with unamed modules, more dark magic is required to work around this error: module java.base does not "opens java.lang.reflect" to unnamed module I suspect it should be possible. – Gzorg Oct 24 '22 at 14:43
5

Yes, it is:

You need to add a semicolon (;) to terminate the empty list of enums.
This compiles:

public enum MyEnum {
    ;
    public void method() {

    }
}

Although I can't think what it would be useful for.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 1
    Methods can be useful, when enums are say composed of fields.. so say u have an enum COLORS which has an int representation, short string representation as well a display string representation.. then this enum can have methods like getInteger(), getShortString(), getDisplayString().. so for example it be shown on the GUI using the getDisplayString() option... maybe stored in the DB using getShortString() option... – Scorpion Sep 06 '11 at 10:17
  • 2
    I think what Bohemian means is that he can't think of anything useful with an *empty* enum with methods. – aioobe Sep 06 '11 at 10:23
  • 1
    Yes - any such instance methods would be inaccessible. Further, I can't think of much useful to do with an empty enum. – Bohemian Sep 06 '11 at 10:53
  • I don't think there is a way to call this method - so agreed, not useful at all! – user85421 Sep 06 '11 at 10:54
  • If you really need an Enum and you want it to have instance methods, and you have resolved to summon the elder gods of reflection to force this abomination upon the world, then it is useful. – ggb667 Feb 15 '13 at 17:56
  • 1
    @GGB667 what on earth are talking about? What has this answer to do with reflection? This would have use for as a placeholder during development that you could code against until you knew what the instances were (tenuous, I admit, but hardly Lovecraftian) – Bohemian Feb 15 '13 at 19:42
  • Ok, well that's true. But I was thinking about production code, not development! And in the example I gave above, I used reflection to force it into existance after the fact. – ggb667 Sep 13 '13 at 17:38
  • That way you can call non-static methods of something that doesn't really exist at compile time. I would say it's Lovecraftian because it will really throw other developers off who are trying to decipher why their IDE provides no actual enumeration values, yet enumerations exist at runtime, and have methods that are called (such as iterating a list of them and invoking methods on them). – ggb667 Sep 11 '14 at 20:20
1

Absoulely,

/**
 * @author The Elite Gentleman
 * @since 06 September 2011
 *
 */
public enum ExampleEnum {
    WHAT_ENUM
    ;

    public void doOperation() {

    }
}

Later:

ExampleEnum exEnum = ExampleEnum.WHAT_ENUM;
exEnum.doOperation();
Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228