亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 ClassName 為字符串來執行“new Class”?

如何使用 ClassName 為字符串來執行“new Class”?

楊魅力 2023-07-19 10:57:31
所以我正在制作一個迷你游戲,并希望在游戲重新啟動時隨機獲得一個新的競技場。每個競技場都是一個 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。只需從數組中獲取類即可。
查看完整描述

2 回答

?
偶然的你

TA貢獻1841條經驗 獲得超3個贊

Class.forName(this.maps.get(n)).newInstance()就很好了。當然,您不應該將其轉換為Class,因為它們不是 的實例Class。你們的類有一個共同的基類嗎?這就是要投射到的類。

您沒有使用完全限定名稱。也許你應該。


查看完整回答
反對 回復 2023-07-19
?
幕布斯7119047

TA貢獻1794條經驗 獲得超8個贊

簡單的方法

我懷疑你讓你的工作變得太復雜了。


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." );


查看完整回答
反對 回復 2023-07-19
  • 2 回答
  • 0 關注
  • 181 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號