英文:
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-classes
和 static-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;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论