ArrayList 中存储的实例化 class 的访问方法
Access methods of instantiated class stored in ArrayList
我是 Java 的初学者(我有 JS 背景),我正在尝试做 nature of code 书第 1 章末尾的练习。
我想做的是生成一个实例列表。
我很难理解 Java 如何管理 classes 和实例,所以请多多包涵。
我现在拥有的:
- 创建数组列表
- Select 随机 class 字符串列表中的名称
- 用 Class.forName、getConstructor 和 newInstance
实例化 class
- 在 ArrayList 中存储实例
- 迭代 ArrayList
- 调用方式
代码如下:
import java.util.*;
import java.lang.reflect.*;
List < Object > bugs = new ArrayList < Object > ();
String[] bugList = {
"Bug",
"Fly",
"Bee"
};
void setup() {
String currentClass;
int bugLength = bugList.length;
for (int i = 0; i < 20; i++) {
int chosenClass = getRandNumber(0, bugLength - 1);
currentClass = bugList[chosenClass];
bugs.add(loadClass(currentClass));
}
}
public Object loadClass(String chosenClass) {
String className;
Class <? > cl = null;
Constructor[] cons = null;
Object instance = null;
className = this.getClass().getName() + "$";
try {
cl = Class.forName(className + chosenClass);
} catch (ClassNotFoundException e) {
//
}
try {
cons = cl.getDeclaredConstructors();
} catch (Exception e) {}
try {
instance = cons[0].newInstance(new Object[] {
this
});
} catch (InstantiationException e) {
//
} catch (IllegalAccessException e) {
//
} catch (InvocationTargetException e) {
//
}
return instance;
}
void draw() {
for (int i = 0; i < bugs.size(); i++) {
bugs.get(i).update();
}
}
class Bug {
// Snip
public Bug() {
// Snip
}
public void update() {
// Snip
}
public void render() {
// Snip
}
}
class Fly extends Bug {
public Fly() {
// Snip
}
}
class Bee extends Bug {
public Bee() {
// Snip
}
}
问题出在 draw 函数中,因为我认为它试图从对象而不是我的实例访问名为 "update" 的方法。
是否可以在访问时将对象显式转换为正确的类型?
或者有什么方法可以存储不同的实例类型并直接命名?
或者,正如我在其他地方看到的某人的一段代码,我是不是想对 Java 过于动态化?
您可以在调用 update
之前明确地将对象转换为 Bug
然而
如果您知道 bugs
列表中的所有对象都是 Bug
的子 类 那么您应该将 List<Object> bugs
更改为 List<Bug> bugs
.这样你就可以毫无问题地调用 update()
(如果你将列表传递给代码的其他区域,那么其他代码可以使用列表作为 Bug
的列表而不是对象) .为了使这项工作正常进行,您必须在 loadClass()
和 return 中执行对 Bug
的强制转换 Bug
的实例而不是 Object
。
我是 Java 的初学者(我有 JS 背景),我正在尝试做 nature of code 书第 1 章末尾的练习。
我想做的是生成一个实例列表。 我很难理解 Java 如何管理 classes 和实例,所以请多多包涵。
我现在拥有的:
- 创建数组列表
- Select 随机 class 字符串列表中的名称
- 用 Class.forName、getConstructor 和 newInstance 实例化 class
- 在 ArrayList 中存储实例
- 迭代 ArrayList
- 调用方式
代码如下:
import java.util.*;
import java.lang.reflect.*;
List < Object > bugs = new ArrayList < Object > ();
String[] bugList = {
"Bug",
"Fly",
"Bee"
};
void setup() {
String currentClass;
int bugLength = bugList.length;
for (int i = 0; i < 20; i++) {
int chosenClass = getRandNumber(0, bugLength - 1);
currentClass = bugList[chosenClass];
bugs.add(loadClass(currentClass));
}
}
public Object loadClass(String chosenClass) {
String className;
Class <? > cl = null;
Constructor[] cons = null;
Object instance = null;
className = this.getClass().getName() + "$";
try {
cl = Class.forName(className + chosenClass);
} catch (ClassNotFoundException e) {
//
}
try {
cons = cl.getDeclaredConstructors();
} catch (Exception e) {}
try {
instance = cons[0].newInstance(new Object[] {
this
});
} catch (InstantiationException e) {
//
} catch (IllegalAccessException e) {
//
} catch (InvocationTargetException e) {
//
}
return instance;
}
void draw() {
for (int i = 0; i < bugs.size(); i++) {
bugs.get(i).update();
}
}
class Bug {
// Snip
public Bug() {
// Snip
}
public void update() {
// Snip
}
public void render() {
// Snip
}
}
class Fly extends Bug {
public Fly() {
// Snip
}
}
class Bee extends Bug {
public Bee() {
// Snip
}
}
问题出在 draw 函数中,因为我认为它试图从对象而不是我的实例访问名为 "update" 的方法。
是否可以在访问时将对象显式转换为正确的类型? 或者有什么方法可以存储不同的实例类型并直接命名?
或者,正如我在其他地方看到的某人的一段代码,我是不是想对 Java 过于动态化?
您可以在调用 update
Bug
然而
如果您知道 bugs
列表中的所有对象都是 Bug
的子 类 那么您应该将 List<Object> bugs
更改为 List<Bug> bugs
.这样你就可以毫无问题地调用 update()
(如果你将列表传递给代码的其他区域,那么其他代码可以使用列表作为 Bug
的列表而不是对象) .为了使这项工作正常进行,您必须在 loadClass()
和 return 中执行对 Bug
的强制转换 Bug
的实例而不是 Object
。