我的静态方法无法找到我的静态内部类的静态内部类。

huangapple go评论74阅读模式
英文:

My static method can't find my static inner class' static inner class

问题

I tried to run the following code contained in my MainClass.java file, but it failed with a compilation error.

public class MainClass
{

   public static interface StaticParentType{
      public static class StaticChildType implements StaticParentType {}
   }

   public static void main(final String[] args)
   {
      new StaticChildType();
   }

}

It failed with the following compilation error.

$ java MainClass.java
MainClass.java:10: error: cannot find symbol
      new StaticChildType();
          ^
  symbol:   class StaticChildType
  location: class MainClass
1 error
error: compilation failed

I tried various different combinations of public/private, static/non-static, and it seems the only way to get my code to work is to do something like the following instead.

public class MainClass
{

   public static interface StaticParentType{}
   public static class StaticChildType implements StaticParentType {}


   public static void main(final String[] args)
   {
      new StaticChildType();
   }

}

So, I am not blocked, I have a decent enough workaround here. It seems that having the class contained within the curly braces prevents the main method from being able to see and/or use it.

My question is why? More specifically, why would a public static inner class be invisible to the main method? I really felt like being public and static (as well as the interface being public and static) would make it visible, but it appears not. I spent a couple minutes searching StackOverflow and the internet, but it didn't seem to come up.

英文:

I tried to run the following code contained in my MainClass.java file, but it failed with a compilation error.

public class MainClass
{

   public static interface StaticParentType{
      public static class StaticChildType implements StaticParentType {}
   }

   public static void main(final String[] args)
   {
      new StaticChildType();
   }

}

It failed with the following compilation error.

$ java MainClass.java
MainClass.java:10: error: cannot find symbol
      new StaticChildType();
          ^
  symbol:   class StaticChildType
  location: class MainClass
1 error
error: compilation failed

I tried various different combinations of public/private, static/non-static, and it seems the only way to get my code to work is to do something like the following instead.

public class MainClass
{

   public static interface StaticParentType{}
   public static class StaticChildType implements StaticParentType {}


   public static void main(final String[] args)
   {
      new StaticChildType();
   }

}

So, I am not blocked, I have a decent enough workaround here. It seems that having the class contained within the curly braces prevents the main method from being able to see and/or use it.

My question is why? More specifically, why would a public static inner class be invisible to the main method? I really felt like being public and static (as well as the interface being public and static) would make it visible, but it appears not. I spent a couple minutes searching StackOverflow and the internet, but it didn't seem to come up.

答案1

得分: 3

以下是翻译好的部分:

有趣的是,在添加这个问题的标签时,inner-classesstatic-classes 的资源指引了我正确的方向。

首先,我找不到答案的部分原因是我使用了错误的术语。事实证明,官方术语是 static nested class,你可以在这里看到 (Ctrl+F "Terminology") -- https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

事实证明,如果你想在嵌套它的类之外使用静态嵌套类,你必须这样引用静态嵌套类。

StaticParentType.StaticChildType

请注意,这个语法仅适用于我的嵌套类是 static 的情况。如果不是这样,规则会发生变化。点击上面提到的链接以了解更多信息。

所以,对于我的目的,这意味着我的主方法必须如下所示。

public static void main(final String[] args)
{
   new StaticParentType.StaticChildType();
}

这是完整的类。

public class MainClass
{

   public static interface StaticParentType{
      public static class StaticChildType implements StaticParentType {}
   }

   public static void main(final String[] args)
   {
      new StaticParentType.StaticChildType();
   }

}

作为奖励,我进一步设置了访问修饰符,使它们应该是什么。起初,我希望嵌套类和包含它的类都是私有的,但在得到编译错误后我改变了主意。下面是我最终采用的解决方案。

public class MainClass
{

   private interface StaticParentType{
      static class StaticChildType implements StaticParentType {}
      // 显然,这个嵌套的静态类不能是私有的
      // 否则会导致编译错误
   }


   public static void main(final String[] args)
   {
      new StaticParentType.StaticChildType();
   }

}

这是 java.util.Map.Entry 的一个很好的例子。Entry 是在 Map 内部的一个静态接口,因此遵循与此相同的规则。所以,如果我想引用 Entry,我必须这样做 Map.Entry

编辑 -- 如果上面的语法(ParentType.StaticChildType)有点丑陋,你可以进行 Static Import

当然,这仅在你静态导入的类不在你尝试使用它的文件中时才有效。毕竟,为什么要导入已经在你的文件中的东西呢?

为了展示静态导入在代码中的样子,这里有一个示例。

import static java.util.Map.Entry;

public class Abc
{

   public static void main(String[] args)
   {
   
      Entry<String, Integer> e = null;
      //Map.Entry<String, Integer> e = null;
   
   }

}
英文:

Funnily enough, when adding the tags for this question, the resources for inner-classes and static-classes pointed me in the right direction.

For starters, part of the reason I couldn't find my answer was because I was using the wrong terminology. As it turns out, the official word for it is static nested class, which you can see over here (Ctrl+F "Terminology") -- https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

As it turns out, if you want to use a static nested class outside of the class that is nesting it, you must refer to the static nested class like this.

StaticParentType.StaticChildType

PLEASE NOTE, this syntax is only if my nested class is static. The rules change if that is not true. Click on the earlier mentioned link to learn more.

So, for my purposes, that means that my main method would have to look like this.

public static void main(final String[] args)
{
   new StaticParentType.StaticChildType();
}

Here is the full class.

public class MainClass
{

   public static interface StaticParentType{
      public static class StaticChildType implements StaticParentType {}
   }

   public static void main(final String[] args)
   {
      new StaticParentType.StaticChildType();
   }

}

And as a bonus, I went further and set the access modifiers to be what they should have been. I had originally wanted both the nested class and the one that housed it to be private, but changed that once I get my compilation error. Here is the final solution I landed on.

public class MainClass
{

   private interface StaticParentType{
      static class StaticChildType implements StaticParentType {}
      //apparently, this nested static class cannot be private
      //else it gets a compilation error
   }


   public static void main(final String[] args)
   {
      new StaticParentType.StaticChildType();
   }

}

A good example of this would java.util.Map.Entry. Entry is a static interface inside of Map, thus, falling under the same rules as this. So, if I want to refer to Entry, I have to do Map.Entry.

EDIT -- If the syntax above (ParentType.StaticChildType) is a bit ugly, what you can do is do a Static Import.

Of course, this only works if the class you are statically importing is not in the same file that you are trying to use it in. After all, why would you need to import something that is already in your file?

To show off what a static import would like in code, here is an example.

import static java.util.Map.Entry;

public class Abc
{

   public static void main(String[] args)
   {
   
      Entry<String, Integer> e = null;
      //Map.Entry<String, Integer> e = null;
   
   }

}

huangapple
  • 本文由 发表于 2023年5月14日 12:41:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76245836.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定