Java 使用枚举和反射在类列表上调用方法
我下载了一个学习Java的项目,发现了一种修改一些大代码块的有趣方法。Java 使用枚举和反射在类列表上调用方法,java,class,reflection,enums,Java,Class,Reflection,Enums,我下载了一个学习Java的项目,发现了一种修改一些大代码块的有趣方法。 我对Java还是新手,我不知道我所做的是更有效还是更危险… 语法1是before,语法2是我的方法 语法1: class Person{ TestClass testClass; TestClass2 testClass2; //etc... public Person(){ testClass = new TestClass(); testClass2 =
我对Java还是新手,我不知道我所做的是更有效还是更危险…
语法1是before,语法2是我的方法 语法1:
class Person{
TestClass testClass;
TestClass2 testClass2;
//etc...
public Person(){
testClass = new TestClass();
testClass2 = new TestClass2();
//etc...
}
void init(){
testClass.init();
testClass2.init();
//etc...
}
}
对
语法2:
而不是做:
person.testclass.doThing();
此方法使用hashmap并将类存储为对象,使用枚举作为键
TestClass tc = (TestClass) person.attribute.get(EnumKey.TEST_CLASS);
tc.doThing();
enum枚举键{
测试类(TestClass.CLASS),
TEST_CLASS2(TestClass2.class);
类握手类;
EnumKey(类握手类){
this.handshakeClass=handshakeClass;
}
}
语法2非常简单,因为每次创建新类时,我不必键入TaskClass的所有抽象方法。我只需要创建一个新的枚举字段,其余的就完成了 但是这个方法好吗?效率高吗?慢一点吗?还是有风险 效率高吗?慢一点吗 您使用的是“反射”,因此,是的,有一些开销 另一种可能是立即构建Hashmap
HashMap<Integer, Object> attribute = new HashMap<>() {{
put(0, new TestClass());
put(1, new TestClass1()) ;
}};
HashMap属性=新HashMap(){{
put(0,新TestClass());
put(1,新TestClass1());
}};
这是一个好方法吗
这实际上取决于您需要做什么,但这是迭代类似类列表并动态更新其他对象的最短方法,是的
您可以通过接口和抽象类进一步扩展它
危险
据我所知没有
在没有枚举的情况下,还有其他一些方法可以实现,比如迭代类路径中的所有文件,但是我想说,枚举更安全有什么方法可以绕过反射吗?我试图使枚举字段的字段(缺少术语)是new TestClass(),而不是TestClass.class,然后是newInstance,但这样每个人的TestClass都是一样的。。。如果需要多个实例,则必须多次调用
new
。您可以直接构建属性
Hashmap,就像您拥有enumsIs一样简单,这里有一个默认的java方法来执行:newTestClass().newInstance();而不是使用TestClass.class.newInstance();,因此,不需要反射newtestclass()。newInstance()
没有真正的意义您可以传递供应商而不是类,例如TestClass::new
。这将更加安全(因为您肯定知道不带参数的构造函数存在并且是可见的——或者,至少您可以调用一个不带参数并返回实例的方法),并避免反射。
class Class2{
void sendTasks(Person p)
for (EnumKey ek : EnumKey.values(){
try {
p.attribute.put(ek, ek.handshakeClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
}
void initTasks(Person p){
for (EnumKey ek : EnumKey.values(){
(TaskClass) tc = p.attribute.get(ek); //NOTE: all stored values (testclass1,2,3,etc) implement the interface TaskClass...
tc.init();
}
}
}
enum EnumKey{
TEST_CLASS(TestClass.class),
TEST_CLASS2(TestClass2.class);
Class<?> handshakeClass;
EnumKey(Class<?> handshakeClass){
this.handshakeClass = handshakeClass;
}
}
HashMap<Integer, Object> attribute = new HashMap<>() {{
put(0, new TestClass());
put(1, new TestClass1()) ;
}};