什么是实例的局部变量/方法的范围(What is the scope of the local va

2019-08-05 19:51发布

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();

Answer 1:

你应该区分声明和定义。

在你的情况,你声明类的变量Test ,并将其分配到源自某种类的一个对象Test (它是一个匿名类),其中有一些附加的东西在里面。

这个定义后的代码看到t类的Test而已,因此它不知道xhello ,因为Test没有他们。

因此,除了反射,不能使用xhello匿名类的定义之后。 是的,开发人员使用这些变量,当他们需要定义内这些变量。

有人提到,你可以调用没有的部分方法和访问变量Test定义后:

int y = new Test(){
    int x = 0;
    //System.out.print("" + x);
    void hello(){
        System.out.print("inside hello\n");
    }
}.x;

这可以因为此时做一个对象的类型是知道(这是匿名类)。 只要你指定这个对象Test t ,你失去了这个信息。



Answer 2:

它创建了一个匿名内部类。 在这种情况下,它有什么用处。 匿名类一般用于实现一个接口,而无需创建一个全新的类。 当你这样做,你可以根据需要添加尽可能多的成员。 例如:

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



Answer 3:

你的代码创建了一个匿名内部类 。 这是(更多或更少)等效于这样做:

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添加方法。



Answer 4:

由于写的,既不是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();

  }
}


文章来源: What is the scope of the local variable/methods of an instance
标签: java scope