英文:
Java new keyword with static inner class
问题
我知道这个问题之前已经被问过了,但大多数情况下都是关于特定库的问题。而且给出的答案并没有真正解释清楚发生了什么。
这就是为什么我在这里设置了一个相当简单的测试场景,并尝试去摸索,但仍然有一些疑问!在线Java示例
这个简单的代码由两个文件组成:
Main.java
public class Main
{
public static void main(String[] args) {
// 这个工作正常,inner1和inner2似乎是新的实例
Outer.Inner inner1 = new Outer.Inner();
Outer.Inner inner2 = new Outer.Inner();
inner1.setName("Mario");
inner1.say();
inner2.setName("Luigi");
inner2.say();
// 如果Inner不是一个public static类,会出现这个错误:
// 错误:需要包含Outer.InnerNoStatic的封闭实例
Outer.InnerNoStatic inner3 = new Outer.InnerNoStatic();
}
}
Outer.java
public class Outer {
public static class Inner {
private String name;
public void say() {
System.out.println("Hi " + name);
}
public void setName(String name) {
this.name = name;
}
}
public class InnerNoStatic {
public void say() {
System.out.println("Hi from InnerNoStatic");
}
}
}
所以,尽管Inner
类被声明为静态,我们还是创建了两个名为inner1和inner2的新实例。那么为什么它被称为静态呢?
反过来,如果我移除静态,就像InnerNoStatic
中那样,我应该如何获取该类的实例呢?
英文:
I know this questions has been asked before, but mostly pretty specific regarding a certain library. And the answers given didn't really explain to me what was going on.
That's why I set up a pretty simple test scenario here, and tried to fiddle with it, but there are still some question marks!
Online Java Example
The simple code consists of two files:
Main.java
public class Main
{
public static void main(String[] args) {
// this works, and inner1 and inner2 seem to be new instances
Outer.Inner inner1 = new Outer.Inner();
Outer.Inner inner2 = new Outer.Inner();
inner1.setName("Mario");
inner1.say();
inner2.setName("Luigi");
inner2.say();
// if Inner is not a public static class this gives this error:
// error: an enclosing instance that contains Outer.InnerNoStatic is required
Outer.InnerNoStatic inner3 = new Outer.InnerNoStatic();
}
}
Outer.java
public class Outer {
public static class Inner {
private String name;
public void say() {
System.out.println("Hi " + name);
}
public void setName(String name) {
this.name = name;
}
}
public class InnerNoStatic {
public void say() {
System.out.println("Hi from InnerNoStatic");
}
}
}
So it seems like even though the Inner
class is declared with static, we create two new instances called inner1 and inner2. Why is it called static then?
And in turn, if I remove the static, as in InnerNoStatic
how would I go about getting an instance of that class?
答案1
得分: 1
> 所以似乎虽然内部类声明为静态,我们创建了两个名为inner1和inner2的新实例。那么为什么它被称为静态?
"静态"内部类的对象与其所在的外部类对象没有关联,与非"静态"内部类相反。将一个类声明为"静态"内部类,而不是将该类移到"顶层",是一种方便的方式,向用户表明该内部类的对象与外部类分开使用并没有太多意义,类似于例如 Map.Entry
。
> 而且反过来,如果我移除static,比如InnerNoStatic,我该如何获取该类的一个实例?
例如:
public class Outer {
private InnerNoStatic innerNoStatic = new InnerNoStatic();
public InnerNoStatic getInnerNoStatic () {
return innerNoStatic;
}
// ...
以及
Outer.InnerNoStatic innerNoStatic = new Outer().getInnerNoStatic();
英文:
> So it seems like even though the Inner class is declared with static, we create two new instances called inner1 and inner2. Why is it called static then?
Objects of a "static" inner class are not tied to the objects of its enclosing class, opposite to non "static" inner classes. Having a "static" inner class instead of moving that class to the "top level" is a handy way of signalling to a user that objects of that inner class have not much use separate from the outer class, similar to e. g. Map.Entry
.
> And in turn, if I remove the static, as in InnerNoStatic how would I go about getting an instance of that class?
For example
public class Outer {
private InnerNoStatic innerNoStatic = new InnerNoStatic();
public InnerNoStatic getInnerNoStatic () {
return innerNoStatic;
}
// ...
and
Outer.InnerNoStatic innerNoStatic = new Outer().getInnerNoStatic();
答案2
得分: 1
所以看起来,即使内部类声明为静态,我们还是创建了两个称为inner1和inner2的新实例。那么为什么它被称为静态呢?
static
意味着嵌套类更独立。它主要设计用于增加封装性、可读性、可维护性,以及逻辑上组织类的一种良好方式。
而且,反过来说,如果我去掉 static,就像 InnerNoStatic 中那样,我该如何获得该类的一个实例呢?
语法有些不同,因为你需要一个 Outer
的实例。
Outer.InnerNoStatic inner3 = new Outer().new InnerNoStatic();
英文:
> So it seems like even though the Inner class is declared with static, we create two new instances called inner1 and inner2. Why is it called static then?
static
implies more independence for the nested class. It's designed mainly to increase encapsulation, readability, maintainability and it's a nice way to logically group classes.
> And in turn, if I remove the static, as in InnerNoStatic how would I go about getting an instance of that class?
The syntax is a bit different because you need an instance of Outer
.
Outer.InnerNoStatic inner3 = new Outer(). new InnerNoStatic();
答案3
得分: 1
static
在这里决定了Inner
和InnerNoStatic
与Outer
的关系。
因为Inner
在Outer
中是静态的,它不与任何特定的Outer
实例相关联(一如既往,静态成员属于类,而不属于该类的任何特定实例)。这解释了以下代码为什么可以编译通过:
Outer.Inner inner1 = new Outer.Inner();
然而,InnerNoStatic
是一个实例成员(即如果它不是静态的,则与给定的实例相关联)。这就解释了为什么编译器在以下代码中会引发错误:
Outer.InnerNoStatic inner3 = new Outer.InnerNoStatic();
因为InnerNoStatic
必须与Outer
的实例关联,所以你需要使用这样一个实例来创建inner3
:
Outer.InnerNoStatic inner3 = new Outer().new InnerNoStatic(); // 注意调用顺序
你也可以使用现有的实例:
Outer outer = new Outer();
Outer.InnerNoStatic inner3 = outer.new InnerNoStatic();
在这两种情况下,都是使用一个Outer
实例来构建一个InnerNoStatic
实例(只是没有指向使用new Outer().new InnerNoStatic()
创建的Outer
对象的变量)。
注意:很容易将new Outer.Inner();
与new Outer().new Inner();
混淆。它们并不做相同的事情(前者中的“Outer”基本上起到了命名空间的作用,而后者中的new Outer()
正在创建一个Outer
对象)。也就是说,在前者中只有一个构造函数调用(Inner()
),而在后者中有两个构造函数调用(Outer()
和Inner()
)。
英文:
static
here dictates how Inner
and InnerNoStatic
are used with respect to Outer
.
Because Inner
is static in Outer
, it is not tied to any specific instance of Outer
(as always, a static member belongs to the class, not to any particular instance of that class). That explains how this compiles:
Outer.Inner inner1 = new Outer.Inner();
InnerNoStatic
, however, is an instance member (that's that: if it's not static, it is tied to a given member). And that explains why the compiler raises an error here:
Outer.InnerNoStatic inner3 = new Outer.InnerNoStatic();
Because InnerNoStatic
must be tied to an instance of Outer
, you need to use such an instance to create inner3
:
Outer.InnerNoStatic inner3 = new Outer().new InnerNoStatic(); //note the calls
Your can also use an existing instance.
Outer outer = new Outer();
Outer.InnerNoStatic inner3 = outer.new InnerNoStatic();
In both of these cases, an Outer
instance is used to build an InnerNoStatic
instance (there's just no variable pointing to the Outer
object created with new Outer().new InnerNoStatic()
)
Note: It's easy to confuse new Outer.Inner();
with new Outer().new Inner();
. These are not doing the same thing ("Outer" in the former is basically playing the role of a namespace, whereas new Outer()
in the latter is creating an Outer
object). That is, one constructor call (Inner()
) in the former, but two constructor calls in the latter (Outer()
and Inner()
).
答案4
得分: 1
非静态内部类始终引用相应的外部类。因此,只能通过外部类来实例化这样的类。
相反地,静态内部类不引用外部类,并且可以由任何其他对象创建,如果可见性允许的话。这与静态方法的行为非常相似,静态方法调用时不需要对象实例。
英文:
Non-static inner classes always have a reference to a corresponding outer class. As a result, such class can be instantiated only by Outer class.
In opposite, a static inner class has no reference to Outer class and can be created by any other object, if visibility allows that. This is very similar to the behavior of static methods, that do not require an objects instance to be called.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论