
场景 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 反射这块的知识建议完整的看一遍,能解决你当前的问题和将来衍生出来的其他问题。 |
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 |