Omn*_*ent 1691 java inner-classes static-classes
Java中的内部类和静态嵌套类之间的主要区别是什么?设计/实施是否在选择其中一个方面发挥作用?
Mar*_*tin 1638
从Java教程:
嵌套类分为两类:静态和非静态.声明为static的嵌套类简称为静态嵌套类.非静态嵌套类称为内部类.
使用封闭的类名访问静态嵌套类:
OuterClass.StaticNestedClass
Run Code Online (Sandbox Code Playgroud)
例如,要为静态嵌套类创建对象,请使用以下语法:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
Run Code Online (Sandbox Code Playgroud)
作为内部类的实例的对象存在于外部类的实例中.考虑以下类:
class OuterClass {
...
class InnerClass {
...
}
}
Run Code Online (Sandbox Code Playgroud)
InnerClass的实例只能存在于OuterClass的实例中,并且可以直接访问其封闭实例的方法和字段.
要实例化内部类,必须首先实例化外部类.然后,使用以下语法在外部对象中创建内部对象:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Run Code Online (Sandbox Code Playgroud)
请参阅:Java教程 - 嵌套类
class A {
int t() { return 1; }
static A a = new A() { int t() { return 2; } };
}
Run Code Online (Sandbox Code Playgroud)
这里new A() { ... }
是一个在静态上下文中定义的内部类,没有封闭的实例.
Jeg*_*sch 578
在Java教程说:
术语:嵌套类分为两类:静态和非静态.声明为static的嵌套类简称为静态嵌套类.非静态嵌套类称为内部类.
一般说来,术语"嵌套"和"内部"可以被大多数程序员互换使用,但我会使用正确的术语"嵌套类",它涵盖了内部和静态.
类可以无限制地嵌套,例如,类A可以包含类B,其包含类C,其包含类D等.然而,多于一级的类嵌套是罕见的,因为它通常是糟糕的设计.
您可以创建嵌套类有三个原因:
Java中有四种嵌套类.简而言之,它们是:
让我详细说明一下.
静态类是最容易理解的类,因为它们与包含类的实例无关.
静态类是声明为另一个类的静态成员的类.就像其他静态成员一样,这样的类实际上只是一个使用包含类作为其命名空间的hanger,例如,在包披萨中声明为类Rhino的静态成员的类Goat被称为pizza.Rhino.Goat.
package pizza;
public class Rhino {
...
public static class Goat {
...
}
}
Run Code Online (Sandbox Code Playgroud)
坦率地说,静态类是一个非常没用的功能,因为类已经被包分成了命名空间.创建静态类的唯一真正可能的原因是这样的类可以访问其包含类的私有静态成员,但我发现这是静态类特性存在的一个相当蹩脚的理由.
内部类是声明为另一个类的非静态成员的类:
package pizza;
public class Rhino {
public class Goat {
...
}
private void jerry() {
Goat g = new Goat();
}
}
Run Code Online (Sandbox Code Playgroud)
与静态类一样,内部类被称为包含类名称pizza.Rhino.Goat的限定类,但在包含类中,它可以通过其简单名称来识别.然而,一个内部类的每一个实例被绑定到其包含类的特定实例:如上所述,山羊中创建杰里,被隐式地绑定到犀牛实例这在杰里.否则,我们在实例化Goat时使关联的Rhino实例显式化:
Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();
Run Code Online (Sandbox Code Playgroud)
(注意你用奇怪的新语法将内部类型称为Goat:Java从rhino部分推断出包含类型.而且,新的rhino.Goat()对我来说也更有意义.)
那么这对我们有什么影响呢?好吧,内部类实例可以访问包含类实例的实例成员.这些封闭的实例成员仅通过它们的简单名称引用到内部类中,而不是通过 它(这在内部类中引用内部类实例,而不是关联的包含类实例):
public class Rhino {
private String barry;
public class Goat {
public void colin() {
System.out.println(barry);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在内部类中,您可以将包含类的this引用为Rhino.this,您可以使用它来引用其成员,例如Rhino.this.barry.
本地内部类是在方法体中声明的类.这样的类只在其包含方法中是已知的,因此它只能被实例化并在其包含方法中访问其成员.增益是本地内部类实例绑定并可以访问其包含方法的最终局部变量.当实例使用其包含方法的最终局部时,该变量将保留实例创建时保留的值,即使该变量已超出范围(这实际上是Java的粗略,有限版本的闭包).
由于本地内部类既不是类或包的成员,也不会使用访问级别声明它.(但要明确的是,它自己的成员具有像普通类一样的访问级别.)
如果局部内部类是一个实例方法声明,内部类的一个实例绑定到由含有方法的召开实例这在实例的创建的时间,所以包含类的实例成员都像一个实例访问内心阶级.本地内部类只是通过其名称实例化,例如本地内部类Cat被实例化为新的Cat(),而不是你想象的新的this.Cat().
匿名内部类是编写本地内部类的语法上方便的方法.最常见的是,每次运行包含方法时,本地内部类最多只被实例化一次.那么,如果我们可以将本地内部类定义和它的单个实例化组合成一个方便的语法形式,那将是很好的,如果我们不必为该类想出一个名称也会很好(无用的更少)你的代码包含的名称越多越好.匿名内部类允许这两件事:
new *ParentClassName*(*constructorArgs*) {*members*}
Run Code Online (Sandbox Code Playgroud)
这是一个返回未命名类的新实例的表达式,该实例扩展了ParentClassName.你不能提供自己的构造函数; 相反,一个是隐式提供的,它只是调用超级构造函数,因此提供的参数必须适合超级构造函数.(如果父级包含多个构造函数,则称为"最简单"的构造函数,"最简单",由一组相当复杂的规则决定,不值得详细学习 - 只需注意NetBeans或Eclipse告诉您的内容.)
或者,您可以指定要实现的接口:
new *InterfaceName*() {*members*}
Run Code Online (Sandbox Code Playgroud)
这样的声明创建了一个未命名类的新实例,它扩展了Object并实现了InterfaceName.同样,你不能提供自己的构造函数; 在这种情况下,Java隐式地提供了一个no-arg,do-nothing构造函数(因此在这种情况下永远不会有构造函数参数).
即使你不能给匿名内部类一个构造函数,你仍然可以使用初始化块(在任何方法之外放置一个{}块)进行任何你想要的设置.
要明确的是,匿名内部类只是一种使用一个实例创建本地内部类的灵活性较低的方法.如果你想要一个实现多个接口的本地内部类,或者在扩展某个类而不是Object或者指定自己的构造函数的情况下实现接口,那么你就会陷入创建常规命名的本地内部类的困境.
jru*_*lph 140
我不认为上述答案中真正的区别变得清晰.
首先要使条款正确:
到目前为止,马丁的回答是正确的.但是,实际的问题是:声明嵌套类静态的目的是什么?
如果您只想将类保持在一起,或者如果嵌套类专门用于封闭类,则可以使用静态嵌套类.静态嵌套类与每个其他类之间没有语义差异.
非静态嵌套类是一种不同的野兽.与匿名内部类相似,这种嵌套类实际上是闭包.这意味着他们捕获周围的范围及其封闭的实例并使其可访问.也许一个例子将澄清这一点.查看Container的这个存根:
public class Container {
public class Item{
Object data;
public Container getContainer(){
return Container.this;
}
public Item(Object data) {
super();
this.data = data;
}
}
public static Item create(Object data){
// does not compile since no instance of Container is available
return new Item(data);
}
public Item createSubItem(Object data){
// compiles, since 'this' Container is available
return new Item(data);
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您希望从子项目到父容器的引用.使用非静态嵌套类,这没有一些工作.您可以使用语法访问Container的封闭实例Container.this
.
更多核心解释如下:
如果查看编译器为(非静态)嵌套类生成的Java字节码,它可能会变得更加清晰:
// class version 49.0 (49)
// access flags 33
public class Container$Item {
// compiled from: Container.java
// access flags 1
public INNERCLASS Container$Item Container Item
// access flags 0
Object data
// access flags 4112
final Container this$0
// access flags 1
public getContainer() : Container
L0
LINENUMBER 7 L0
ALOAD 0: this
GETFIELD Container$Item.this$0 : Container
ARETURN
L1
LOCALVARIABLE this Container$Item L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 1
public <init>(Container,Object) : void
L0
LINENUMBER 12 L0
ALOAD 0: this
ALOAD 1
PUTFIELD Container$Item.this$0 : Container
L1
LINENUMBER 10 L1
ALOAD 0: this
INVOKESPECIAL Object.<init>() : void
L2
LINENUMBER 11 L2
ALOAD 0: this
ALOAD 2: data
PUTFIELD Container$Item.data : Object
RETURN
L3
LOCALVARIABLE this Container$Item L0 L3 0
LOCALVARIABLE data Object L0 L3 2
MAXSTACK = 2
MAXLOCALS = 3
}
Run Code Online (Sandbox Code Playgroud)
如您所见,编译器会创建一个隐藏字段Container this$0
.这是在构造函数中设置的,该构造函数具有Container类型的附加参数以指定封闭实例.您无法在源中看到此参数,但编译器会为嵌套类隐式生成它.
马丁的例子
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Run Code Online (Sandbox Code Playgroud)
会被编译成类似(在字节码中)的调用
new InnerClass(outerObject)
Run Code Online (Sandbox Code Playgroud)
为了完整起见:
匿名类是刚刚没有与之关联的名称,并且不能在以后引用非静态嵌套类的一个很好的例子.
ale*_*oot 90
我认为上述答案都没有向您解释嵌套类和静态嵌套类在应用程序设计方面的真正区别:
嵌套类可以是非静态的,也可以是静态的,并且在每种情况下都是在另一个类中定义的类.嵌套类应该只存在于封闭类中,如果嵌套类对其他类(不仅是封闭的)有用,则应该声明为顶级类.
非静态嵌套类:与包含类的封闭实例隐式关联,这意味着可以调用封闭实例的方法和访问变量.非静态嵌套类的一个常见用途是定义Adapter类.
静态嵌套类:无法访问封闭的类实例并在其上调用方法,因此在嵌套类不需要访问封闭类的实例时应该使用它.静态嵌套类的一个常见用途是实现外部对象的组件.
因此,从设计的角度来看,两者之间的主要区别是:非静态嵌套类可以访问容器类的实例,而静态则不能.
Tha*_*var 32
简单来说,我们需要嵌套类主要是因为Java不提供闭包.
嵌套类是在另一个封闭类的主体内定义的类.它们有两种类型 - 静态和非静态.
它们被视为封闭类的成员,因此您可以指定四个访问说明符中的任何一个 - private, package, protected, public
.我们没有顶级类的奢侈品,只能声明public
或包私有.
内部类也称为非堆栈类可以访问顶级类的其他成员,即使它们被声明为私有,而静态嵌套类也无法访问顶级类的其他成员.
public class OuterClass {
public static class Inner1 {
}
public class Inner2 {
}
}
Run Code Online (Sandbox Code Playgroud)
Inner1
是我们的静态内部类,Inner2
是我们的内部类,它不是静态的.它们之间的关键区别是,您无法创建Inner2
没有外部的实例,因为您可以Inner1
独立创建对象.
你什么时候使用内心课?
考虑一种情况,其中Class A
和Class B
相关,Class B
需要访问Class A
成员,并且Class B
仅与之相关Class A
.内部课程进入了画面.
要创建内部类的实例,需要创建外部类的实例.
OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();
Run Code Online (Sandbox Code Playgroud)
要么
OuterClass.Inner2 inner = new OuterClass().new Inner2();
Run Code Online (Sandbox Code Playgroud)
你什么时候使用静态内部类?
当您知道它与封闭类/顶级类的实例没有任何关系时,您将定义一个静态内部类.如果你的内部类不使用外部类的方法或字段,那只是浪费空间,所以将它静态化.
例如,要为静态嵌套类创建对象,请使用以下语法:
OuterClass.Inner1 nestedObject = new OuterClass.Inner1();
Run Code Online (Sandbox Code Playgroud)
静态嵌套类的优点是它不需要包含类/顶级类的对象.这可以帮助您减少应用程序在运行时创建的对象数量.
Beh*_*yar 27
以下是Java内部类和静态嵌套类之间的主要区别和相似之处.
希望能帮助到你!
与封闭类的实例关联以便首先实例化它需要一个外部类的实例(注意新关键字的地方):
Outerclass.InnerClass innerObject = outerObject.new Innerclass();
Run Code Online (Sandbox Code Playgroud)无法定义任何静态成员本身
无法访问外部类实例方法或字段
与封闭类的任何实例都没有关联,以便实例化它:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
Run Code Online (Sandbox Code Playgroud)根据Oracle文档,有几个原因(完整文档):
它是一种逻辑分组仅在一个地方使用的类的方法:如果一个类只对另一个类有用,那么将它嵌入该类并将两者保持在一起是合乎逻辑的.嵌套这样的"帮助类"使得它们的包更加简化.
它增加了封装:考虑两个顶级类A和B,其中B需要访问A的成员,否则这些成员将被声明为私有.通过将类B隐藏在类A中,可以将A的成员声明为私有,并且B可以访问它们.另外,B本身可以隐藏在外面.
它可以带来更易读和可维护的代码:在顶级类中嵌套小类会使代码更接近于使用它的位置.
sac*_*tiw 26
我认为,通常遵循的惯例是:
但是,要记住的其他几点是:
顶级类和静态嵌套类在语义上是相同的,除了在静态嵌套类的情况下,它可以对其外部[父]类的私有静态字段/方法进行静态引用,反之亦然.
内部类可以访问Outer [parent]类的封闭实例的实例变量.但是,并非所有内部类都包含实例,例如静态上下文中的内部类,如静态初始化程序块中使用的匿名类,则不会.
默认情况下,匿名类扩展父类或实现父接口,并且没有其他子句可以扩展任何其他类或实现更多接口.所以,
new YourClass(){};
手段 class [Anonymous] extends YourClass {}
new YourInterface(){};
手段 class [Anonymous] implements YourInterface {}
我觉得更大的问题仍然是开放哪一个使用什么时候?那么这主要取决于你正在处理的场景,但阅读@jrudolph给出的答案可能会帮助你做出一些决定.
小智 15
嵌套类:类内部的类
类型:
区别:
非静态嵌套类[Inner class]
在非静态嵌套类内部类的对象存在于外部类的对象中.因此外部类的数据成员可以被内部类访问.因此要创建内部类的对象,我们必须首先创建外部类的对象.
outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass();
Run Code Online (Sandbox Code Playgroud)
静态嵌套类
在内部类的静态嵌套类对象中不需要外部类的对象,因为单词"static"表示不需要创建对象.
class outerclass A {
static class nestedclass B {
static int x = 10;
}
}
Run Code Online (Sandbox Code Playgroud)
如果要访问x,请编写以下内部方法
outerclass.nestedclass.x; i.e. System.out.prinltn( outerclass.nestedclass.x);
Run Code Online (Sandbox Code Playgroud)
rma*_*ski 11
在创建外部类的实例时,将创建内部类的实例.因此,内部类的成员和方法可以访问外部类的实例(对象)的成员和方法.当外部类的实例超出范围时,内部类实例也不再存在.
静态嵌套类没有具体实例.它刚刚在第一次使用时加载(就像静态方法一样).它是一个完全独立的实体,其方法和变量无法访问外部类的实例.
静态嵌套类不与外部对象耦合,它们更快,并且它们不占用堆/堆栈内存,因为它不需要创建此类的实例.因此经验法则是尝试定义静态嵌套类,尽可能限制范围(private> = class> = protected> = public),然后将其转换为内部类(通过删除"静态"标识符)并放松范围,如果真的有必要的话.
Hip*_*Man 11
关于嵌套静态类的使用有一些微妙之处,这些静态类在某些情况下可能很有用.
静态属性在通过构造函数实例化类之前得到实例化,嵌套静态类中的静态属性似乎直到调用类的构造函数之后才被实例化,或者至少直到首次引用属性之后才被实例化,即使它们被标记为"最终".
考虑这个例子:
public class C0 {
static C0 instance = null;
// Uncomment the following line and a null pointer exception will be
// generated before anything gets printed.
//public static final String outerItem = instance.makeString(98.6);
public C0() {
instance = this;
}
public String makeString(int i) {
return ((new Integer(i)).toString());
}
public String makeString(double d) {
return ((new Double(d)).toString());
}
public static final class nested {
public static final String innerItem = instance.makeString(42);
}
static public void main(String[] argv) {
System.out.println("start");
// Comment out this line and a null pointer exception will be
// generated after "start" prints and before the following
// try/catch block even gets entered.
new C0();
try {
System.out.println("retrieve item: " + nested.innerItem);
}
catch (Exception e) {
System.out.println("failed to retrieve item: " + e.toString());
}
System.out.println("finish");
}
}
Run Code Online (Sandbox Code Playgroud)
即使'nested'和'innerItem'都被声明为'static final'.在实例化类之后(或者至少直到首次引用嵌套静态项之后)才会发生nested.innerItem的设置,因为您可以通过注释和取消注释我引用的行来自行查看,以上.同样不适用于'outerItem'.
至少这是我在Java 6.0中看到的.
Ank*_*ain 10
在创建实例的情况下,非静态内部类的实例是使用外部类的对象的引用创建的,在该对象中定义它.这意味着它有实例.但是静态内部类的实例是使用外部类的引用创建的,而不是使用外部类的对象的引用.这意味着它没有包含实例.
例如:
class A
{
class B
{
// static int x; not allowed here…..
}
static class C
{
static int x; // allowed here
}
}
class Test
{
public static void main(String… str)
{
A o=new A();
A.B obj1 =o.new B();//need of inclosing instance
A.C obj2 =new A.C();
// not need of reference of object of outer class….
}
}
Run Code Online (Sandbox Code Playgroud)
我不认为这里有很多内容,大多数答案完美地解释了静态嵌套类和内部类之间的区别.但是,在使用嵌套类与内部类时请考虑以下问题.作为一对夫妇的答案提到的内部类不能没有和他们的外围类的实例,它意味着他们被实例化HOLD一个指针,以他们的包围类的实例,它可能会导致内存溢出或堆栈溢出异常由于在GC即使它们不再使用,也无法对封闭类进行垃圾收集.为清楚起见,请检查以下代码:
public class Outer {
public class Inner {
}
public Inner inner(){
return new Inner();
}
@Override
protected void finalize() throws Throwable {
// as you know finalize is called by the garbage collector due to destroying an object instance
System.out.println("I am destroyed !");
}
}
public static void main(String arg[]) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
// out instance is no more used and should be garbage collected !!!
// However this will not happen as inner instance is still alive i.e used, not null !
// and outer will be kept in memory until inner is destroyed
outer = null;
//
// inner = null;
//kick out garbage collector
System.gc();
}
Run Code Online (Sandbox Code Playgroud)
如果你删除评论// inner = null;
该程序将把" 我被摧毁! ",但保持这个评论它不会.
原因是仍然引用了白色内部实例GC无法收集它,并且因为它引用(有一个指针)外部实例它也没有被收集.在项目中有足够的这些对象,并且可能会耗尽内存.
与不与内部类实例有关的静态内部类相比,因为它与实例无关但与类相关.如果你使Inner类静态并实例化,上面的程序可以打印" 我被销毁! "Outer.Inner i = new Outer.Inner();
这些术语可互换使用.如果你想对它真的很迂腐,那么你可以定义"嵌套类"来引用一个静态内部类,一个没有封闭实例.在代码中,您可能会遇到以下情况:
public class Outer {
public class Inner {}
public static class Nested {}
}
Run Code Online (Sandbox Code Playgroud)
但这并不是一个广泛接受的定义.
嗯......内部类是一个嵌套类...你的意思是匿名类和内部类吗?
编辑:如果你实际上意味着内部与匿名......内部类只是在类中定义的类,例如:
public class A {
public class B {
}
}
Run Code Online (Sandbox Code Playgroud)
而匿名类是匿名定义的类的扩展,因此没有定义实际的"类",如:
public class A {
}
A anon = new A() { /* you could change behavior of A here */ };
Run Code Online (Sandbox Code Playgroud)
进一步编辑:
维基百科声称 Java 存在差异,但我已经使用Java工作了8年,这是我第一次听到这样的区别......更不用说那里没有提到支持声明了...... line,内部类是在类中定义的类(静态或非静态),嵌套只是另一个术语,意思是相同的东西.
静态和非静态嵌套类之间存在细微差别...基本上非静态内部类具有对实例字段的隐式访问和封闭类的方法(因此它们不能在静态上下文中构造,它将是一个编译器错误).另一方面,静态嵌套类没有对实例字段和方法的隐式访问,并且可以在静态上下文中构造.
针对学习者,他们是Java和/或嵌套类的新手
嵌套类可以是:
1.静态嵌套类.
2.非静态嵌套类.(也称为内课)=>请记住这一点
1.Inner类
示例:
class OuterClass {
/* some code here...*/
class InnerClass { }
/* some code here...*/
}
Run Code Online (Sandbox Code Playgroud)
内部类是嵌套类的子集:
内班专业:
2.静态嵌套类:
示例:
class EnclosingClass {
static class Nested {
void someMethod() { System.out.println("hello SO"); }
}
}
Run Code Online (Sandbox Code Playgroud)
情况1:从非封闭类中实例化静态嵌套类
class NonEnclosingClass {
public static void main(String[] args) {
/*instantiate the Nested class that is a static
member of the EnclosingClass class:
*/
EnclosingClass.Nested n = new EnclosingClass.Nested();
n.someMethod(); //prints out "hello"
}
}
Run Code Online (Sandbox Code Playgroud)
情况2:从封闭类中实例化静态嵌套类
class EnclosingClass {
static class Nested {
void anotherMethod() { System.out.println("hi again"); }
}
public static void main(String[] args) {
//access enclosed class:
Nested n = new Nested();
n.anotherMethod(); //prints out "hi again"
}
}
Run Code Online (Sandbox Code Playgroud)
静态课程专业:
结论:
问题: Java中内部类和静态嵌套类之间的主要区别是什么?
答:只需仔细阅读上面提到的每个课程的具体内容.
Java中的内部类和嵌套静态类都是在另一个类中声明的类,在Java中称为顶级类.在Java术语中,如果声明嵌套类为static,则它将在Java中调用嵌套静态类,而非静态嵌套类则简称为内部类.
什么是Java中的内部类?
任何不是顶级或在另一个类中声明的类称为嵌套类,在这些嵌套类中,声明为非静态的类在Java中称为Inner类.Java中有三种内部类:
1)本地内部类 - 在代码块或方法中声明.
2)匿名内部类 - 是一个没有名称可引用的类,并在创建它的同一位置初始化.
3)成员内部类 - 被声明为外部类的非静态成员.
public class InnerClassTest {
public static void main(String args[]) {
//creating local inner class inside method i.e. main()
class Local {
public void name() {
System.out.println("Example of Local class in Java");
}
}
//creating instance of local inner class
Local local = new Local();
local.name(); //calling method from local inner class
//Creating anonymous inner class in Java for implementing thread
Thread anonymous = new Thread(){
@Override
public void run(){
System.out.println("Anonymous class example in java");
}
};
anonymous.start();
//example of creating instance of inner class
InnerClassTest test = new InnerClassTest();
InnerClassTest.Inner inner = test.new Inner();
inner.name(); //calling method of inner class
}
//Creating Inner class in Java
private class Inner{
public void name(){
System.out.println("Inner class example in java");
}
}
}
Run Code Online (Sandbox Code Playgroud)
什么是Java中的嵌套静态类?
嵌套静态类是另一个类,它在类中声明为成员并且是静态的.嵌套静态类也被声明为外部类的成员,可以像任何其他成员一样使其成为私有,公共或受保护.嵌套静态类相对于内部类的主要好处之一是嵌套静态类的实例未附加到任何外部类的外部实例.您也不需要任何Outer实例来在Java中创建嵌套静态类的实例.
1)它可以访问外部类的静态数据成员,包括private.
2)静态嵌套类无法访问非静态(实例)数据成员或方法.
public class NestedStaticExample {
public static void main(String args[]){
StaticNested nested = new StaticNested();
nested.name();
}
//static nested class in java
private static class StaticNested{
public void name(){
System.out.println("static nested class example in java");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想这里的人应该注意到海报:Static Nest Class只是第一个内部类.例如:
public static class A {} //ERROR
public class A {
public class B {
public static class C {} //ERROR
}
}
public class A {
public static class B {} //COMPILE !!!
}
Run Code Online (Sandbox Code Playgroud)
因此,总结一下,静态类不依赖于它包含哪个类.所以,他们不能在正常的课堂上.(因为普通类需要一个实例).
小智 5
当我们在类中声明静态成员类时,它被称为顶级嵌套类或静态嵌套类.它可以证明如下:
class Test{
private static int x = 1;
static class A{
private static int y = 2;
public static int getZ(){
return B.z+x;
}
}
static class B{
private static int z = 3;
public static int getY(){
return A.y;
}
}
}
class TestDemo{
public static void main(String[] args){
Test t = new Test();
System.out.println(Test.A.getZ());
System.out.println(Test.B.getY());
}
}
Run Code Online (Sandbox Code Playgroud)
当我们在类中声明非静态成员类时,它被称为内部类.内部类可以如下所示:
class Test{
private int i = 10;
class A{
private int i =20;
void display(){
int i = 30;
System.out.println(i);
System.out.println(this.i);
System.out.println(Test.this.i);
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我认为上述答案都没有给您提供真实的例子,说明嵌套类和静态嵌套类在应用程序设计方面的区别。静态嵌套类和内部类的主要区别在于访问外部类实例字段的能力。
让我们看一下下面两个例子。
静态嵌套类:使用静态嵌套类的一个很好的例子是构建器模式(https://dzone.com/articles/design-patterns-the-builder-pattern)。
对于 BankAccount 我们使用静态嵌套类,主要是因为
静态嵌套类实例可以在外部类之前创建。
在构建器模式中,构建器是一个帮助器类,用于创建 BankAccount。
public class BankAccount {
private long accountNumber;
private String owner;
...
public static class Builder {
private long accountNumber;
private String owner;
...
static public Builder(long accountNumber) {
this.accountNumber = accountNumber;
}
public Builder withOwner(String owner){
this.owner = owner;
return this;
}
...
public BankAccount build(){
BankAccount account = new BankAccount();
account.accountNumber = this.accountNumber;
account.owner = this.owner;
...
return account;
}
}
}
Run Code Online (Sandbox Code Playgroud)
内部类:内部类的常见用途是定义事件处理程序。 https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
对于MyClass,我们使用内部类,主要是因为:
内部类MyAdapter需要访问外部类成员。
在示例中,MyAdapter 仅与 MyClass 关联。没有其他类与 MyAdapter 相关。因此最好将它们组织在一起而不使用命名约定
public class MyClass extends Applet {
...
someObject.addMouseListener(new MyAdapter());
...
class MyAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
...// Event listener implementation goes here...
...// change some outer class instance property depend on the event
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
701666 次 |
最近记录: |