2011-11-14 68 views
1

我設計一個類類型的無外圍實例:Java編譯器提供了錯誤 -

public class CustomEvent< P, T > 
{ 
    /** Facade interface used for adopting user interfaces to our generic class. */ 
    public interface ICaller< P, T > 
    { 
    /** callback facade method. */ 
    void call(P parent, T callback, Object... objects); 
    } 

    /** Abstract class for simplifying naming in constructor. */ 
    public abstract class Caller implements ICaller< P, T >{} 

    /** Constructor. */ 
    public CustomEvent(final String name, final P parent, final Caller caller){} 
} 

現在我想建立這樣的類的實例:

public class TestClass 
    { 
    private final TestEvent mEventOnLoad; 

    public TestClass() 
    { 
     // ERROR here: No enclosing instance of type CustomEvent<P,T> is accessible. 
     // Must qualify the allocation with an enclosing instance of type 
     // CustomEvent<P,T> (e.g. x.new A() where x is an instance of CustomEvent<P,T>). 
     mEventOnLoad = new TestEvent("onLoad", this, new TestEvent.Caller() { 
     public void call(TestClass parent, ITestCallbacks callback, Object... objects) 
     { 
      // some code here 
     } 
     }); 
    } 

    private class TestEvent extends CustomEvent< TestClass, ITestCallbacks > 
    { 
     public TestEvent(String name, TestClass parent, TestEvent.Caller caller) 
     { 
     super(name, parent, caller); 
     } 
    }; 
    } 

是否有可能以某種方式來解決辦法那?我想簡化類的命名,而不是長泛型聲明使用包含所有需要的類型定義的簡短抽象類名稱?

我有一個填充,這是可能的...但我不是很舒服與Java尚未...

解決方案

private class TestEvent extends CustomEvent< TestClass, ITestCallbacks > 
    { 
     public final static TestEvent Instance = new TestEvent(null, null, null); 

     public TestEvent(String name, TestClass parent, TestEvent.Caller caller) 
     { 
     super(name, parent, caller); 
     } 
    }; 

    public TestClass() 
    { 
     mEventOnLoad = new TestEvent("onLoad", this, TestEvent.Instance.new Caller() { 
     public void call(TestClass parent, ITestCallbacks callback, Object... objects) 
     { 
      // some code here 
     } 
     }); 
    } 
+1

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

回答

2

如果你只是試圖讓你的代碼編譯(請注意,你需要修復與類型安全和參數化的幾個問題),嘗試這樣的事情:

public TestClass() { 
    CustomEvent bla = new CustomEvent("name", null, null); // TODO: parameterise 
    mEventOnLoad = new TestEvent("onLoad", this, bla.new Caller() { 
     @Override 
     public void call(Object parent, Object callback, Object... objects) { 
      // some code here 
     } 
    }); 
} 

什麼錯誤消息試圖說的是,你需要一個實例(bla)撥打new。我建議讀一下內部類的一點;-)

+0

不能說'bla.new Caller'非常直觀的語法...但是,非常感謝這樣的方法有助於... –

+0

請注意,我假設你的代碼僅僅是爲了你自己的利益,玩弄不同的方面Java的泛型和內部類;我上面的代碼並不打算成爲一個好的編程實踐的例子,它只是給你一個如何讓它工作的例子。哦,如果你想要直觀的語法,請嘗試使用Smalltalk而不是Java ;-) –

+0

代碼有效,但使用起來很醜陋...我會更好地尋找另一種方式。 –

1

我建議你擺脫的類Caller。它沒有用處。

如果你堅持保留它,你需要使它成爲一個靜態類。

+0

當然,我會尋找另一種方法。我嘗試簡化回調,但讓它們變得更加困難。在我的代碼中搜索透明度和效率之間的妥協很難找到。感謝您的幫助。 –

5

調用者需要聲明爲靜態。現在聲明的調用者是一個內部類,這意味着它只能從現有超類的實例創建。舉例來說,如果你有:

class A{ 
    class B{} 
} 

然後創建B類的東西,你需要:

A a = new A(); 
B b = new a.B(); 

這是因爲B是一個內部類;它只能存在於某些A的上下文中。您可能不需要它是內部類,因此將其聲明爲靜態,以使其像普通類一樣行事。或者,如果不需要,請刪除。

+0

如果你看看代碼,我使用你推薦的方法。這是行不通的。泛型和匿名類使事情難以閱讀,但更易於使用。 –