3

I recently ran into this error that took me quite a while to figure out.

I thought I should post it on here in case someone else might run into it too, though the probability of that might be extremely low (see below).

I recently started using enum in Java, as follows

public enum State {
    ON, OFF
}

And then, in my object, which extends from Thread, there is a variable called state:

public class Example extends Thread {
    private State state;
    public Example() { state = State.OFF; } // initialize object at OFF state

This will however gives an error at compile time as such:

./Example.java:3: error: cannot find symbol
    state = State.OFF;
                 ^
  symbol:   variable OFF
  location: class State
1 error

1 Answer 1

2

After struggling with this for about an hour, I figured out the problem.

There is in fact a class name State that is a part of the Thread object. Therefore, when I call State.OFF, the compiler is looking for this state, which cannot be found.

You can figure this out by trying to take off the extends Thread part on the class declaration, and it will run fine. If you change the name of the enum type from State to something else, for eg. States, that would be fine too. So you will only run into this problem when extending from Thread and using State as the name.

Just as an FYI, you can find out all the different states for the Thread object by doing:

for (State s : State.values() {
    System.out.println(s);
}

You will get something like:

NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED

Pretty interesting for a rookie like me I must say.

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

4 Comments

Indeed, what you found was the Thread.State defined enumeration that is already defined. When you used State as a type, it referred to this type and not to the one you defined. If you still want to use your own State enumeration you'll need to use its fully qualified name.
The lesson here is: don't extend Thread, implement Runnable and use composition instead. This offers lots of other benefits, such as preventing API clutter and allowing you to easily switch to the Java Executor Framework when it becomes necessary.
It's even mentioned in the documentation: "In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class."
@codesparkle Thanks. I did not know that. I extended Thread based off of the example I read here: csc.villanova.edu/~mdamian/threads/javamonitors.html about monitors in Java. I will keep that in mind the next time and just implements Runnable instead. Thanks!

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.