4

I have a program below:

package com.company;

enum Color {
    RED, GREEN;

    Color() {
        System.out.println(Main.getRegionName(this));
    }
}

public class Main {
    public static String getRegionName(Color region) {
        switch (region) {
            case RED:
                return "red";
            case GREEN:
                return "green";
            default:
                return "false";
        }
    }

    public static void main(String[] args) {
        Main m = new Main();
        Color color = Color.RED;
    }
}

When I run the program, I got the exceptions below:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.company.Main.getRegionName(Main.java:13)
    at com.company.Color.<init>(Main.java:7)
    at com.company.Color.<clinit>(Main.java:4)
    at com.company.Main.main(Main.java:25)
Caused by: java.lang.NullPointerException
    at com.company.Color.values(Main.java:3)
    at com.company.Main$1.<clinit>(Main.java:13)
    ... 4 more

What's the reason for it? Is the 'this' initialized for the Color class when it calls Main.getRegionName(this) in its constructor?

2
  • 4
    No, it's still being constructed. Commented May 1, 2015 at 22:34
  • This is interesting. Printing the name() inside the Color constructor print both RED and GREEN but printing the name in the main function prints just RED Commented May 1, 2015 at 22:56

2 Answers 2

8

The execution of the code can be described like this:

  • Class Loader loads the enum Color.
  • It calls the constructor of Color for the first value, RED.
  • In the constructor, there's a call to method Main#getRegionName.
  • In method Main#getRegionName, the switch will call to the Color#values to obtain the values of the enum for the switch.
  • Since Color values have not been loaded yet, it breaks by a NullPointerException, and the exception gets propagated.

This behavior is noticed by this line in the stacktrace:

Caused by: java.lang.NullPointerException
at com.company.Color.values(Main.java:3)

More info:

Sign up to request clarification or add additional context in comments.

12 Comments

But we can get access to some internal attributes using 'this' pointer? Like: Color(int id) {this.id = id;} ?
@injoy this approach seems very odd to begin with, and shouldn't be used. Why a field of an enum must rely on the values of the enum when creating the values of the enum?
@injoy of course you can, otherwise what would be the point of attributes in enumerations
I don't think values does return null. Just writing values() in an enum constructor throws this exception. Nothing is returned.
@LuiggiMendoza don't understand your comment. It is pretty common to have attributes on an enumeration
|
1

You shouldn't access the object you are constructing from inside the constructor System.out.println(Main.getRegionName(this));

The 'this' pointer is not initialized while you are inside the constructor.

1 Comment

The question is why.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.