Java 生成的匿名类的newInstance上的InstanceionException

Java 生成的匿名类的newInstance上的InstanceionException,java,anonymous-class,instantiationexception,Java,Anonymous Class,Instantiationexception,更新:这或多或少是一个问题,事实证明,在build2中添加一个构造函数以传入局部变量是一种编译器魔法 给定这样的接口: 公共接口IFoo{ 公共int get(); } 下面的代码打印1、1、2,然后在尝试对build2返回的值调用getClass().newInstance()时引发异常,但在对build1返回的值调用getClass().newInstance()时不会引发异常。你知道为什么吗 public class Foo { public static IFoo build1()

更新:这或多或少是一个问题,事实证明,在build2中添加一个构造函数以传入局部变量是一种编译器魔法

给定这样的接口:

公共接口IFoo{
公共int get();
}

下面的代码打印1、1、2,然后在尝试对build2返回的值调用getClass().newInstance()时引发异常,但在对build1返回的值调用getClass().newInstance()时不会引发异常。你知道为什么吗

public class Foo {

 public static IFoo build1() {
  return new IFoo() { public int get() { return 1; } };
 }

 public static IFoo build2(final int v) {
  return new IFoo() { public int get() {return v;} };
 }

 public static void main(String[] args) throws Exception {
  IFoo foo, bar;

  foo = build1();
  System.out.println(foo.get());

  bar = foo.getClass().newInstance();  
  System.out.println(bar.get());

  foo = build2(2);
  System.out.println(foo.get());

  bar = foo.getClass().newInstance();  
  System.out.println(bar.get());
 }
}
我的调试器指出,在newInstance()调用中,getConstructor0正在抛出NoSuchMethodException。

下面是发生的情况:

  • newInstance()
    需要空构造函数
  • 创建访问
    final
    变量的匿名类时,实际上会隐式创建一个字段来保存该值,该值最初会传递给其隐式构造函数
  • 因此,在
    build2
    中创建的
    IFoo
    实际上没有空构造函数
下面是一个片段来说明发生了什么:

import java.lang.reflect.*;
public class Foo {
    interface IFoo { public int get(); }

    public static IFoo build2(final int v) {
        return new IFoo() { public int get() {return v;} };
    }
    public static void main(String[] args) throws Exception {
        Class<?> klazz = build2(42).getClass();
        for (Constructor<?> c : klazz.getDeclaredConstructors()) {
            System.out.println(c);
        }
        // prints: Foo$1(int)
    }
}
import java.lang.reflect.*;
公开课Foo{
接口IFoo{public int get();}
公共静态IFoo构建2(最终int v){
返回新的IFoo(){public int get(){return v;}};
}
公共静态void main(字符串[]args)引发异常{
类klazz=build2(42).getClass();
对于(构造函数c:klazz.getDeclaredConstructors()){
系统输出打印ln(c);
}
//印刷品:Foo$1(整数)
}
}
它显示
Foo$1
(为匿名
IFoo
类指定的二进制名称)只有一个构造函数,并且它采用
int
。这就是它如何
返回v
,因为返回的实际上是这个隐式创建的构造函数分配给隐式创建字段的内容

反编译
Foo$1
(使用例如
javap-c
)以查看生成了哪些字节码是很有指导意义的。您将看到,实际上,当匿名类访问
final
变量时,会发生这种情况

相关问题
可能的副本-好了