2013-03-07 63 views
0

我有下面的類:Java實例方法

public class Example(

    private String id; 
    private ArrayList<String> docs = new ArrayList(); 

    public Example(string startid){ 
     id = startid; 
     docs = null; 
    } 

    public void myMethod(String externalID){ 

     Example myExample = new Example(externalID); 

} 

如果我沒有理解好,當我打電話myMethod的,它會創建一個實例的實例名爲myexample中使用id =外部ID和文檔= NULL。

我想要什麼這個類做的是: 呼叫同時從將創建一個實例(myexample中),並確保外部調用不能覆蓋任何myexample中的變量的外緣點的MyMethod 我也(線程安全的嗎?)希望它是在適當的myExample實例中從外部調用填充文檔數組。這是可能的,還是我必須同時傳遞ArrayList和startid?

+0

你在用'myExample' var做什麼?你不能讓'myMethod'返回它嗎?這樣,任何*外部點*都會根據需要管理自己的實例。 – sp00m 2013-03-07 11:19:38

+0

'myExample'在方法'myMethod'中具有本地可見性,對外部調用完全不可見。或者你是否打算將'myExample'作爲實例或類變量? – A4L 2013-03-07 11:20:39

+0

我不確定你想用myMethod來實現你爲什麼不調用構造函數來創建一個新的對象。我沒有看到使用這種方法的好處,並順便說一句。 - 如前所述 - 創建的Example對象不能在方法外部使用。 – Don 2013-03-07 11:28:17

回答

1

根據你想才達到什麼Benoit的想法,我想如果你想thread-最好的辦法是使用地圖(或ConcurrentMap安全):

ConcurrentMap<String, List<String>> myData = new ConcurrentHashMap<>(); 

這樣,您可以通過您提供的id來解決任何列表。

List<String> myList = myData.get(id); 

如果要限制列表的訪問器(例如只提供了add方法),你需要封裝列表中的一類:

public final class Example { 
    private final List<String> docs = new ArrayList<>(); 

    public boolean addDoc(final String doc) { 
     return docs.add(doc); 
    } 
} 

然後使用地圖如下:

ConcurrentMap<String, Example> myData = new ConcurrentHashMap<>(); 

並添加文檔這樣的:

myData.get(id).addDoc(myDoc); 

希望這有助於...

在註釋中討論的話題:設置變量

你有一個這樣的類:

public class Example { 
    public String var; 
} 

和實例這樣

Example ex = new Example(); 

您可以

設置的值
ex.var = "abc"; 

有了這樣

public class Example { 
    private String var; 
    public void setVar(String var) { 
     this.var = var; 
    } 
} 

使用CALSS

ex.setVar("abc"); 

管理多個實例:

1)您的網絡服務中獲得的信息與ID

2)您的服務器應用程序存儲實例的地圖,您可以通過ID訪問它(請參閱上面的地圖示例)。 在Web服務調用

Example ex = ReportHolder.getReport(id); 

假設這樣一個類:

public class ReportHolder { 
    private static ConcurrentMap<String, Example> map = new ConcurrentMap<>(); 
    public static Example getReport(final String id) { 
     return map.get(id); 
    } 
} 

3)然後你就可以操作實例。

確保您正確理解術語變量,類,實例和靜態。 Otherwiese這將是很難理解爲什麼你的錯誤發生。

+0

我很困惑。我想實現的是:通過HTTP調用調用jar文件並傳入變量,例如ID和文檔。每個新的傳入web服務調用都會生成一個新的類實例。 – L4zl0w 2013-03-07 13:49:57

+0

我不知道我們正在談論網絡服務。 Web服務請求通常由一個線程處理,因此不同的請求由不同的線程處理。這意味着你總是通過調用Web服務來創建一個新的Example對象。您正在使用哪種框架(您如何實現Web服務)?問題是你在創建它之後想使用Example對象做什麼? – Don 2013-03-07 14:04:19

+0

我在名爲BI Publisher的第三方應用程序中運行我的代碼。當通過Web服務調用執行報告時,報告將啓動Java應用程序。目前,當一個Web服務調用一次進入但當同時有多個Web服務調用時,應用程序正在工作,因此靜態變量將被覆蓋,從而產生錯誤的輸出。因此,Web服務調用會調用一個報告,然後該報告調用Java類並使用靜態setter方法提供各種屬性。不知何故,我需要確保2個報告運行時,變量不會混淆。 – L4zl0w 2013-03-07 14:21:31

1

你理解不正確。

爲了調用myMethod你需要有一個已經創建好的Example實例,調用myMethod會用externalId實例化一個新的實例,並立即丟棄它。

從我個人理解你想要的是以下幾點:

public class Example { 

    // Final so it can't be modified once set. 
    private final String id; 

    // Final so it can't be switch to a different list. 
    // Public so others can add to it and have acces to List methods. 
    // Synchronized so acces to it from multiple threads is possible. 
    // Note: You should probably make this private and have a getList() method that 
    //  returns this instance to have nice encapsulation. 
    public final List<String> docs = Collections.synchronizedList(new ArrayList()); 

    // Make default constructor private to force setting the startId. 
    private Example() {} 

    public Example(final String startId){ 
    this.id = startId; 
    } 
} 
+0

謝謝Benoit。每個類的實例是否都有自己的List?我可以將特定實例添加到列表中嗎?例如基於ID? – L4zl0w 2013-03-07 12:16:46