【转】Java 内部类总结
Java内部类
一、 含义
在Java编程语言里,程序是由类(class)构建而成的。在一个类的内部也可以声明类,我们把这样的类叫做内部类。
二、 作用
- 实现了更好的封装,我们知道,普通类(非内部类)的访问修饰符不能为private或protected,而内部类可以。当我们将内部类声明为private时,只有外部类可以访问内部类,很好地隐藏了内部类。
- 内部类可以继承(extends)或实现(implements)其他的类或接口,而不受外部类的影响。
- 内部类可以直接访问外部类的字段和方法,即使是用private修饰的,相反的,外部类不能直接访问内部类的成员。
三、 原理
内部类是一个编译时的概念,编译后会生成两个独立的class文件,如下:

public class Outer{
private String outerName = "outer";
class Inner{
private String innerName = "inner";
}
}

编译后的文件如下图:

编译后Outer.Inner被重命名为Outer$Inner,句点(.)被替换成了美元符号($)。
四、 分类
Java内部类可分为成员内部类、局部内部类、匿名内部类、静态内部类。
1) 成员内部类
成员内部类可以看成是外部类的一个成员,在成员内部类中无法声明静态成员,但static final字段是个例外。我们知道加载类时,会先初始化静态成员,如果成员内部类有静态成员,那么内部类就会在外部类之前生成,而内部类是为外部类服务的,内部类在外部类之前就生成可能会脱离掌控。在实例化成员内部类时,成员内部类会持有一个外部类当前对象的引用,这样在成员内部类中就可以直接访问外部类的成员,即使是private修饰的。

import static java.lang.System.out;
public class Outer{
private String outerName = "outer";
//外部类无法直接访问内部类的成员,需要实例化内部类对象
private Inner inner = new Inner();
public class Inner{
private String innerName = "inner";
public void show(){
out.println(outerName); //可以直接访问外部类的成员
}
}
public void show(){
out.println(inner.innerName);
inner.show();
}
public static void main(String[] args){
Outer outer = new Outer();
outer.show();
//实例化内部类
Outer.Inner inner = outer.new Inner();
inner.show();
}
}

运行结果:
inner
outer
outer
成员内部类对外部类对象的引用,是通过在this前面加上外部类的名字构成的,这种形式叫作限定-this,out.println(outerName)与out.println(Outer.this.outerName)是等价的。
2) 局部内部类
局部内部类的使用和成员内部类的使用基本一致,只是局部内部类定义在外部类的方法中,就像局部变量一样,并不是外部类的成员。局部内部类在方法外是无法访问到的,但它的实例可以从方法中返回,并且实例在不再被引用之前会一直存在。局部内部类也可以访问所在方法的局部变量、方法参数等,限制是局部变量或方法参数只有在声明为final时才能被访问。

import static java.lang.System.out;
public class Outer{
private String outerName = "outer";
public void show(final String str){ //方法参数为final类型
class Inner{
public void print(){
out.println(outerName+str);
}
}
Inner inner = new Inner();
inner.print();
}
public static void main(String[] args){
Outer outer = new Outer();
outer.show(":lalala");
}
}

运行结果:
outer:lalala
3) 匿名内部类
可以把匿名内部类想象成是没有类名的局部内部类,匿名内部类有以下特点:
1、匿名内部类不能有构造器,匿名内部类没有类名,肯定无法声明构造器。
2、匿名内部类必须继承或实现一个接口,指定给new的类型为匿名类的超类型,匿名类不 能有显示的extends或implements子句,也不能有任何修饰符。
3、匿名内部类和成员内部类、局部内部类一样,也不能声明静态成员。

import static java.lang.System.out;
public class Outer{
private String outerName = "outer";
public void show(final String str){
new Inner(){ //实现了Inner接口
public void print(){
out.println(outerName+str);
}
}.print();
}
public static void main(String[] args){
Outer outer = new Outer();
outer.show(":lalala");
}
}
interface Inner{
void print();
}

运行结果:
outer:lalala
4) 静态内部类
静态内部类,有的书上也称为嵌套类,声明它时需要用static修饰符,静态内部类不同于前三种内部类,静态内部类不会持有外部类当前对象的引用,所以在静态内部类中无法访问外部类的非静态成员,可以这么说,静态内部类不依赖于外部类。

