2010-06-14 147 views
6

我是新來的Java(與C#的經驗),如何從(靜態)類中的類創建新的類實例?

這就是我想做的事:

public final class MyClass 
{ 
    public class MyRelatedClass 
    { 
     ... 
    } 
} 

public class OtherRandomClass 
{ 
    public void DoStuff() 
    { 
     MyRelatedClass data = new MyClass.MyRelatedClass(); 
    } 
} 

這使得這個錯誤在Eclipse:

No enclosing instance of type BitmapEffects is accessible. Must qualify the allocation with an enclosing instance of type BitmapEffects (e.g. x.new A() where x is an instance of BitmapEffects).

這是可能在C#中使用靜態類,這裏應該怎麼做?

+0

可能重複[Java - 沒有可以訪問Foo類型的封閉實例](http://stackoverflow.com/questions/9560600/java-no-enclosing-instance-of-type- foo-is-accessible) – fabian 2016-03-03 23:46:05

回答

2

爲了迴應關於在一個文件中打包多個類的評論:與.NET不同,Java的大多數實現強制公共類類型的名稱與聲明類類型的文件的名稱之間存在嚴格關聯。不是一個硬性的要求,但沒有使用相關性不被執行的系統。該JLS - 7.6 Top Level Type Declarations這樣說:

When packages are stored in a file system (§7.2.1), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:

  • The type is referred to by code in other compilation units of the package in which the type is declared.
  • The type is declared public (and therefore is potentially accessible from code in other packages).

見這太問題:multiple class declarations in one file

如果您正在尋找創建一個命名空間附上相關的類,然後使用靜態內部類是你所需要的。靜態聲明並不意味着一個instnace - 它們仍然可以被實例化 - static意味着它們可以被實例化而不需要引用封閉類。由於封閉類僅用於分組,而不是數據,因此您可以安全地將其設置爲靜態。爲了更清楚地說明封閉類僅用於分組,您應該聲明它爲interface,以便它不能被實例化並且沒有實現細節。

儘管個人,我會避免這樣做 - 在Java中,包被用來強制執行命名空間。爲此使用內部類很快變得麻煩。 (我已經嘗試過了!)

+0

啊感謝信息:)。 (並感謝大家的幫助) – Mervin 2010-06-16 17:34:18

3

嘗試將MyRelatedClass定義爲靜態。

編輯
更多關於這個問題
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

+0

我不希望MyRelatedClass是靜態的,我需要它的多個實例。 – Mervin 2010-06-14 17:32:20

+1

@Mervin請閱讀鏈接中的描述(或馬特的回答)。如果內部類是'靜態',那並不意味着它只有一個實例。這意味着MyRelatedClass不會關聯到任何特定的MyClass實例,並且將無法訪問其(父類)實例成員。 – 2010-06-14 17:38:47

+0

@Mervin - 這不是什麼靜態手段在這種情況下。即使嵌套在MyClass中,它的行爲仍然像頂級類一樣。 – Robin 2010-06-14 17:40:27

19

你定義MyRelatedClass的樣子,你需要有MyClass實例能夠訪問/實例化這個類。

通常在Java中,當MyRelatedClass的實例需要訪問某個MyClass實例的某些字段(因此在編譯器警告中引用「封閉實例」)時,可以使用此模式。

像這樣的東西應該編譯:

public void doStuff() { 
    MyClass mc = new MyClass(); 
    MyRelatedClass data = mc.new MyRelatedClass(); 
} 

但是,如果MyRelatedClass實例並不需要訪問它的領域是包實例(MyClass的字段),那麼你應該考慮定義MyRelatedClass作爲一個靜態類,這將允許您發佈的原始代碼進行編譯。

在具有嵌套類(您已發佈的信息)和靜態嵌套類(一個classstatic class)不同的是,前者的嵌套類屬於父類的例如,而後者沒有這種關係 - 只有邏輯/名稱空間關係。

+4

在隱式'this'以外的任何內容上創建(非靜態)內部類使我生病。 – 2010-06-14 17:34:21

+0

以及我試圖完成什麼,我可以在C#中做: //[MapManagement.cs] 命名空間MapManagement { 公共靜態類MapManager { ... } 公共類SpecialMapFile { ... } } 我想要2個類(非靜態)在1文件,不知何故在Java中這是不允許的..錯誤:「公共類型*名稱*需要定義在它自己的文件」所以這是我的解決方案,我想要1包,我想有相關的類分組在他們自己的文件 – Mervin 2010-06-14 17:47:05

+0

@Mervin如你所見,Java只允許每個文件一個公共頂級類。相關的類只能在相同的包中定義在不同的文件中。 – 2010-06-14 18:29:37

0

是的,非靜態嵌套類可以訪問外部類實例成員,因此必須爲外部類的實例創建。所以,你有兩個選擇:

  1. 使嵌套類的靜態作爲默文暗示,或
  2. 作爲錯誤信息建議使用外部類的一個實例創建它。

實際上,我很少創建一個內部類的實例,除了外部類的方法外,我很少使這樣的類變爲可變的 - 但這只是我自己。

+0

以及我試圖完成我可以在c#中執行的操作:// [MapManagement.cs] namespace MapManagement {public static class MapManager {...} public class SpecialMapFile {...}}我想要2個類(non-靜態)在1文件,不知何故在Java中,這是不允許的..錯誤:「公共類型名稱需要在它自己的文件中定義」,所以這是我的解決方案,我想要1包,我想有相關類分組在自己的文件 - – Mervin 2010-06-14 17:56:26

相關問題