java - 在 Java 中实例化大量子类的最有效方法是什么?
问题描述
我正在做一个项目,该项目需要使用大量扩展特定抽象类的类对象。手动实例化需要调用每个对象的单独构造函数,这开始污染我的客户端类。
该项目的原始代码太长,无法在此站点上发布,因此我在下面提供了一个简化示例:
假设有一个名为 Letter 的抽象类:
public abstract class Letter{
String letter;
}
以及扩展 Letter 抽象类的 26 个单独的字母类:
public class A extends Letter{
this.letter = "A";
}
public class B extends Letter{
this.letter = "B";
}
... and so on
这是我寻求帮助的地方 - 有一个名为 Alphabet 的客户端类:
public class Alphabet{
public List<Letter> getLetters(){
List<Letter> letters = new ArrayList<>();
A a = new A();
B b = new B();
C c = new C();
list.add(a);
list.add(b);
list.add(c);
...the list goes on
return letters;
}
}
如您所见,手动实例化每个字母并不理想。我正在寻找一种在运行时动态创建类对象列表的方法。
也许与此类似:
public class Alphabet{
public List<Letter> getLetters(){
List<Letter> letters = getAllClassesExtending(Letter.class);
return letters;
//list would then contain A,B,C,D,E,F,G, etc.
}
}
我最终希望能够创建一个新类并将其自动添加到客户端类中的对象列表中,而无需修改客户端类(例如,我不想显式引用客户端类中的每个字母类) .
解决方案
这听起来像是enum
. an 的常量enum
可以有一个带有代码的类主体,覆盖基类型的方法,甚至声明新字段。
获取所有子类型的实例的任务意味着一组封闭的子类型,它与enum
类型的行为相匹配。
public enum Letter {
A {
@Override
public boolean isVowel() {
return true;
}
},
B, C, D,
E {
@Override
public boolean isVowel() {
return true;
}
},
F, G, H,
I {
@Override
public boolean isVowel() {
return true;
}
}, J, K, L, M, N,
O {
@Override
public boolean isVowel() {
return true;
}
}, P, Q, R, S, T,
U {
@Override
public boolean isVowel() {
return true;
}
}, V, W, X, Y, Z;
;
String letter = name();
public static List<Letter> getLetters() {
return Arrays.asList(values());
}
public boolean isVowel() {
return false;
}
}
这表明覆盖方法是可能的,而且获取所有实例(作为数组)的方法也是免费的。此外,名称本质上是指定的,没有冗余。
如果您希望拥有一组开放的子类,以便在编译代码后进行潜在扩展,您应该查看Service Provider 概念和ServiceLoader
类。这种机制不会自动找到子类,而只会找到那些在文件中META-INF
或通过模块声明声明为服务提供者的子类,另一方面,它为您提供了一个健壮的、已建立的解决方案,该解决方案将由 Java 开发人员维护甚至发展与平台一样,融入新的模块概念。
推荐阅读
- python - 如何在 Python 中打印此输出 [自上而下(偶数)] [自下而上(奇数)]
- php - 下载 php 文件而不是使用 nginx 和 docker 执行
- bootstrap-4 - 如果我们已经有用于创建响应式网站的引导类,为什么还要使用媒体查询
- python - 系列和数据框之间的区别
- c - 声明未定义的行为
- ios - InstantiateViewController(identifier:creator:)' 仅适用于 iOS 13.0 或更高版本
- c++ - Qt - 为什么我在 qml 资源中添加 10Mb 文件后 Visual Studio 2019 无法再编译我的项目?
- bash - 允许自动完成 Ansible playbook 中的标签
- wordpress - 如何从 foreach 循环中删除重复的结果
- javascript - 如何将 react-chartjs-2 与 chartjs-plugin-datasource 集成以在 s3 url 处使用数据源