4

我写 Java 已经 6 年了,所以请原谅生锈。

我正在使用需要传递Class对象的库方法。由于我必须动态多次调用此方法,每次使用稍微不同的Class参数,我想将其传递给匿名类。

但是,到目前为止,我能找到的所有文档/教程都只讨论了实例化匿名类,例如

new className(optional argument list){classBody}

new interfaceName(){classBody}

我可以定义一个匿名类而不实例化它吗?或者,也许更清楚,我可以Class为匿名类创建一个对象吗?

4

6 回答 6

2

不幸的是,您无法在此处避开实例化。但是,您可以将其设为无操作:

foo((new Object() { ... }).getClass());

当然,如果您必须从某个在构造函数中执行某些操作的类派生,这可能不是一个选项。

编辑

您的问题还说您想调用foo“每次都使用略有不同的 Class 参数”。上面不会这样做,因为仍然会有一个匿名内部类定义,即使你把 new-expression 放在一个循环中。因此,与命名类定义相比,它不会真正为您购买任何东西。特别是,如果您尝试捕获某些局部变量的值,则将使用传递给它foo的对象创建的匿名类的新实例将不会捕获它们。Class

于 2009-07-25T19:34:28.437 回答
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等字节码操作库构建动态类。另一种方法是使用动态代理,但这种方法的缺点是您只能代理接口方法(因此您需要 Java 接口)。

于 2009-07-25T20:02:51.127 回答
0

You can access the class object of an anonymous class by calling .getClass() on it immediately after creation. But what good would that do?

I think the key is in this part of what you said:

I'm working with a library method that requires that I pass it Class objects.

Why does it want you to pass it Class objects? What does this library do with the Class objects you pass it? Instantiate objects? But if so, what constructor does it use and how does it decide what arguments to pass? I don't know what library you are using or what it does, but I would guess that it always creates objects using the no-argument constructor. However, that will not work for anonymous classes anyway, since they have no public constructor (and in any case, to instantiate any non-static inner class, a reference to the outer instance must be provided, so there is no no-argument constructor).

于 2013-04-11T08:18:39.707 回答
0

您只能引用匿名类 ONCE。如果您不在那里实例化它,则无法实例化它,因为您没有它的名称。

因此,我相信匿名类只能与“new BaseClass()”结合使用。

在您的情况下,您会将 BaseClass 对象传递给您的方法,并在需要传递对象时在源代码中实例化匿名对象。

于 2009-07-25T19:23:16.027 回答
0

你不能访问匿名类的 Class 对象而不实例化它。但是,如果您只需要访问该类,您可以在您的方法中定义本地类,并使用 ClassName.class 文字语法来引用这些类。

于 2009-07-25T20:14:06.533 回答
0

您可以假设匿名类的名称并调用Class.forName("mypackage.MyBaseClass$1")以获取匿名类的句柄。这将为您提供在您的 中定义的第一个匿名类MyBaseClass,因此这是一种相当脆弱的引用类的方式。

我怀疑您尝试做的任何事情都可以做得更好。你真正想要达到什么目的?也许我们可以建议一种不需要您通过Class这种方式的方式。

于 2009-07-25T22:17:47.750 回答