自从我写Java以来已经有6年了,所以请原谅我的生锈。
我正在使用一个库方法,该方法要求我传递Class
个对象。因为我必须动态调用这个方法,每次都有一个稍微不同的Class
参数,我想把它传递给一个匿名类。
但是,到目前为止我能够找到的所有文档/教程只讨论实例化匿名类e.g.:
new className(optional argument list){classBody}
new interfaceName(){classBody}
我可以在不实例化的情况下定义匿名类吗?或者,或许更清楚的是,我可以为匿名类创建一个Class
对象吗?
答案 0 :(得分:2)
不幸的是,你无法在这里躲避实例化。但是,你可以把它变为无操作:
foo((new Object() { ... }).getClass());
当然,如果你必须派生出一些在构造函数中执行某些操作的类,这可能不是一个选项。
您的问题还表示您希望每次使用稍微不同的Class参数调用foo
“。上面不会这样做,因为即使你把new-expression放在一个循环中,仍然会有一个匿名内部类定义。因此,与命名类定义相比,它并不会真正为您买任何东西。特别是,如果您尝试捕获某些局部变量的值,foo
将使用传递给它的Class
对象创建的匿名类的新实例将不会让他们被捕获。
答案 1 :(得分:1)
你不能(仅使用JDK类)
public interface Constant {
int value();
}
public static Class<? extends Constant> classBuilder(final int value) {
return new Constant() {
@Override
public int value() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}.getClass();
}
让我们创建两个新的类“参数”类:
Class<? extends Constant> oneClass = createConstantClass(1);
Class<? extends Constant> twoClass = createConstantClass(2);
但是你无法实例化这个类:
Constant one = oneClass.newInstance(); // <--- throws InstantiationException
Constant two = twoClass.newInstance(); // <--- ditto
它将在运行时失败,因为每个匿名类只有一个实例。
但是,您可以使用字节码操作库(例如ASM )在运行时构建动态类。另一种方法是使用dynamic proxies,但这种方法的缺点是你只能代理接口方法(所以你需要一个Java接口)。
答案 2 :(得分:0)
您只能引用匿名类ONCE。如果你没有在那里实例化它,你就无法实例化它,因为你没有它的名字。
因此我相信匿名类只能与“new BaseClass()”一起使用。
在您的情况下,您可以将BaseClass对象传递给执行该工作的方法,并在需要传递对象时在源代码中实例化匿名对象。
答案 3 :(得分:0)
如果不对其进行实例化,则无法访问匿名类的Class对象。但是,如果您只需要访问该类,则可以在方法中定义本地类,并使用ClassName.class文字语法引用这些类。
答案 4 :(得分:0)
您可以假定匿名类的名称并调用Class.forName("mypackage.MyBaseClass$1")
来获取匿名类的句柄。这将为您提供MyBaseClass
中定义的第一个匿名类,因此这是一种引用类的相当脆弱的方法。
我怀疑无论你想做什么都可以做得更好。你真正想要实现的目标是什么?也许我们可以提出一种方法,不要求你以这种方式传递Class
。
答案 5 :(得分:0)
您可以在创建后立即通过调用.getClass()
来访问匿名类的类对象。但那会有什么好处呢?
我认为关键在于你所说的那部分:
我正在使用一个库方法,要求我传递它 对象。
为什么是否要求你传递Class对象?这个库对你传递的Class对象有什么作用?实例化对象?但如果是这样,它使用什么构造函数以及它如何决定传递什么参数?我不知道你正在使用什么库或它做什么,但我猜它总是使用无参数构造函数创建对象。但是,无论如何这对匿名类都不起作用,因为它们没有公共构造函数(并且无论如何,为了实例化任何非静态内部类,必须提供对外部实例的引用,因此没有无参数构造函数)。