Java反射运行时性能
这是一项学术活动(免责声明) 我正在构建一个应用程序,它将从尽可能快的速度中获益,因为它将与其他应用程序竞争 我知道,与标准声明相比,使用反射(下面的示例)声明类将遭受巨大的惩罚Java反射运行时性能,java,performance,reflection,Java,Performance,Reflection,这是一项学术活动(免责声明) 我正在构建一个应用程序,它将从尽可能快的速度中获益,因为它将与其他应用程序竞争 我知道,与标准声明相比,使用反射(下面的示例)声明类将遭受巨大的惩罚 Class mDefinition = Class.forName("MySpecialClassString"); Constructor mConstructor = mDefinition.getConstructor(new Class[]{MySpecialClass.class}); myClass = (
Class mDefinition = Class.forName("MySpecialClassString");
Constructor mConstructor = mDefinition.getConstructor(new Class[]{MySpecialClass.class});
myClass = (MySpecialClass) mConstructor.newInstance(this);
但是,在声明了
myClass
之后,如果我以标准方式使用它myClass.myMethod()
我还会受到性能问题的困扰吗,还是会像我以标准方式声明类一样 一旦类被加载,您就应该没事了。开销与检查表示类等的运行时结构有关。以标准方式调用方法应该可以,但是如果您开始按名称或签名搜索方法,这将产生额外的开销。Chris Thompson的答案是正确的。但是,我对您的代码示例感到困惑
这将动态加载该类:
Class mDefinition = Class.forName("MySpecialClassString");
这将为您的类获得一个构造函数
,它将该类的一个实例作为参数。还请注意,您在编译时使用MySpecialClass.class
访问该类:
Constructor mConstructor = mDefinition.getConstructor(new Class[]{MySpecialClass.class});
这是通过将This
传递到构造函数来实例化MySpecialClass
:
myClass = (MySpecialClass) mConstructor.newInstance(this);
基于构造函数参数,这是否意味着我们处于MySpecialClass
的实例方法中?非常困惑
编辑:这更接近我预期看到的内容:
Class<?> mDefinition = Class.forName("MySpecialClassString");
//constructor apparently takes this as argument
Class<?> constructorArgType = this.getClass(); //could be ThisClassName.class
Constructor<?> mConstructor = mDefinition.getConstructor(constructorArgType);
MySpecialInterface mySpecialInstance = (MySpecialInterface)mConstructor.newInstance(this);
无论如何,如果我在这里有误解或不正确,请告诉我。当您第一次实例化该对象时,会有性能损失。一旦类被加载,它就如同它被正常实例化一样,不会有进一步的性能损失 更进一步说,如果使用反射调用方法,将有大约15倍的性能损失(Java中的默认值),之后JVM将重写反射调用,使其与静态编译调用完全相同。因此,一旦JVM重新编译了字节码,即使重复反射的方法调用也不会导致性能下降 有关这方面的更多信息,请参见以下两个链接:
这个(ClassB_对象)一起馈送,因为它们必须调用存在于ClassB_对象上的函数。它可能很凌乱,但很有效。你能建议我采取另一种方法吗?感谢您花时间查看我的代码。我必须说我个人没有使用过动态类加载,这就是为什么我希望得到某人的确认。但是,我的理解是,如果您在代码中直接引用一个类,甚至在编译时可以访问它,那么动态加载它是没有意义的。但是,如果您有一个静态加载的Foo
,它是一个抽象类或接口,并且动态加载的类扩展/实现了Foo
,那么这是有意义的。这样,在动态加载一个类并实例化它之后,您可以将它强制转换为Foo
,并与之交互,而无需进一步思考。当然,Foo
需要以抽象/接口方法声明的形式知道您要对这些动态加载的类执行的所有操作。动态类加载(在我的例子中)只有一个目的,游戏是用一个有地图名称的txt文件提供的。地图是预先给定的,我们可以(应该)每个映射都有不同的策略。因此映射的名称将决定加载哪个类。这些不同的策略是否属于常见的抽象方法?另外,动态加载类的原因是什么-速度?编译时可用的类在运行时需要时才会加载。或者ese映射/行为在运行时之前不可用?
interface MySpecialInterface {
//methods used to interface with dynamically loaded classes
}