一、代码块:根据代码块出现的位置以及关键字,分为以下四种
1.普通代码块(了解):定义在方法中的代码块。
2.构造块(*****):定义在类中的代码块(不加任何修饰符)
- 在对象产生时,优先于构造方法执行。
- 有几个对象产生,就调用几次构造块。
- 用于在构造方法执行前完成一些属性的初始化。
3.静态代码块:
(1)非主类的静态代码块:
- 在类加载时执行(什么时候用到这个类,就叫类加载)。
- 优先于构造块执行。
- 无论有几个对象,只调用一次。
(2)主类中的静态代码块:
- 优先于主方法执行。
4.同步代码块(多线程同步部分再议)
小结:
- 非主类:静态代码块 > 构造块 > 构造方法
- 主类:静态代码块 > 主方法执行
二、内部类:在类内部进行其他类型结构嵌套操作
1.内部类的优点:
(1)内部类与外部类可以方便的访问彼此的私有域(包括私有方法、私有属性)
(2)内部类是另外一种封装(保护性),对外部其他类隐藏。(心脏包在人身体内部)
(3)内部类可以实现java单继承的局限。
2.内部类的缺点:结构复杂
3.内部类与外部类的关系:
(1)对于非静态内部类,内部类 的创建需要依赖外部类对象,在没有外部类实例之前无法创建非静态内部类。
(2)内部类是一个相对独立的个体,与外部类没有is-a关系。
(3)内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类元素,需要通过内部类的引用间接访问。
4.创建内部类的语法(在外部类外部):
(1)创建非静态内部类
外部类.内部类 内部类引用 = new 外部类().new 外部类();
Outter.Inner in = new Outter().new Inner();
(2)创建静态内部类
外部类.内部类 内部类引用 = new 外部类.内部类();
Outter.Inner in = new Outter.Inner();
5.内部类的分类:
(1)成员内部类(成员方法)
①成员内部类不能存在任何static变量或方法,但是可以访问外部类的静态域。
②成员内部类依附外部类,所以只有先创建了外部类才能创建内部类。
(2)静态内部类(静态方法)
①静态内部类的创建不需要依赖外部类,可以直接创建。
②静态内部类不可以使用任何外部类的非static域(包含属性与方法),但是可以存在自己的成员变量。
(3)方法内部类
①方法内部类不允许使用访问权限修饰符。public、private、protected均不允许。
class Outter{
private int num=5;
public void display(final int temp){//此处final可隐藏,用public修饰方法,则会报错:非法表达式的开始
//方法内部类
public class Inner{
}
}
}
public class Test{
public static void main(String[] args){
new Outter();
}
}
②方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其它的地方均不能访问。
③方法内部类如果想使用方法形参,该形参必须使用final声明(JDK将形参变为隐式final声明)。
class Outter{
private int num = 5;
public void display(final int temp){//此处final可省略
//方法内部类
class Inner{
public void fun(){
System.out.println(num);
temp++; //temp如果进行运算引用,则报错:从内部类引用的本地变量必须是最终变量或实际上的最终变量
System.out.println(temp);
}
}
new Inner().fun();
}
}
public class Test{
public static void main(String[] args){
Outter out = new Outter();
out.display(20);
}
}
④匿名内部类(lamdba表达式前身):是一个没有名字的方法内部类,因此特点与方法内部类完全一样。
除此之外:还有两个自己的特点:
- 匿名内部类必须继承一个抽象类或实现一个接口。
- 匿名内部类没有构造方法,因为它没有类名。
//interface实现接口 interface MyInterface{ void Test(); } class Outter{ private int num = 5; public void display(int temp){ //匿名内部类,匿名的实现了MyInterface接口 new MyInterface(){ @override public void test(){ System.out.println("匿名实现MyInterface接口"); System.out.println(temp); } }.test(); } } public class Test2{ public static void main(String[] args){ Outter out = new Outter(); out.display(20); } }
public class Test3{ public static void main(String[] args){ //新启了一个线程 //new Thread(()->System.out.println("hello bit")).start();与以下语句是一样的性质。 new Thread(new Runnable(){ @override public void run(){ System.out.println("hello bat"); } }).start(); } }
总结:如果类名称上出现了".",应当立即想到内部类的概念。