代码块
静态代码块 static{}
类加载时自动执行,类只会加载一次,静态代码块只会执行一次,往往用来对类的静态资源的初始化。
实例代码块 {}
,每次创建对象时执行,用来完成对象的初始化的。
内部类
一个类定义在另一个类内部,叫做内部类。
使用场景:当一个类的内部,包含了一个完整的事物,且这个事物没有必要单独设计时,就可以设计成内部类。
成员内部类
外部类的对象持有的,没有static修饰。
内部类创建对象是有要求的。
Outer.Inner oi = new Outer().new Inner();
oi.show();
成员内部类可以直接访问外部类的静态成员,也可以直接访问外部类的实例成员。
成员内部类的实例方法中,可以直接拿到当前外部类的对象:外部类名.this
。
静态内部类
外部类自己持有的 ,有static修饰。
Outer.Inner oi = new Outer.Inner();
oi.show();
静态内部类可以访问外部类的静态成员,但不可以直接访问外部类的实例成员。
局部内部类
定义在方法、代码块、构造器等执行体中的类。
匿名内部类(重点)
一种特殊的局部内部类。
匿名:程序员不需要为这个类声明名字,默认有个隐藏的名字(外部类名$编号.class
)。
new 类或接口(){
类体(一般是方法重写);
}
=========================
public abstract class Animal {
public abstract void cry();
}
Animal a = new Animal(){
@Override
public void cry(){
"miaomiaomiao".sout;
}
};
a.cry();
匿名内部类的本质与作用
- 本质:匿名内部类本质是一个子类(如是Animal的子类),同时会立即创建出一个子类对象。
- 作用:更方便创建一个子类对象。
匿名内部类的常见使用形式
通常作为一个对象参数传输给方法。调用别人提供的方法实现需求时,正好可以让我们传输一个匿名内部类对象给其使用。
public interface Swim{
void swimming();
}
public class Test{
psvm{
start(new Swim(){
@Override
public void swimming(){
"学生游泳很快".sout;
}
});
}
public static void start(Swim s){
"开始".sout;
s.swimming();
"结束".sout;
}
}
函数式编程(重点)
函数式编程需要结合匿名内部类学习。
Lambda表达式
- 函数:类似数学中的函数,强调做什么。只要输入的数据一致返回的结果也一致。
- Java中的函数就是 Lambda表达式。(Java中方法是方法,函数是函数)
- Lambda表达式能解决什么问题:使用Lambda函数替代函数式接口的匿名内部类对象,从而让程序更简洁,可读性好。
- 函数式接口:有且仅有一个抽象方法的接口。用注解
@FunctionalInterface
约束。 - Lambda表达式通过上下文推断对匿名内部类进行替代。
Lambda表达式的写法
(被重写方法的形参列表) -> {
被重写方法的方法体列表
}
==============================================
swimStart(new Swim() {
@Override
public double swimming(int a, double b) {
return a+b;
}
});
// 简化为:
swimStart((int a, double b)->{
return a+b;
});
进一步简化-Lambda表达式的省略策略
可以进一步简化Lambda表达式:
- 参数类型全部可以省略不写。
- 如果只有一个参数,参数类型省略的同时()也可以省略。(多个参数不能省略小括号)。
- 如果Lambda表达式中只有一行代码,大括号可以不写,同时省略分号;如果是return语句,return必须省略。
swimStart((a, b) -> a+b); // 应用1和3
再进一步简化-方法引用
进一步简化Lambda函数。
- 静态方法引用
类名::静态方法
使用场景:如果某个Lambda表达式里只是调用一个静态方法,并且→前后参数形式一致,就可以使用静态方法引用。
- 实例方法引用
对象名::实例方法
使用场景:如果某个Lambda表达式里只是通过对象名称调用一个实例方法,并且→前后参数形式一致,就可以使用实例方法引用。
- 特定类型的方法引用
特定类的名称::方法
特定类的实例方法
使用场景如果某个Lambda表达式里只是调用一个特定类型的实例方法,并且前面参数列表中的第一个参数是作为方法的主调,后面的所有参数都是作为该实例方法的入参的,则此时就可以使用特定类型的方法引用。
- 构造器引用
类名::new
如果某个Lambda表达式里只是在创建对象,并且→前后参数情况一致,就可以使用构造器引用。
常用API
String
- 只要是以
""
方式写出的字符串对象, 会存储到字符串常量池(也在堆内存中),且相同内容的字符串只存储一份; - 通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。
- 字符串的内容比较千万不要用
==
。
ArrayList
集合是一种容器,用来装数据,类似于数组。
数组定义完成,长度就固定了。集合是可变的。