内部类
定义在类当中的一个雷
为什么要使用内部类
1.增强封装,把内部类隐藏在外部类当中,不允许其它类访问这个内部类
2.增加了代码的可维护性
3.内部类可以直接访问外部类当中的成员
外部类的修饰符只能有俩个public或者说默认修饰符,内部类可以使用多个修饰符
内部类可以分为四种
实例内部类
直接定义在类当中的一个类
一个文件中有俩个外部类的时候,生成时,会生成俩份.class文件,当有内部类也会多生成一个class文件
package com.company;
import java.lang.Object;
public class Main extends Object {
public static void main(String[] args) {
Lei lei = new Lei();
//创建实例内部类的方式
Lei.SonLei sonLei = lei.new SonLei();
sonLei.test();
}
}
class Lei{
String name="1";
class SonLei{
String name2="1";
void test(){
//用外部类名.this的方式来调用外部类的属性
System.out.println(Lei.this.name);
//访问自身直接用this
System.out.println(this.name2);
}
}
}
以上例子会生成三个.class文件分别是Main.class,Lei.class,Lei$Son.class
内部类编译成字节码的时候,会有一个外部类的引用,final Lei this$0
this$0特指该内部类所在的外部类的引用,不需要手动定义,编译时自动加上
在内部实例类当中不能有静态成员!!!
外部类不能直接访问内部类当中的成员
静态内部类
在内部类前面加上一个static
静态内部类是不需要创建外部对象
静态内部类中,是没有外部类对象的引用的(static修饰的字段是属于)
静态类当中也可以定义非静态的成员
package com.company;
import java.lang.Object;
public class Main extends Object {
public static void main(String[] args) {
Lei.SonLei sonLei = new Lei.SonLei();//创建静态内部类的方式
sonLei.test();
System.out.println(Lei.SonLei.a);//直接访问静态类当中的静态字段
}
}
class Lei{
static String name="1";
int age=10;
static class SonLei{
int b=30;//静态类当中也可以定义非静态的成员
static String a="2";
void test(){
//非要访问内部类可以这样
System.out.println(new Lei().age);
System.out.println(name);//直接访问外部类的静态成员
}
}
}
局部内部类
定义在方法的内部类
不能使用一些修饰,private,public
局部内部类只能在定义的方法中使用
局部内部类当中不能包含静态变量(因为类是属于方法的,不能属于类)
局部内部类当中可以包含局部变量,生成字节码的时候,回生成一个final类型的引用(1.8之后的特性),
ps:栈中的数据会出栈入栈,而堆中的数据如果引用的是栈中的数据,而堆中的数据没有及时的进行销毁的话,会造成空指针异常.所以局部内部类引用的其实是方法区中用final修饰的字段
匿名内部类
数据局部内部的类的一种特殊情况
匿名内部类是没有构造器的
在安卓中使用的比较多,web开发中使用较少
new 父类构造器 或 接口 (){}
匿名内部类必须得要用父类或者实现了接口才可以
枚举
java 枚举 : 是一个特殊的类,多个常量对象的集合
枚举的本质也是一个类
[修饰符] enum 枚举的名称{
常量1,常量2
}
enum WeeDay{
MoNDAY,TUESDAY,WENESDAY,FRIDAY,SATURDAT,SUNDAY
}
编译成字节码之后的样子:
继承了Enum,私有化了构造器,Enum是一个抽象类,枚举在定switch循环的时候,本质还是循环的int类型
所以枚举不能创建对象
package com.company;
import java.lang.Object;
public class Main extends Object {
public static void main(String[] args) {
WeeDay a=WeeDay.valueOf("TUESDAY");
WeeDay b[]=WeeDay.values();//可以用values获取全部的元素
System.out.println(a);//也可以穿字符串,单字符串的值必须是枚举当中的值
System.out.println(WeeDay.MoNDAY);//MoNDAY
}
}
enum WeeDay{
MoNDAY,TUESDAY,WENESDAY,FRIDAY,SATURDAT,SUNDAY
}