import static java.lang.System.out;
public class Outer{
private String outerName = "outer";
private static int id = 123;
private Inner inner = new Inner();
public static class Inner{
public void print1(){
//out.println(outerName); 无法访问外部类的非静态成员
out.println(id);
}
public static void print2(){
out.println(id);
}
}
public void show(){
inner.print1();
}
public static void main(String[] args){
Outer outer = new Outer();
outer.show();
Outer.Inner.print2(); //直接通过类名访问静态内部类
}
}

转载:https://www.cnblogs.com/brave7/p/8486034.html。
【转】Java 内部类总结的更多相关文章
- Java内部类final语义实现
本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...
- Java内部类详解
Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...
- 黑马----JAVA内部类
黑马程序员:Java培训.Android培训.iOS培训..Net培训 黑马程序员--JAVA内部类 一.内部类分为显式内部类和匿名内部类. 二.显式内部类 1.即显式声明的内部类,它有类名. 2.显 ...
- java 内部类 *** 最爱那水货
注: 转载于http://blog.csdn.net/jiangxinyu/article/details/8177326 Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类.内部类又 ...
- java内部类和匿名内部类
内部类即是包含在类里面的又一个类. java内部类分为: 成员内部类.静态嵌套类.方法内部类.匿名内部类 . 内部类的共性 (1).内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.clas ...
- Java内部类小程序(成员内部类,静态内部类,匿名内部类)
/** * 测试java内部类(成员内部类,静态内部类,匿名内部类) * 局部内部类不常用,就不写了. * @package :java05 * @author shaobn * @Describe ...
- [转] Java内部类详解
作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...
- java内部类的作用分析
提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比.内部类从表面上看,就 ...
- 9)Java内部类(Inner Class)
内部类:不可以有静态数据,静态方法或者又一个静态内部类 内部类的优点:隐藏类的细节,内部类可以声明为私有.内部类可以访问外部类的对象(包括private) 静态内部类:可以有静态数据,静 ...
- JAVA内部类(转)
源出处:JAVA内部类 在java语言中,有一种类叫做内部类(inner class),也称为嵌入类(nested class),它是定义在其他类的内部.内部类作为其外部类的一个成员,与其他成员一样, ...
随机推荐
- Shell基本运算符之算术、关系运算符
Shell 运算符 =============================摘自菜鸟教程================================= Shell和其他编程语言一样,支持多种运算 ...
- python 使用队列实现线程同步
#通过queue的方式进行线程间同步,Queue在底层通过实现了dqueue(双生队列,在字节码时实现了线程安全)实现了线程安全 from queue import Queue import time ...
- WebApplicationInitializer启动分析
从Servlet 3.0 开始Tomcat已经支持注解式的配置.了解下,在注解的配置方式下,Web是怎样启动起来的. 通过注解配置一个Web应用 下面是一个通过注解实现一个简单的Web应用 publi ...
- OWIN,Katana,identity整体概述
在用asp.net identity的时候,发现很多概念不是很懂,特地去查资料了解了一些相关信息,现在做下笔记. 1.OWIN,OWIN是Open Web Server Interface for . ...
- Javaweb常用解决问题连接
1.javaweb的idea如何创建及配置web项目 https://www.jianshu.com/p/8d49d36a3c7e 2.servlet的建立以及部署 https://blog.csdn ...
- Laravel向表里插入字段
执行: php artisan make:migration add_字段_to_表名_table --table=表名 此时在database/migrations文件夹下会生成一个相应文件,更改如 ...
- js删除html标记 去掉所有html标记
js删除html标记 去掉所有html标记 function delHtml(str){ return str.replace(/<[^>]+>/g,""); / ...
- Java实现贪吃蛇游戏(含账号注册登录,排行榜功能)
这是我第一次工程实践的作业,选题很多,但我只对其中的游戏开发感兴趣,可游戏就两三个类型,最终还是选择了贪吃蛇.其实就贪吃蛇本身的代码实现还算是比较简单的,可是实践要求代码行达到一定数量,所以我就额外给 ...
- angular6 表单验证
这里使用的是模型驱动的表单 1.app.module.ts import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ ... ...
- [Linux]F5负载均衡器
F5负载均衡器是硬件的负载均衡设备 F5配置最简单负载均衡,需要配置的参数有Node(节点).Pool(资源池).和Virtual Server(虚拟服务器),它们的关系是,先配置Node,然后配置V ...