所以我正在制作一个迷你游戏,想在游戏重新启动时随机获得一个新的竞技场。 每个竞技场都是一个Java类,因为每个竞技场上的数据都会发生变化,而且在我加载和卸载地图时也是如此。
然后我进入ArrayList<String>
,每次都需要做new Class
。
之所以使用它的字符串,是因为我不希望类被实例化,因为加载器位于每个地图的构造函数中
我曾尝试使用class.forName()
函数然后应用newInstance()
似乎没有帮助。
public class Arena {
private ArrayList<String> maps;
private Class currentMap;
public Arena() {
setMaps();
setNewMap();
}
private void setMaps() {
maps = new ArrayList<String>() {
{
add("Beach");
add("CandyLand");
add("Forest");
add("Frozen");
add("Space");
}
};
}
private void setNewMap() {
Random rand = new Random();
int n = rand.nextInt(4); // count includes 0
try {
currentMap = (Class) Class.forName(this.maps.get(n)).newInstance();
} catch (IllegalAccessException | ClassNotFoundException | InstantiationException e) {
e.printStackTrace();
}
}
public Class getCurrentMap() {
return currentMap;
}
public ArrayList<String> getMaps() {
return maps;
}
}
我希望获得与new Class
相同功能的结果。只需从数组中获取Class。
答案 0 :(得分:2)
Class.forName(this.maps.get(n)).newInstance()
很好。当然,您不应将其强制转换为Class
,因为它们不是Class
的实例。您的班级有一个共同的基础班吗?然后就是要上课的班级。
您不使用完全限定名称。也许你应该。
答案 1 :(得分:0)
我怀疑您的工作太复杂了。
使用Java 13中预览的新switch
语句功能,您可以轻松地做到这一点。
int i = ThreadLocalRandom.current().nextInt( 1 , 6 ); // Half-open: origin is inclusive while the bound is exclusive.
Arena arena = switch ( i )
{
case 1 -> new Beach();
case 2 -> new CandyLand();
case 3 -> new Forest();
case 4 -> new Frozen();
case 5 -> new Space();
default -> null;
};
System.out.println( "BASIL - Done." );
只需两行代码(kinda-sorta)。无需费心Class
类和反思。
顺便说一句,你的声明:
其字符串之所以是因为我不希望该类在加载器位于每个地图的构造函数中之前就被实例化
...对我来说毫无意义。我怀疑您是在尝试避免不存在的问题。
尽管如此,您还是问过如何与Class
搏斗,所以去了。
我会避免使用字符串。在这里使用字符串没有任何价值。您知道将要实例化的特定类集。因此,将其中的List
,容纳List
个对象的Class
做成一个。我们可以随机选择这些Class
对象之一来实例化该类型的对象。
将您的课程放在一个包中。我将使用一个名为arena
的软件包。导入该软件包。
import work.basil.example.arena.* ;
Arena
创建一个接口Arena
,所有五个类都将实现该接口。
package work.basil.example.arena;
public interface Arena
{
}
我们的五个Arena
实现类中的每一个都看起来像这样。当我们看到控制台输出时,我们将知道构造函数已成功运行。
package work.basil.example.arena;
public class Beach implements Arena
{
public Beach ( )
{
System.out.println( "BASIL - Constructing Beach. " );
}
}
制作一个List
对象,该对象包含Class
个对象,每个对象代表游戏应用中使用的类。 Java 9及更高版本中的List.of
语法使此过程变得简单,产生了unmodifiable list。
List < Class > classes = List.of( Beach.class , CandyLand.class , Forest.class , Frozen.class , Space.class );
使用ThreadLocalRandom::nextInt
随机选择一个。注意,如何通过使用参数化类型Arena
将所选的类声明为< Arena >
。
int index = ThreadLocalRandom.current().nextInt(0 , classes.size()); // Half-open: origin is inclusive while the bound is exclusive.
Class < Arena > c = classes.get( index );
Class::newInstance
已弃用实例化来自我们随机选择的类的对象。
请注意,您不赞成使用Class::newInstance
的方法。 Javadoc建议使用clazz.getDeclaredConstructor().newInstance()
。
捕获各种可能的异常。
Arena arena = null;
try
{
arena = c.getDeclaredConstructor().newInstance();
} catch ( InstantiationException e )
{
e.printStackTrace();
} catch ( IllegalAccessException e )
{
e.printStackTrace();
} catch ( InvocationTargetException e )
{
e.printStackTrace();
} catch ( NoSuchMethodException e )
{
e.printStackTrace();
}
结束信号。
System.out.println( "BASIL - Done." );
参见类似的code run live at IdeOne.com。
巴西-建设森林。
巴西-完成。