Java 有什么优雅的方式动态实例化子类吗

2021-11-02 20:29:42 +08:00
 OnlyO

场景 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();

想实现的效果是后面只需要添加子类,查找子类的方法就不用修改了

2971 次点击
所在节点    Java
24 条回复
leonme
2021-11-02 20:36:30 +08:00
子类上加注解,利用反射
huaouo
2021-11-02 20:38:09 +08:00
Class.forName ?
OnlyO
2021-11-02 20:41:13 +08:00
@huaouo #2 forName 不太好吧,用户输入的就是一个简单的名称
Vegetable
2021-11-02 20:41:24 +08:00
恕我冒昧哈,这是不是 JAVA 程序员面试必备设计模式里边的,工厂模式?
OnlyO
2021-11-02 20:45:04 +08:00
@Vegetable #4 工厂模式需要追加 else if 判断吧,我希望查找这个子类的方法不需要修改.
ikas
2021-11-02 21:07:33 +08:00
1.没有实例化呢,怎么取 x.a,如果改成静态,那与注解又有何区别
2.这种相关类似的代码太多了..无非就是先扫描 /配置类信息,读取标志..然后找到具体类,或者 factory..调用而已
3.😂
OnlyO
2021-11-02 21:15:47 +08:00
@ikas 方法多,所以想找个简单的方式。貌似用 spring 的 @component 最简单
pigspy
2021-11-02 21:21:40 +08:00
有个库叫做 Reflections ,可以做到获取一个类的所有子类
https://github.com/ronmamo/reflections

但是我觉得这不是个好做法
OnlyO
2021-11-02 21:25:17 +08:00
@pigspy 这个类库我写了一半,发现需要硬编码把路径进去,最后没有用
aguesuka
2021-11-02 21:27:54 +08:00
标准库有 SPI. 不过 Spring 会灵活很多.
yidinghe
2021-11-02 21:49:23 +08:00
反射这块的知识建议完整的看一遍,能解决你当前的问题和将来衍生出来的其他问题。
dranfree
2021-11-03 09:21:55 +08:00
可以看看 dubbo 的 SPI 做法
wolfie
2021-11-03 16:39:03 +08:00
工厂扔到 map 里,name 作为 key 。
seedhk
2021-11-03 16:59:00 +08:00
这不就是工厂模式嘛。。。
312ybj
2021-11-03 18:16:58 +08:00
向上转型&向下转型, 具体哪个子类,传个标识符
treeboy
2021-11-03 18:23:42 +08:00
策略模式 + 依赖注入
night98
2021-11-03 22:41:42 +08:00
spring 的 applicationcontext.getbean(接口.class)会获取到所有此接口的实现类,然后将其转为一个 map ,之后直接从 map 中 get 就行
olaloong
2021-11-04 09:17:45 +08:00
如果是 Spring 的话直接 @autowired 到 Map 里,根据别名 get 就是了
Hayson
2021-11-04 13:49:13 +08:00
spring 的话
@autowried
private Map<string,B> map ,根据 Bean 名 get
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()));
}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/812542

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX