如何使用 ClassName 为字符串来执行“new Class”?

所以我正在制作一个迷你游戏,并希望在游戏重新启动时随机获得一个新的竞技场。每个竞技场都是一个 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。只需从数组中获取类即可。


杨魅力
浏览 135回答 2
2回答

偶然的你

Class.forName(this.maps.get(n)).newInstance()就很好了。当然,您不应该将其转换为Class,因为它们不是 的实例Class。你们的类有一个共同的基类吗?这就是要投射到的类。您没有使用完全限定名称。也许你应该。

幕布斯7119047

简单的方法我怀疑你让你的工作变得太复杂了。switch借助Java 13 中预览的新语句功能,您可以简单地执行此操作。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." );只需 2 行代码(有点像)。也没有阶级和反思的争论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对象的对象,每个对象代表游戏应用程序中使用的类。List.ofJava 9 及更高版本中的语法使此过程变得简单,生成不可修改的列表。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." );
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java