Java中内部类和静态内部类的区别
2020-03-26 16:18:48来源:博客园 阅读 ()
Java中内部类和静态内部类的区别
内部类和静态内部类
示例
public class OuterClass {
private int numPrivate = 1;
public int numPublic = 2;
public static int numPublicStatic = 3;
private static int numPrivateStatic = 4;
public void nonStaticPublicMethod(){
System.out.println("using nonStaticPublicMethod");
}
private void nonStaticPrivateMethod(){
System.out.println("using nonStaticPrivateMethod");
}
public static void staticPublicMethod(){
System.out.println("using staticPublicMethod");
}
private static void staticPrivateMethod(){
System.out.println("using staticPrivateMethod");
}
class InnerClass{
//Inner class cannot have static declarations
//static int numInnerClass = 4;
//public static void test(){}
int numNonStaticInnerClass = 5;
public void print(){
System.out.println("using InnerClass");
System.out.println("access private field: "+numPrivate);
System.out.println("access public field: "+numPublic);
System.out.println("access public static field: "+numPublicStatic);
System.out.println("access private static field: "+numPrivateStatic);
System.out.println("access numNonStaticInnerClass: "+numNonStaticInnerClass);
nonStaticPrivateMethod();
nonStaticPublicMethod();
staticPrivateMethod();
staticPublicMethod();
}
}
static class StaticNestedClass{
static int numStaticNestedClass = 6;
int numNonStaticNestedClass = 7;
public void print(){
System.out.println("using StaticNestedClass");
System.out.println("access public static field: "+numPublicStatic);
System.out.println("access private static field: "+numPrivateStatic);
System.out.println("access numStaticNestedClass: "+numStaticNestedClass);
System.out.println("access numNonStaticNestedClass: "+numNonStaticNestedClass);
staticPrivateMethod();
staticPublicMethod();
}
}
public static void main(String[] args) {
//内部类实例对象
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
innerClass.print();
System.out.println("=====================");
//静态内部类实例化对象
OuterClass.StaticNestedClass nestedClass = new OuterClass.StaticNestedClass();
nestedClass.print();
}
}
结果
using InnerClass
access private field: 1
access public field: 2
access public static field: 3
access private static field: 4
access numNonStaticInnerClass: 5
using nonStaticPrivateMethod
using nonStaticPublicMethod
using staticPrivateMethod
using staticPublicMethod
=====================
using StaticNestedClass
access public static field: 3
access private static field: 4
access numStaticNestedClass: 6
access numNonStaticNestedClass: 7
using staticPrivateMethod
using staticPublicMethod
静态内部类使用方法
通过外部类访问静态内部类
OuterClass.StaticNestedClass
创建静态内部类对象
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
内部类的使用方法
必须先实例化外部类,才能实例化内部类
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
两者区别
-
内部类, 即便是私有的也能访问,无论静态还是非静态都能访问
- 可以访问封闭类(外部类)中所有的成员变量和方法
- 封闭类(外部类)中的私有private成员变量和方法也可以访问
- 内部类中不可以有静态的变量和静态的方法
-
静态内部类
- 无权访问封闭类(外部类)的中的非静态变量或者非静态方法
- 封闭类(外部类)中的私有private的静态static成员变量和方法也可以访问
- 静态内部类中可以有静态的变量和静态的方法
-
内部类可以被声明为private, public, protected, or package private. 但是封闭类(外部类)只能被声明为
public
or package private
特殊情况
public class ShadowTest {
public int x = 0;
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
输出结果
x = 23
this.x = 1
ShadowTest.this.x = 0
结论
-
ShadowTest类中定义了三个名字一样的变量x
-
ShadowTest的成员变量x
-
FirstLevel内部类的成员变量x
-
methodInFirstLevel方法中的参数x
-
-
methodInFirstLevel方法中的参数x在内部类FirstLevel的阴影下, 所以在方法methodInFirstLevel中使用x的时候, x指向的是方法的参数x, 此时x的结果为23
-
此时this指向的内部类FirstLevel的作用域, 所以this.x的结果是1
-
ShadowTest.this指向的是ShadowTest的作用域, 此时ShadowTest.this.x的结果是1
为什么使用内部类
- 这是一种对仅在一个地方使用的类进行逻辑分组的方法:如果一个类仅对另一个类有用,那么将其嵌入该类并将两者保持在一起是合乎逻辑的。
- 它增加了封装:考虑两个顶级类A和B,其中B需要访问A的成员,如果将A的成员声明为
private
则B无法访问。通过将类B隐藏在类A中,可以将A的成员声明为私有,而B可以访问它们。另外,B本身可以对外界隐藏。 - 这可能会导致代码更具可读性和可维护性:在外部类中嵌套小类会使代码更靠近使用位置。
序列化
强烈建议不要对内部类(包括 本地和 匿名类)进行序列化。
如果序列化一个内部类,然后使用其他JRE实现对其进行反序列化,则可能会遇到兼容性问题。
Serialization of inner classes, including local and anonymous classes, is strongly discouraged. When the Java compiler compiles certain constructs, such as inner classes, it creates synthetic constructs; these are classes, methods, fields, and other constructs that do not have a corresponding construct in the source code. Synthetic constructs enable Java compilers to implement new Java language features without changes to the JVM. However, synthetic constructs can vary among different Java compiler implementations, which means that .class files can vary among different implementations as well. Consequently, you may have compatibility issues if you serialize an inner class and then deserialize it with a different JRE implementation. See the section Implicit and Synthetic Parameters in the section Obtaining Names of Method Parameters for more information about the synthetic constructs generated when an inner class is compiled.
原文链接:https://www.cnblogs.com/eternityz/p/12577225.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 国外程序员整理的Java资源大全(全部是干货) 2020-06-12
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- 2020年java就业前景 2020-06-11
- 04.Java基础语法 2020-06-11
- Java--反射(框架设计的灵魂)案例 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash