2016-03-07 64 views
0

這裏的第一個計時器,在處理簡單的策略遊戲時遇到了Java問題。這裏有:訪問同一類中聲明的對象的變量

爲了節省處理器時間,我用int數組(多維)作爲數據庫接口。就像這樣:

//database variables 
public int mapSize;// amount of tiles along one side of the map 
public int[][] map;// [area id] - [resource type] - value 

public int[][][] trades;// [trade id] - [sender/recipient] - [resource type] - value 

public Object users = new Object(){ 
    public int usercount;// amount of users in the game 
    public int[][] opinion;// [first user id] - [second user id] - value 
    public int[][][] resources;// [user id] - [resource type] - [value type] - value 
    public int[][] efficiency;// [user id] - [resource type] - value 
    public int[][] processes;// [user id] - [resource type] - value 
}; 

//public math function (triangular numbers by iteration) 
public int triNum(int i){ 
    return (int) i*(i+1)/2; 
} 

正如你所看到的,我用了一個Object()到用戶數據存儲在用戶是指玩家+ AI在這裏,沒有任何實際的人。我這樣做是因爲我關心內存,因爲resources佔用比opinion,efficiencyprocesses多得多的空間,並且絕對多於usercount。該代碼位於class Game。這個類不是主類,也不包含public static void main(String[] args)方法。此代碼不在任何方法內,但它在類內。這裏沒有錯誤。

問題在於void start(Main home, String save)方法,它實際上引發了一場遊戲。 class Game()監視當前活動的遊戲及其變量和對象,並始終處於活動狀態)。在這裏,在啓動框架和麪板並生成地圖(使用方法int[][] generateMap(int size))之後,我想填充數組。這是相關代碼:

//DATA VARIABLES 
if (save.equals("new")){ 
    //make map 
    mapSize = 9;//placeholder value - retrieve actual value from settings file later 
    int mapScale = (int) Math.pow(mapSize, 2); 
    map = generateMap(mapSize);//9x9 grid 

    //make users 
    users.usercount = (int) Math.pow(mapSize/3, 2);//<--- ERROR HERE 
    for (int i = 0; i < users.usercount; i++){//<--- ERROR HERE 

    }  

    //make trades 
    trades = new int[triNum(users.usercount - 1)][1][8];//<--- ERROR HERE 
    for (int[][] trade : trades) { 
     //fill array with appropriate values 
     for (int j = 0; j < users.usercount; j++) {//<--- ERROR HERE 
      for (int k = 0; k < users.usercount; k++) {//<--- ERROR HERE 
       if (j < k) { 
        trade[0][0] = j; 
        trade[1][0] = k; 
       } 
      } 
     } 
    } 
} 

標記的位置生成以下NetBeans IDE的8.1錯誤:

cannot find symbol: 
    symbol: variable usercount 
    location: variable users of type Object 
---- 
(Alt-Enter shows hints) 

按住ALT鍵,同時輸入簡單的顯示錯誤,即使沒有懸停在圖標。按下這個圖標會產生一個「無法做到」的Windows聲音(Windows 10)。

據我所知,編譯器不能從start()方法訪問對象users。有什麼辦法讓我的訪問,從公共方法,在公共班,公共變量,在公共對象,在相同的公共類所做的?


如果沒有,你能這麼好心解釋:

A)爲什麼不呢?

B)我沒有/錯誤理解什麼?

C)我可以做什麼呢?

我明白我可以很好地聲明這些變量與任何users對象分開。但是1)我想用單一名稱來引用這組變量,並且數組的內存密集程度不成比例,2)我的問題可能會在稍後出現在另一個設置中,如果是這樣,我想知道如何處理它。


我知道我只是一個Java新手,但我一直在使用谷歌搜索試過了,而否則他們幫助我,他們沒有幫助我在這裏。也許我正在使用不正確的搜索條件,但如果是這樣的話,那麼這些條款已經是一個巨大的幫助。

感謝這堵牆文本閱讀,並感謝你,甚至更多,如果你會這麼好心幫我在這裏。

+1

在嘗試預優化時,您已決定不使用類並使您的代碼完全無法讀取。使用類。你的用戶對象是Object類型的。對象沒有任何字段。定義你的類。選擇適當的數據結構。添加可讀的方法和封裝。 –

回答

3

你在這裏使用的方法不是正確的方法來做你想要的。當你這樣宣佈users時,它就是所謂的anonymous class。基本上,它變成了具有自動生成名稱的完整類聲明。

因爲Java的類型系統是如何工作的,你只能(直接)訪問域和對象的方法,如果他們在你用它來指代它引用的類型要宣佈。因此,舉例來說,如果你說Object o = "string",你可以使用任何的Object的方法,但你不能調用只存在於String的方法,因爲編譯器不知道你有什麼實際上是一個String

這是給你一個問題,因爲你沒有辦法給你的對象轉換成它的實際類型,因爲類本身是匿名的。沒有反思,沒有辦法讓這些領域退出,這使得對象無效。

正確的做法是直接把這些字段到您已經聲明users類,或使一個單獨的類來保存這些領域:

class Users { 
    public int usercount; 
    public int[][] opinion; 
    public int[][][] resources; 
    public int[][] efficiency; 
    public int[][] processes; 
}; 

再後來通過類名稱引用它:

Users users = new Users(); 

既然你現在給一個名字的類,編譯器可以安全地知道它是什麼類型,以及哪些字段,它包含。

作爲一個側面說明,這些陣列仍然將是非常令人費解。不要害怕以有用的方式聲明對象來表示數據。 JVM非常擅長創建和管理對象,並且您嘗試實現的性能收益實際上很不重要。更有可能的是,你的程序會混淆得足夠多,以至於你最終編寫的代碼效率低於只編寫可讀代碼的速度。