Java内流和静态嵌套类
-
09-06-2019 - |
题
是什么之间的主要差别的一个内部类和一个静态的嵌套类Java?并设计/执行方面发挥作用,在选择这个吗?
解决方案
从 Java教程:
嵌套的课程都分为两类:静止和非静态的。嵌套类声明的静态是简单地称之为静态的嵌套的课程。非静态的嵌套的课程被称为内部课程。
静态的嵌套类访问使用的封闭类的名称:
OuterClass.StaticNestedClass
例如,创造一个目的的静态嵌套类,使用这种语法:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
对象的实例的内流存在的一个实例外类。考虑以下几类:
class OuterClass {
...
class InnerClass {
...
}
}
一个实例InnerClass只能存在的一个实例OuterClass和直接访问的方法和领域的其封闭的实例。
实例的内流,必须首先实例外类。然后,创建内目内外的对象用这种语法:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
参见: Java教程的嵌套类
为完整起见请注意,还有这样的事情的一个 内舱 没有 一个封闭的实例:
class A {
int t() { return 1; }
static A a = new A() { int t() { return 2; } };
}
在这里, new A() { ... }
是一个 内类中定义的一种静态的方面 并没有一个封闭的实例。
其他提示
的 Java教程说:
术语:嵌套的课程 分为两类:静 并非静态的。嵌套类 被宣布为静态的简称 静态的嵌套的课程。非静态的 嵌套的课程被称为内 课程。
在共同的说法,该条款"嵌套的"和"内在"可交换使用的大多数程序员,但我会用正确的术语"嵌套的课",其中涵盖内部以及静态的。
课程可以嵌套 循环往复, 如A类可以包含有B类,它包含C类,其中包含D类,等等。然而,多于一个等级的舱筑巢是罕见的,因为它一般是坏的设计。
有三个原因,你可能会建立一套类:
- 组织:有时它似乎最合理的种类进入空间的另一个类,特别是当它不会被用于任何其他方面
- 访问:嵌套课程有特别的入变量/领域,它们包含类(精确的变量/领域取决于这种嵌套类,无论是内部或静态)。
- 便利:具有创建一个新的文件,对于每一个新的类型是麻烦的,再次,特别是当类型将只使用一个上下文
还有 四种嵌套类Java.简言之,它们是:
- 静类:宣布作为一个静态的成员,另一类
- 内舱:宣布作为一个实例成员的另一类
- 当地内类:宣布内部的一个实例法中的另一类
- 匿名内部流:就像一个地方内类,但是书面作为一个表达其返回的一个对象
让我详细阐述的更多详细信息。
静类
静类最简单的一种理解,因为他们什么都没有做与的实例包含类。
一个静态的类是一个类声明作为一个静态的成员,另一类。就像其他的静态的成员,这样一类是真的只是一个吊架上使用含有类作为其名字空间, 例如 类 山羊 宣布作为一个静态部件的类 犀牛 在包 披萨 是已知的名字 比萨。犀牛。山羊.
package pizza;
public class Rhino {
...
public static class Goat {
...
}
}
坦率地说,静类是一个漂亮的毫无价值的特征,因为课程已经分成名字空间由软件包。只有真正的可想到的理由来创建一个静态的类是这一类访问其包含类的私有静态的成员,但我发现这是很蹩脚的理由的类的静态功能存在。
内部类
内类是一个类宣布为非静态的成员,另一类:
package pizza;
public class Rhino {
public class Goat {
...
}
private void jerry() {
Goat g = new Goat();
}
}
像一个静态的类,内类被称为合格通过其含有类的名称, 比萨。犀牛。山羊, 但里面包含类,可以称通过其简单的名称。但是,每个实例的内部流是依赖于特定的实例,其中含有类:上述, 山羊 创建 杰瑞, 是隐含地绑的 犀牛 实例 此 在 杰瑞.否则,我们的关联 犀牛 实例明确,当我们实例 山羊:
Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();
(注意到你提到的内的类型只是 山羊 在奇怪 新的 语法:Java推断含有类型 犀牛 部分。而且,是的 新的犀牛。山羊() 会作出更多意识到我了。)
那么,这一获得我们吗?好了,内类实例访问的实例,成员包含类实例。这些包围的实例成员都提到的内类 通过 只是他们简单的名称,不 通过 此 (此 在内部流是指内部类实例中,没有相关的含有类实例):
public class Rhino {
private String barry;
public class Goat {
public void colin() {
System.out.println(barry);
}
}
}
在内部流,可以参考 此 包含类为 犀牛。此, 和你可以使用 此 参阅向其成员, 例如犀牛。这一点。barry.
当地内的类
本地内类是一个类声明的体的方法。这样一类是唯一已知的在其包含的方法,所以它只能被实例和它的成员访问在其包含的方法。益的是,一个当地内的类实例是联系,并且可以访问的最后地方的变量,其包含的方法。实例时使用的最终地的其包含的方法,可变保留价值的举行时间的实例是建立,即使变了范围(这是有效Java粗,有限的版本的封锁).
因为当地的内部流的既不是成员的一类或包装,就不宣布的访问水平。(是清楚的,但是,它自己的成员都可以访问的级别,如在一个正常班。)
如果当地的内部类声明的一个实例的方法,一个实例的内部流是联系在一起的实例举行的由含有方法的 此 当时的实例建立的,所以包含类的实例成员都可以喜欢一个实例内类。当地的内部流化简单 通过 它的名字, 例如 当地内类 猫 实例化为 新的猫(), 不新这一点。猫()作为你可能期望。
匿名内部课程
一个匿名内部流是语法上的便利方式编写的本地内的类。最常见的是,一个当地的内部流化在大多数只是一旦每个时间,其包含的方法是运行。这将是很好的,然后,如果我们可以结合当地内类的定义及其个实例化为一个方便的语法形式,并且它也会很好如果我们没有想到了一个名为类(减少无用的姓名代码包含好)。一个匿名内部流允许这些事情:
new *ParentClassName*(*constructorArgs*) {*members*}
这是一个表达返回了一个新的实例一位不愿透露姓名类延伸 ParentClassName.您不能提供自己的构造;相反,一个是含蓄地提供这只是呼吁超级的构造,使所提供的参数必须符合的超构造。(如果父包含了多个构造,"简单的"一个被称为"最简单"确定通过一个相当复杂的规则不值得打扰到详细了解--只要注意什么//需要将物品寄或蚀告诉你.)
或者,可以指定一个接口,以实施:
new *InterfaceName*() {*members*}
这一宣言创建一个新的实例一位不愿透露姓名类延伸的对象,并实现了 InterfaceName.再次,你不能提供自己的构造;在这种情况下,Java隐含地提供一个没有阿根廷、做的-什么构造(使永远不会有构造的论点,在这种情况下)。
即使你不能给一个匿名内部流的一个构造,你仍然可以做任何安装你想要使用的一种初始化框(a{}块的放置之外的任何方法)。
明确的是,匿名内部流的只是一个较不灵活的方式创建当地内类的一个实例。如果你想要的本地内这类实现了多个接口或其实现接口,同时延伸的一些其他类比 对象 或者指定其自己的构造,你坚持创建一个普通的名为当地内的类。
我不认为真正的区别清楚在上述答复。
第一,获得方面的权利:
- 一套类是一个类,它包含在另一个类的源代码的水平。
- 它是静态的,如果声明它与 静 改性剂。
- 非静态的嵌套类被称为内类。(I留与非静态的嵌套类。)
马丁的回答是正确的这么远。然而,实际的问题是:什么样的目的是宣布一套类的静态或者不能?
你使用 静态的嵌套类 如果你只是想跟你一起上课,如果他们属于局部一起,或者如果嵌套类是专门用于在封闭类。没有语义之间的差异的一个静态的嵌套类和所有其他类。
非静态的嵌套类 是一个不同的野兽。类似于匿名内部课程,这套课程都实际上关闭。这意味着他们捕获他们的周边范围和他们的包围的实例,并使这一访问。也许是一个例子将澄清。看看这票根的一个容器:
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);
}
}
在这种情况下你想要有一个参考儿童的项目向父容器。使用非静态的嵌套类,这个工作没有的一些工作。你可以访问的实例包围的容器的语法 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
}
正如你可以看到编译器创建了一个隐藏的场 Container this$0
.这是设置的构造其具有附加参数的容器类型,以指定封闭的实例。你不能看此参数的来源,但编译器隐含地产生了一套类。
马丁例
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
会使汇编到一个电话喜欢的东西(在字节)
new InnerClass(outerObject)
为了完整性:
一个匿名流 是 一个完美的例子的一个非静态的嵌套类,这只是没有名字与它相关联和不可引用后。
我认为,没有上述的答复向你解释之间的真正区别的一套类和一个静态的嵌套类术语的应用程序的设计:
概述
一套类 可能是非静态或静态和在每个情况下 是一类的定义内的另一类. 一套类应该仅存在于作为封闭类, 如果一套类是有用的其他类(不仅是封闭的),应宣布为一个顶级的类。
差
非静态的嵌套类 :是隐含相关的封闭的实例包含类,这意味着它可以调用的方法和访问量的变量包围的实例。一个常见用途的非静态的嵌套类是确定一个适配器类。
静态的嵌套类 :不能访问封闭类实例和调用的方法上,所以应使用当的嵌套类并不需要访问的实例包围类。共同使用的静态嵌套类是实现一个组成部分的外对象。
结论
所以主要区别两者之间从设计的角度来看是: 非静态的嵌套类可以访问的实例的容器类,同时不能静.
简而言之我们需要套课程主要是因为Java没有提供关闭。
嵌套类是定义的主体内的另一个封闭类。他们有两种类型-静止和非静态的。
他们都被作为成员的封闭类,因此可以指定的四个访问符- private, package, protected, public
.我们没有这个豪华顶级课程,它只能声明 public
或者包裹-私人的。
内部类aka非堆类访问其他成员的顶级中,即使他们被宣布为私人当静态的嵌套类没有访问的其他成员的顶级。
public class OuterClass {
public static class Inner1 {
}
public class Inner2 {
}
}
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();
或
OuterClass.Inner2 inner = new OuterClass().new Inner2();
如果您使用的是静态的内班?
你将定义一个静态的内上课的时候你知道,它没有任何关系的实例的封闭类/顶类。如果你内心的类不使用方法或领域的外流,它只是一个废弃的空间,以使其静态的。
例如,创造一个目的的静态嵌套类,使用这种语法:
OuterClass.Inner1 nestedObject = new OuterClass.Inner1();
优势的静态嵌套类是,它不需要对象包含类/顶级的工作。这可以帮助你的数量减少对象的应用程序创建在运行时间。
我认为,《公约》,通常接着是这样的:
- 静类 在一个顶级的类是一个 嵌套类
- 非静态的类 在一个顶级的类是一个 内舱, ,这进一步
有两个形式:
- 当地的类 -叫班宣内的一块就像一个方法或构造的身体
- 匿名流 -未命名的课程的实例是建立在表达和言论
然而,其他几个 点要记住 有:
顶级课程和静态的嵌套类义相同,只是在情况下的静态嵌套类可以使静参考私人静领域/方法的其外[父]类,反之亦然。
内部类访问的实例变量的实例包围之外[父]类。然而,不是所有的内部课程都包围的实例,例如内部类的静态上下文中,像一个匿名的流用在一个静态的初始化框,不这样做。
匿名类默认情况下延伸父类或实现了父母的接口并没有进一步的条款延长的任何其他类或实现任何更多的接口。所以,
new YourClass(){};
装置class [Anonymous] extends YourClass {}
new YourInterface(){};
装置class [Anonymous] implements YourInterface {}
我觉得这个更大的问题,仍然是开放的使用哪一个?嗯,这主要取决于什么情况下你正在处理的,但阅读该答复由@jrudolph可以帮助你做一些决定。
这里是关键的差别和相似之处Java内流和静态嵌套类。
希望它能帮助!
内舱
- 可以访问 外层级 这两个实例和静 方法和领域
相关的实例的封闭类 这样的实例,它首先需求的一个实例外类(注 新的 关键的地方):
Outerclass.InnerClass innerObject = outerObject.new Innerclass();
不能 定义的任何 静态的成员 本身
- 不能 已 类 或 接口 宣言
静态的嵌套类
无法访问 外类 实例 方法或领域
不与任何实例的封闭类 这样的实例:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
相似之处
- 既 内部类 甚至可以访问 私人领域和方法 的 外类
- 还的 外类 有权访问 私人领域和方法 的 内部类
- 这两个课程可以拥有私人的、保护或公共访问的修改
为什么使用嵌套的课?
根据Oracle文件是有几个原因(完整的文档):
它是一种在逻辑上分组类,仅仅用在一个地方: 如果一类是有用的唯一一个其他类,那么它是合乎逻辑的嵌入它在那类和保持两个在一起。筑巢的这种"辅助课程",使他们的软件包的更加精简。
它增加了封装: 考虑两个顶级课程,A和B,B需要访问的成员,否则将被宣布为私有。通过隐藏B类内一级,成员国可以声明的私人和B可以对它们进行访问。此外,B本身可以被隐藏在外面的世界。
它可以导致更易读和易于维护的代码: 筑巢的小类内的顶级课程的地方代码接近它在哪里使用。
嵌套类:类类
类型:
- 静态的嵌套类
- 非静态的嵌套类[Inner class]
差异:
非静态的嵌套类[Inner class]
在非静态的嵌套课目的内流存在的目的之外的类。因此,数据会员的外流是可以访问的内类。因此,要创建目的内部类我们必须创造对象的外流的第一个。
outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass();
静态的嵌套类
在静嵌套课目的内部类不需要对象的外流,因为这个词"静态"表示没有必要建立对象。
class outerclass A {
static class nestedclass B {
static int x = 10;
}
}
如果你想要访问x,然后编写以下内的方法
outerclass.nestedclass.x; i.e. System.out.prinltn( outerclass.nestedclass.x);
实例的内创建类当实例的外流的创建。因此成员和方法的内部类访问的成员和方法的实例(目的)的外类。当例外类超出范围,也在内的类情况不再存在。
静嵌套类没有一个具体实例。这只是装载时,它第一次使用(就像静态的方法)。这是一个完全独立的实体,其方法和变量不会有任何访问的实例外类。
静嵌套类不是与外部对象,他们的速度更快,它们不要采取堆/堆的记忆,因为它没有必要建立实例种类。因此,该规则是试图定义静嵌套类,作为有限的范围作可能的(私人>=类>=保护>=公共),然后将其转换为内部类(通过删除"静态"的标识)和放松的范围,如果这是真的有必要。
有一个微妙的有关使用嵌套静态的课程,可能是有用的,在某些情况下。
鉴于静态属性,得到实例之前,这类变化通过其构造, 静态属性内嵌套的静态类似乎并没有得到实例之后 类的构造变得援引,或至少不直到以后的属性是第一个被引用, 即使他们被标记为'最终'.
考虑这个例子:
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");
}
}
虽然'嵌套的"和"innerItem'被宣布为'静止的最终'.设定 嵌套的。innerItem不发生之后直到该类实例(或至少 不,直到后嵌套的静止项目首先引用),正如你可以看到自己 通过评论,并取消注释的行我指,上面。同样不住 真正的'outerItem'.
至少这是我所看到的在Java6.0.
在这种情况下创建的实例,实例不 静内心的创建类与参考的 目的外流的其它定义。此 意味着它有inclosing的实例。但实例的静态内类 创建与所参考的外流,不用 参考的对象的外类。这意味着它 没有inclosing的实例。
例如:
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….
}
}
我不认为有很多要在这里补充,大部分的答复完美的解释的差异之间的静态嵌套的课内课程。然而,考虑下列问题时使用嵌套类vs内的课程。为说几个答案内的类不能实例和实例对他们的封闭类,这意味着他们 抱 一个 指针 实例,他们的封闭类可能导致记忆的溢出或栈溢出异常由于事实上的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();
}
如果你移除的评论 // inner = null;
该计划将出把
"我摧毁了!",但是保持这个评论也不会。
其原因是,白内实例仍然引用的GC无法收集它,因为它引用(有一个指向)外实例,它没有收集。具有足够的这些项目中的对象并且可以运行的存储器。
相比,静态的内部类不住点内的类实例,因为它是不相关的实例,但类有关。上述程序可以打印的"我摧毁了!"如果你让内类的静态和实例有 Outer.Inner i = new Outer.Inner();
该条款可互换使用。如果你想要真是迂腐的关于这一点,那么你 可能 定义"嵌套类"指一个静态的内流,一个没有封闭的实例。在代码时,可能会有这样的事情:
public class Outer {
public class Inner {}
public static class Nested {}
}
这不是一个被广泛接受的定义。
嵌套类是一个非常一般性的术语:每一类这不是顶级的一套类。一个内流是一个非静态的嵌套类。约瑟夫*达西写了一个非常好的解释 嵌套,内,成员,顶级课程.
嗯...内类是一种嵌套类...你的意思是匿名的课内课吗?
编辑:如果你实际上意味着内vs匿名...内类仅仅是一类定义内的一类,例如:
public class A {
public class B {
}
}
而一个匿名的流是一个扩展的一个类定义的匿名,因此没有实际"类限定,如:
public class A {
}
A anon = new A() { /* you could change behavior of A here */ };
进一步的编辑:
维基百科 索赔是有差别的 在爪哇,但我已经工作与Java为8年,而这是我第一次听到这种区别的...更不要说没有引用的那份声...底线,内类是一个类在类中定义(静态的或不是),并嵌套的只是一个术语意味着同样的事情。
有一种微妙的差异之间的静态而非静态的嵌套类...基本上非静态的内部类有隐含的访问的实例领域和方法的封闭类(因此它们不能构成在一个静态的背景下,这将是一个编译器错误)。静态的嵌套课程,另一方面,没有隐含的访问的实例领域和方法,并且可构成一个静态的上下文。
针对学习者,谁是新手Java和/或课程的嵌套
嵌套课程可:
1.静态的嵌套的课程。
2.非静态的嵌套课程。(也称为 内部类)=>请记住这个
1.内部类
例如:
class OuterClass {
/* some code here...*/
class InnerClass { }
/* some code here...*/
}
内部类子集的嵌套类:
- 内部类是一种特定类型的嵌套类
- 内部类子集的嵌套类
- 你可以说一个 内部类也是一种嵌套类,但你可以 不 说一套类也是一个内部类.
专业内类:
- 实例的内部流有 访问的所有 成员的外流,即使是那些被标记为"私人"
2.静态的嵌套类:
例如:
class EnclosingClass {
static class Nested {
void someMethod() { System.out.println("hello SO"); }
}
}
案例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"
}
}
案例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"
}
}
专静类:
- 静态内流将仅访问静态的成员的外流,并且没有访问非静态的成员。
结论:
问题: 是什么之间的主要差别的一个内部类和一个静态的嵌套类Java?
回答: 只是通过具体细节的每一类上面提到的。
内舱 和 嵌套静类 在Java两类声明的另一个类,称为顶级别分类。在Java的术语,如果声明的一套类的静态的,它将称为嵌套静类Java而非静态的嵌套类被简单地称为内类。
什么是内部类Java?
任何一类,这不是一个顶级或声明内的另一类被称为嵌套类和出这些嵌套的课程,这类声明不是静态被称为内部流。有三种类型的内部类在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");
}
}
}
什么是嵌套静类Java?
嵌套静类是另一类是内部声明的一类为其成员制是静态的。嵌套静类也宣布作为成员的外流,并可能使私人、公共或保护像任何其他部件。其中一个主要益处的嵌套静类在内的类实例的嵌套静类不附加任何封闭的例外类。 你也不需要任何例外类创造的实例嵌套静类Java.
1)它可以访问 静态数据成员 外层级,包括私人。
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");
}
}
}
Ref: 内部类和嵌套静类Java例
我想这里的人们应该注意到海报的是:静态巢类仅仅是第一内类。例如:
public static class A {} //ERROR
public class A {
public class B {
public static class C {} //ERROR
}
}
public class A {
public static class B {} //COMPILE !!!
}
因此,总结,静类不取决于哪一类,其所包含的内容。因此,他们无法在普通类。(因为正常类需要的一个实例)。
当我们声明,静态部件的类内部一级,它被称为顶级套类或一个静态的嵌套类。它可以证明如下:
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());
}
}
当我们宣布非静态部件的类内部一级,它被称为内类。内部类可以证明如下:
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);
}
}
}
以下是一例 static nested class
和 inner class
:
OuterClass.java
public class OuterClass {
private String someVariable = "Non Static";
private static String anotherStaticVariable = "Static";
OuterClass(){
}
//Nested classes are static
static class StaticNestedClass{
private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable";
//can access private variables declared in the outer class
public static void getPrivateVariableofOuterClass(){
System.out.println(anotherStaticVariable);
}
}
//non static
class InnerClass{
//can access private variables of outer class
public String getPrivateNonStaticVariableOfOuterClass(){
return someVariable;
}
}
public static void accessStaticClass(){
//can access any variable declared inside the Static Nested Class
//even if it private
String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable;
System.out.println(var);
}
}
OuterClassTest:
public class OuterClassTest {
public static void main(String[] args) {
//access the Static Nested Class
OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();
//test the private variable declared inside the static nested class
OuterClass.accessStaticClass();
/*
* Inner Class Test
* */
//Declaration
//first instantiate the outer class
OuterClass outerClass = new OuterClass();
//then instantiate the inner class
OuterClass.InnerClass innerClassExample = outerClass. new InnerClass();
//test the non static private variable
System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass());
}
}
我认为,没有上述的答复得到实际例子,你之间的差异一套类和一个静态的嵌套类术语的应用程序设计。和之间的主要差别是静态的嵌套类和内类访问的能力外流的实例领域。
让我们看一看以下两个例子。
静态巢类:一个很好的例子使用的是静态的嵌套课程是建设者模式(https://dzone.com/articles/design-patterns-the-builder-pattern).
为BankAccount我们使用一个静态的嵌套类,主要是因为
静态巢类的实例可以建立之前,外类。
在构建模式,生成器是一种辅助类其用于创造BankAccount.
- BankAccount.建设者是仅与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;
}
}
}
内类:共同使用的内部类是定义的一个事件处理程序。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
}
}
}
首先,没有这种类的所谓静类。静剂使用与内部类(称为嵌套类)说,这是一个静态部件的外流,这意味着我们可以访问它作为与其他的静态成员和不具有任何例外类。(这是有益的静态的原本。)
之间的差异使用嵌套类和定期的内部类是:
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
第一,我们可以化Outerclass然后我们可以访问内。
但是,如果类然后嵌套法是:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
使用静态的语法正常执行的静态的关键词。
Java编程语言中的定义一类内的另一类。这样一类被称为一套类,并说明在这里:
class OuterClass {
...
class NestedClass {
...
}
}
嵌套的课程都分为两类:静止和非静态的。嵌套类声明的静态被称为静态的嵌套的课程。非静态的嵌套的课程被称为内部课程。一件事,即我们应该记住的是非静态的嵌套课程(内部类)访问其他成员的封闭类,即使他们宣称为私有。静态的嵌套的课程只能访问其他成员的封闭类,如果这些都是静态的。它不能访问非静态的成员外流的。为有类方法和变量,一个静态的嵌套类是与其外类。例如,创造一个目的的静态嵌套类,使用这种语法:
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
实例的内流,必须首先实例外类。然后,创建内目内外的对象用这种语法:
OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
为什么我们使用嵌套类
- 它是一种在逻辑上分组的课程,这些课程只用于一个地方。
- 它增加了封装。
- 它可以导致更易读和易于维护的代码。
资料来源: The Java教程的嵌套类
不同的是,一套类声明,也是静态的可实例之外的封闭类。
当你有一个嵌套级宣言》, 不 静态的,也被称为 内舱, Java不会让你的实例,它除了通过封闭类。对象创造出来的内类联系对象创造了从外部类,所以内流可以参考该领域外。
但如果它是静态的,随后的链路并不存在,外的领域无法进行访问(除了通过一个普通的参考像任何其他目的),因此,您可以创建嵌套类本身。
我说明了各种可能的正确和错误的情况,它可以发生在java代码。
class Outter1 {
String OutStr;
Outter1(String str) {
OutStr = str;
}
public void NonStaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// below static attribute not permitted
// static String tempStatic1 = "static";
// below static with final attribute not permitted
// static final String tempStatic1 = "ashish";
// synchronized keyword is not permitted below
class localInnerNonStatic1 {
synchronized public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
public static void StaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// static attribute not permitted below
//static String tempStatic1 = "static";
// static with final attribute not permitted below
// static final String tempStatic1 = "ashish";
class localInnerNonStatic1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
// synchronized keyword is not permitted
static class inner1 {
static String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
public static void innerStaticMethod(String str11) {
// error in below step
str11 = temp1 +" india";
//str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
//}
}
//synchronized keyword is not permitted below
class innerNonStatic1 {
//This is important we have to keep final with static modifier in non
// static innerclass below
static final String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
synchronized public void innerMethod(String str11) {
tempNonStatic = tempNonStatic +" ...";
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// error in below step
public static void innerStaticMethod(String str11) {
// error in below step
// str11 = tempNonStatic +" india";
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
//}
}
}