场景 class A 有两个子类:
class A{
name="A"
}
下面有两个子类
class B extend A{
name="B"
}
class C extend A{
name="C"
}
我想通过一个函数能够动态的实例化子类 B 或者 C 伪代码:
public A getASubClass(String userInputName)
for (A a: A.subclassList){
if(userInputName == a.name){
return new a();
}
}
throw new Exception();
想实现的效果是后面只需要添加子类,查找子类的方法就不用修改了
1
leonme 2021-11-02 20:36:30 +08:00 via iPhone
子类上加注解,利用反射
|
2
huaouo 2021-11-02 20:38:09 +08:00
Class.forName ?
|
4
Vegetable 2021-11-02 20:41:24 +08:00
恕我冒昧哈,这是不是 JAVA 程序员面试必备设计模式里边的,工厂模式?
|
6
ikas 2021-11-02 21:07:33 +08:00
1.没有实例化呢,怎么取 x.a,如果改成静态,那与注解又有何区别
2.这种相关类似的代码太多了..无非就是先扫描 /配置类信息,读取标志..然后找到具体类,或者 factory..调用而已 3.😂 |
8
pigspy 2021-11-02 21:21:40 +08:00
|
10
aguesuka 2021-11-02 21:27:54 +08:00
标准库有 SPI. 不过 Spring 会灵活很多.
|
11
yidinghe 2021-11-02 21:49:23 +08:00 via Android 2
反射这块的知识建议完整的看一遍,能解决你当前的问题和将来衍生出来的其他问题。
|
12
dranfree 2021-11-03 09:21:55 +08:00
可以看看 dubbo 的 SPI 做法
|
13
wolfie 2021-11-03 16:39:03 +08:00
工厂扔到 map 里,name 作为 key 。
|
14
seedhk 2021-11-03 16:59:00 +08:00
这不就是工厂模式嘛。。。
|
15
312ybj 2021-11-03 18:16:58 +08:00
向上转型&向下转型, 具体哪个子类,传个标识符
|
16
treeboy 2021-11-03 18:23:42 +08:00
策略模式 + 依赖注入
|
17
night98 2021-11-03 22:41:42 +08:00
spring 的 applicationcontext.getbean(接口.class)会获取到所有此接口的实现类,然后将其转为一个 map ,之后直接从 map 中 get 就行
|
19
Hayson 2021-11-04 13:49:13 +08:00 via Android
|
20
CantSee 2021-11-05 11:42:01 +08:00
private static final Map<String,ActiveContext> activeTypeContainer=new ConcurrentHashMap<>();
static { activeTypeContainer.put(ActiveTpEnum.BUYN_MINUS_ONE.getCode(),new ActiveContext(new ActiveAlgorithmBuyNMinusOne())); activeTypeContainer.put(ActiveTpEnum.MCHT_FULL_SUB.getCode(),new ActiveContext(new ActiveAlgorithmFullReduction())); activeTypeContainer.put(ActiveTpEnum.MCHT_RANDOM_SUB.getCode(),new ActiveContext(new ActiveAlgorithmRandomSubtraction())); } |
21
CantSee 2021-11-05 11:42:44 +08:00
根据类型获取实例
|
22
OnlyO OP @CantSee #21 兄弟你给力,不过你这样违法了开闭原则吧,我后期加类型还是要在这里加代码
我用这样的方式实现了 ```java public Type getTypeService(int type) { Reflections reflections = new Reflections("com.xxxx"); Set<Class<?>> classSet = reflections.getTypesAnnotatedWith(CustomAnnotation.class); for (Class<?> aClass : classSet) { CustomAnnotation annotation = aClass.getAnnotation(CustomAnnotation.class); if (type == CustomAnnotation.type()) { try { return (Type) aClass.newInstance(); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); throw new Exc("msg"); } } } throw new Exc("msg"); } ``` |
23
notwaste 2021-11-05 16:46:51 +08:00
我们的做法是在对应的数据库加一个类似 beanName 的字段,下面初始化的时候判断 beanName 字段是否为空,不为空去 getBean beanName
|