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();
你应该区分声明和定义。
在你的情况,你声明类的变量Test
,并将其分配到源自某种类的一个对象Test
(它是一个匿名类),其中有一些附加的东西在里面。
这个定义后的代码看到t
类的Test
而已,因此它不知道x
和hello
,因为Test
没有他们。
因此,除了反射,不能使用x
和hello
匿名类的定义之后。 是的,开发人员使用这些变量,当他们需要定义内这些变量。
有人提到,你可以调用没有的部分方法和访问变量Test
定义后:
int y = new Test(){
int x = 0;
//System.out.print("" + x);
void hello(){
System.out.print("inside hello\n");
}
}.x;
这可以因为此时做一个对象的类型是知道(这是匿名类)。 只要你指定这个对象Test t
,你失去了这个信息。
它创建了一个匿名内部类。 在这种情况下,它有什么用处。 匿名类一般用于实现一个接口,而无需创建一个全新的类。 当你这样做,你可以根据需要添加尽可能多的成员。 例如:
Runnable r = new Runnable() {
int i = 0;
public void run() {
System.out.println(i++);
}
};
通过这样做,你已经添加了一个计数器,以您的实现Runnable接口(它没有这样一个字段)和每次通话时间r.run();
的递增值获取打印。
使用一个类似的图案A少人为的例子:
private final ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
private final AtomicInteger threadId = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Thread #" + threadId.incrementAndGet());
}
});
在这里,基本实现的ThreadFactory的提供其姓名每一个新的线程Thread #i
。
你的代码创建了一个匿名内部类 。 这是(更多或更少)等效于这样做:
public class Test {
// ...
private class TestAnonymousInner extends Test {
int x = 0;
//System.out.print("" + x);
void hello(){
System.out.print("inside hello\n");
}
}
public static void main(String[] args) {
Test t = new TestAnonymousInner();
// invalid:
// t.hello();
}
}
如果你看一下编译器输出该文件,你会发现一个类似文件名为Test$1.class
-这就是你所定义的匿名类。
由于变量你存储的类型的实例Test
,该字段不是通过它访问。 他们访问通过反射,或从构造函数表达式。 例如, 下面的作品 ,虽然它不是特别有用:
new Test() {
void hello() {
System.out.println("hello()");
}
}.hello(); // should print "hello()"
回复:您的编辑。 start()
是的方法Thread
。 变量tr
也是类型的Thread
,这样你就可以调用它的方法。 只是没有你在AIC添加方法。
由于写的,既不是x或问候可以通过吨所引用的对象的外部访问。 问题是,他们只是在T的匿名类中声明。 他们不是在测试定义,这是不可能投的T参考声明它们的类型,因为它是匿名的。
我已经修改了测试,使其抽象并添加打招呼的抽象声明,允许其从被T所引用的对象外部调用。 我也修改招呼添加使用X的。 这些变化说明访问匿名级功能的两种方式 - 虽然基类或内部。
public abstract class Test {
abstract void hello();
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");
System.out.print("My value of x is "+x);
}
};
t.hello();
}
}