【问题标题】:Cannot throw instance of private member class? - Java不能抛出私有成员类的实例? - 爪哇
【发布时间】:2011-07-24 23:46:06
【问题描述】:

这个错误是什么意思,为什么会出现?在似乎与我的情况相关的情况下,我无法通过 Google 找到有关成员类和静态上下文或它们的含义的太多信息。

这是我得到的错误:

non-static variable this cannot be referenced from a static context

它指向这条线,并且在new 运算符处:

throw new ParenthesisException();

ParenthesisException 是主类的私有成员类。我认为问题可能与此有关,但我能想到的就这些了。

这是我对 ParenthesisException 的定义。它在主类定义中:(如果格式不是很好,我很抱歉)

private class ParenthesisException extends Throwable
{
    public ParenthesisException(){}
    public String strErrMsg()
    {
        return "ERROR: Every '(' needs a matching ')'";
    }
}

我发现错误消息相当神秘。我希望能简要解释一下“静态上下文”以及为什么 new 运算符不适用于我的成员类,以及如何抛出私有成员类的实例。

【问题讨论】:

  • 你需要把错误的代码贴出来。私人课程似乎不是问题。

标签: java exception static inner-classes


【解决方案1】:

如果我必须根据您发布的代码片段来猜测发生了什么,则错误可能是因为您试图从 static 方法中抛出 ParenthesisException

在 Java 中,在另一个类中定义的类会自动存储一个指向创建它们的对象的指针。也就是说,ParenthesisException 有一个隐式指针,指向使用new 创建的封闭类。这意味着,特别是,您不能在 static 方法内构造 new ParenthesisException,因为没有可用于引用包含类的 this 指针。

要解决这个问题,您应该像这样将ParenthesisException 设为static 内部类:

private static class ParenthesisException extends Throwable
{
    public ParenthesisException(){}
    public String strErrMsg()
    {
        return "ERROR: Every '(' needs a matching ')'";
    }
}

private 之后的 static 表示 ParenthesisException 不保留对封闭对象的引用,这可能是您想要的。这也意味着您可以在静态方法中创建new ParenthesisExceptions。

希望这个猜测是正确的,希望对您有所帮助!

【讨论】:

  • 感谢您的解释!它现在似乎已经奏效了。谢谢!
【解决方案2】:

当您以前没有看到该错误时,它有点令人困惑,但这正是它所说的:您不能在非静态上下文中使用非静态变量。您的 main 方法以及很可能包含您的 main 方法的类中的任何方法都是静态的,因此您不能从中使用非静态变量。

ParenthesisException 是非静态的,因为您尚未将其声明为静态,但它已在主类中声明并在静态方法中调用。

不要将其声明为内部类 - 将您的新的公共类。然后你就可以实例化这个异常了。

【讨论】:

    【解决方案3】:

    您的主要功能是“静态上下文”。你只能调用静态函数并且没有'this'。当您尝试创建一个新异常时,您实际上调用了this.new ParenthesisException(),因为该异常是一个内部类。但你不能那样做。您需要创建一个主类的实例,然后在该实例上创建异常对象。

    MainClass m = new MainClass();
    throw m.new ParenthesisException();
    

    另一种解决方案是将您的异常定义为静态类:

    private static class ParenthesisException extends Throwable
    

    然后你可以从静态上下文中实例化它,所以你不需要主类的实例。

    【讨论】:

      【解决方案4】:

      如果没有代码,这完全是一种猜测,但根据错误消息,我相信这会起作用。如果您的 main 类是 Animal 那么您需要在 main 内部实例化 Animal 如果您做一个简单的...

      new Animal(); 作为main 中的唯一行

      然后创建一个新方法....

      public Animal(){
          /* put code that used to be in main */
      }
      

      这很可能会解决您的问题....再次,如果没有完整的代码,这只是一个猜测,但根据您所说的和错误,我相信这会解决问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-27
        • 1970-01-01
        • 1970-01-01
        • 2019-06-11
        • 1970-01-01
        • 2012-07-23
        相关资源
        最近更新 更多