内部类和静态内部类

示例

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.

java 静态内部类 内部类_Java中内部类和静态内部类的区别相关推荐

  1. java字节字符_java中字符和字节的区别

    byte(字节): byte即字节的意思,是java中的基本数据类型,用来申明字节型的变量,一个字节包含8个位,所以,byte类型的取值范围是-128到127. 通常在读取非文本文件时(如图片,声音, ...

  2. java什么内部类_Java的内部类学习

    1.匿名内部类 匿名类是不能有名称的类,所以没办法引用它们.必须在创建时,作为new语句的一部分来声明它们.这就要采用另一种形式的new语句,如下所示: new 这种形式的new语句声明一个新的匿名类 ...

  3. java 毕向东 内部类_java基础内部类(毕向东老师)

    内部类 //特点:内部类可以直接访问外部类的成员, //外部类要访问内部类中的成员必须创建内部类的对象. //为什么要定义内部类呢? 类是用于描述事物的,而事务中如果还有具体的事物,而且这个内部的事物 ...

  4. java show过时_Java中show() 方法被那个方法代替了? java编程 显示类中信

    你说的show是swing里的吧,在老版本中Component这个超类确实有show这个方法,而且这个方法也相当有用,使一个窗口可见,并放到最前面.在jdk5.0中阻止了这个方法,普遍用setVisi ...

  5. java判断类型_Java中类型判断的几种方式 - 码农小胖哥 - 博客园

    1. 前言 在Java这种强类型语言中类型转换.类型判断是经常遇到的.今天就细数一下Java中类型判断的方法方式. 2. instanceof instanceof是Java的一个运算符,用来判断一个 ...

  6. java iter是否存在_Java中ListIterator和Iterator的区别以及ListIterator的应用

    Java中ListIterator和Iterator详解与辨析 在使用java集合的时候,都需要使用Iterator.但是java集合中还有一个迭代器ListIterator,在使用List.Arra ...

  7. java堆和客栈_java中堆和栈的区别分析

    堆和栈是java数据结构里非常重要的概念,本文较为详细的分析了二者之间的区别.供大家参考.具体如下: Java的堆是一个运行时数据区,类的(对象从中分配空间.这些对象通过new.newarray.an ...

  8. java steam 去重_Java中对List去重, Stream去重

    问题 当下互联网技术成熟,越来越多的趋向去中心化.分布式.流计算,使得很多以前在数据库侧做的事情放到了Java端.今天有人问道,如果数据库字段没有索引,那么应该如何根据该字段去重?大家都一致认为用Ja ...

  9. java 序列化实例_Java中的序列化与反序列化实例

    创建的字节流与平台无关.因此,在一个平台上序列化的对象可以在另一个平台上反序列化. 为了使Java对象可序列化,我们实现java.io.Serializable可序列化接口. ObjectOutput ...

最新文章

  1. 第十七届智能汽车竞赛-多车编队组入门讲解
  2. GDI+ 获取本地电脑的图片编码器
  3. 常用数据库语句(更新)
  4. 受用一生的高效 PyCharm 使用技巧(五)
  5. 阿里来了位技术新童鞋,一秒K.O八位律师
  6. jQuery 基础教程 (四)之jQuery中的DOM操作
  7. nacos 读取纯数字字符 出错 @value
  8. xcode3.2.6升级至4.0.2经验加教训总结(转)
  9. 辽宁工业大学有没有计算机专业,辽宁工业大学(专业学位)计算机技术考研难吗...
  10. 别说普通的创业者,就是那些小有名气的创业者
  11. pycharm 调试模式下命令行参数的传递
  12. mysql 存储过程 查询语句怎么写_mysql 查询数据库中的存储过程与函数的语句
  13. “狼牙抓鸡”现身IT江湖
  14. 查看手机db数据库文件
  15. RDCMan安装使用说明
  16. MESYS轴承计算设计软件直播回顾
  17. mysql 迁移 myd_mysql文件*.opt *.frm *.MYI *.MYD的迁移
  18. 缺陷管理工具--mantis使用过程
  19. gentoo linux u盘安装,Gentoo系统安装步骤详解
  20. 猫哥教你写爬虫 039--存储数据

热门文章

  1. 征途服务管理器显示不出启动服务器,征途服务器管理器连接数据库
  2. 汇编 第二章 寄存器
  3. 2 python包、模块相关
  4. 解决上传窗口弹不出的问题
  5. [20141121]无法通过powershell读取sql server性能计数器问题
  6. Icon资源详解[1]
  7. 好记心不如烂笔头之JQuery学习,第四章
  8. jetty java 禁用目录列表_Apache httpd 目录列表禁用配置(options indexes)
  9. Linux之dirname与basename命令
  10. Android-7.0-Nuplayer流程图