Java编译器给出错误 - 没有封闭的类型实例

时间:2011-11-14 23:33:41

标签: 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
        }
      } );
    }

3 个答案:

答案 0 :(得分:5)

调用者需要声明为静态。现在声明的调用者是一个内部类,这意味着它只能从现有超类的实例创建。例如,如果你有:

class A{
  class B{}
}

然后要创建B类,你需要:

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

那是因为B是一个内部阶级;它只能存在于某些A的上下文中。您可能不需要它作为内部类,因此将其声明为静态以使其像普通类一样运行。或者,如果不需要则删除。

答案 1 :(得分: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。我建议稍微阅读内部课程; - )

答案 2 :(得分:1)

我建议删除班级Caller。它没有任何用处。

如果你坚持要保留它,你需要把它变成静态类。