I am testing the snippet below, I need to know how can I access t.x or t.hello? What is its scope? Do developers define variables in this way?
public class Test{
public Test(){
System.out.print("constructor\n");
}
public static void main(String[] args) {
Test t = new Test(){
int x = 0;
//System.out.print("" + x);
void hello(){
System.out.print("inside hello\n");
}
};
}
Edit
But why this snippet worked
Thread tr = new Thread() {
int loops = 1;
@Override
public void run() {
loops += 1;
}
};
tr.start();
You should distinguish declaration and definition.
In your case you declare a variable of class
Test
and assign it to an object of some class derived fromTest
(it's an anonymous class) which has some additional stuff in it.The code after this definition sees
t
of classTest
only, it knows nothing aboutx
andhello
becauseTest
doesn't have them.So, apart from reflection, you cannot use
x
andhello
after definition of an anonymous class. And yes, developers use such variables when they need these variables inside of definition.It was mentioned that you can call methods and access variables that are not part of
Test
immediately after definition:This can be done because at this point the type of an object is know (it's the anonymous class). As soon as you assign this object to
Test t
, you lose this information.As written, neither x nor hello can be accessed outside the object referenced by t. The problem is that they are only declared in t's anonymous class. They are not defined in Test, and it is not possible to cast the t reference to the type in which they are declared, because it is anonymous.
I have modified Test to make it abstract and add an abstract declaration of hello, allowing it to be called from outside the object referenced by t. I have also modified hello to add a use of x. Those changes illustrate the two ways of accessing anonymous class features - though the base class or internally.
Your code creates an anonymous inner class. It's (more-or-less) equivalent to doing this:
If you look at the compiler output for that file, you'll notice a file named something like
Test$1.class
– that's the anonymous class you've defined.Since the variable you're storing the instance in is of type
Test
, the fields aren't accessible through it. They're accessible through reflection, or from the constructor expression. E.g. the following works, although it's not particularly useful:Re: your edit.
start()
is a method ofThread
. The variabletr
is also of typeThread
, so you can call its methods. Just not methods you add in an AIC.It creates an anonymous inner class. In this case it has little use. Anonymous classes are generally used to implement an interface without creating a whole new class. When you do that, you can add as many members as you want. For example:
By doing that, you have added a counter to your implementation of the Runnable interface (which does not have such a field) and every time you call
r.run();
an incremented value gets printed.A less contrived example that uses a similar pattern:
Here, a basic implementation of ThreadFactory is provided which names each new Thread
Thread #i
.