目录
代码块
单例模式
Lambda表达式
内部类
常用API
Object
代码块
概述 代码块又称初始化块,属于类中的成员【即是类的一部分】,类似于方法,将逻辑语句封装在方法体中,通过{}包围起来 代码块和方法不同,没有方法名,没有返回,没有参数,只有方法体
不用通过对象或类显示调用,而是加载时,或创建对象时隐式调用
基本语法 [修饰符] {代码}; 1. 修饰符可选,要写的话也只能写static
2. 代码块分为两类,使用static修饰的叫静态代码块,没有static修饰的,叫普通代码块/非静态代码块
3. 逻辑语句可以为任何逻辑语句 (输入、输出、方法调用、循环、判断等)
4. ;号可以写上,也可以省略
好处 1. 相当于另外一种形式的构造器 (对构造器的补充机制),可以做初始化的操作
2. 场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性 注意事项 static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次
如果是普通代码块,每创建一个对象,就执行
类什么时候被加载:
1. 创建对象实例时(new)
2. 创建子类对象实例,父类也会被加载
3. 使用类的静态成员时 (静态属性,静态方法)
普通代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会被调用一次
如果只是使用类的静态成员时,普通代码块并不会执行
创建一个对象时,在一个类调用顺序是:
1. 调用静态代码块和静态属性初始化 (优先级一样,按顺序调用)
2. 调用普通代码块和普通属性的初始化 (优先级一样,按顺序调用)
3. 调用构造方法
构造器的最前面其实隐含了super()和调用普通代码块 创建一个子类对象时 (继承关系)
他们的静态代码块、静态属性初始化,普通代码块、普通属性初始化、构造方法的调用顺序:
1. 父类的静态代码块和静态属性 (优先级一样,按顺序执行)
2. 子类的静态代码块和静态属性 (优先级一样,按顺序执行)
3. 父类的普通代码块和普通属性 (优先级一样,按顺序执行)
4. 父类的构造方法
5. 子类的普通代码块和普通属性 (优先级一样,按顺序执行)
6. 子类的构造方法
静态代码块只能直接调用静态成员 (静态属性和静态方法),普通代码块可以调用任意成员
| 概述 | 代码块又称初始化块,属于类中的成员【即是类的一部分】,类似于方法,将逻辑语句封装在方法体中,通过{}包围起来 |
| 代码块和方法不同,没有方法名,没有返回,没有参数,只有方法体 不用通过对象或类显示调用,而是加载时,或创建对象时隐式调用 | |
| 基本语法 | [修饰符] {代码}; |
| 1. 修饰符可选,要写的话也只能写static 2. 代码块分为两类,使用static修饰的叫静态代码块,没有static修饰的,叫普通代码块/非静态代码块 3. 逻辑语句可以为任何逻辑语句 (输入、输出、方法调用、循环、判断等) 4. ;号可以写上,也可以省略 | |
| 好处 | 1. 相当于另外一种形式的构造器 (对构造器的补充机制),可以做初始化的操作 2. 场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性 |
| 注意事项 | static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次 如果是普通代码块,每创建一个对象,就执行 |
| 类什么时候被加载: 1. 创建对象实例时(new) 2. 创建子类对象实例,父类也会被加载 3. 使用类的静态成员时 (静态属性,静态方法) | |
| 普通代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会被调用一次 如果只是使用类的静态成员时,普通代码块并不会执行 | |
| 创建一个对象时,在一个类调用顺序是: 1. 调用静态代码块和静态属性初始化 (优先级一样,按顺序调用) | |
| 构造器的最前面其实隐含了super()和调用普通代码块 | |
| 创建一个子类对象时 (继承关系) 他们的静态代码块、静态属性初始化,普通代码块、普通属性初始化、构造方法的调用顺序: 1. 父类的静态代码块和静态属性 (优先级一样,按顺序执行) | |
| 静态代码块只能直接调用静态成员 (静态属性和静态方法),普通代码块可以调用任意成员 |
单例模式
概述:采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法 方式一:饿汉式 步骤:
1. 构造器私有化 (防止直接new)
2. 类的内部创建对象 (该对象是static)
3. 提供一个静态的公共方法
代码实现:
GirlFriend类:
private String name;
//为了能够在静态方法中,返回gf对象,修饰为static
private static GirlFriend gf = new GirlFriend("小红红");
private GirlFriend(String name){
this.name = name;
}
public static GirlFriend getInstance(){
return gf;
}
测试类:
//通过方法获取对象
GirlFriend instance = GirlFriend.getInstance();
System.out.println(instance);
类加载就会被执行创建对象!
方式二:懒汉式 概述:步骤与饿汉式基本一样,只是在提供一个静态的公共方法时加了一个判断是否创建对象实例 代码实现:
GirlFriend类:
private String name;
private static GirlFriend gf;
private GirlFriend(String name){
this.name = name;
}
public static GirlFriend getInstance(){
//如果没有创建girlFriend对象
if (gf == null){
gf = new GirlFriend("小红红");
}
return gf;
}
测试类:
GirlFriend instance = GirlFriend.getInstance();
System.out.println(instance);
调用时才创建对象!
饿汉式VS懒汉式 创建对象的时机不同:饿汉式在类加载就创建了对象实例,懒汉式是在使用时才创建 饿汉式不存在线程安全问题,懒汉式存在线程安全问题 饿汉式存在浪费资源的可能,懒汉式不存在 经典单例模式 Java.lang.Runtime (饿汉式)
| 概述:采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法 | |
| 方式一:饿汉式 | 步骤: 1. 构造器私有化 (防止直接new) 2. 类的内部创建对象 (该对象是static) 3. 提供一个静态的公共方法 |
| 代码实现: GirlFriend类: 测试类: 类加载就会被执行创建对象! | |
| 方式二:懒汉式 | 概述:步骤与饿汉式基本一样,只是在提供一个静态的公共方法时加了一个判断是否创建对象实例 |
| 代码实现: GirlFriend类: 测试类: 调用时才创建对象! | |
| 饿汉式VS懒汉式 | 创建对象的时机不同:饿汉式在类加载就创建了对象实例,懒汉式是在使用时才创建 |
| 饿汉式不存在线程安全问题,懒汉式存在线程安全问题 | |
| 饿汉式存在浪费资源的可能,懒汉式不存在 | |
| 经典单例模式 | Java.lang.Runtime (饿汉式) |
Lambda表达式
组成Lambda表达式三要素 形式参数,箭头,代码块 格式 使用前提 有一个接口
接口中有且仅有一个抽象方法 省略模式 1. 类型可以省略。但是有多个参数的情况下,不能只省略一个
2. 如果参数有且仅有一个,那么小括号可以省略
3. 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字 注意事项 使用Lambda必须有接口,并且要求接口中有且仅有一个抽象方法 必须有上下文环境,才能推导出Lambda对应的接口
根据局部变量的赋值得知Lambda对应的接口
Runnable r = ( ) -> System.out.println("Lambda表达式");
根据调用方法的参数得知Lambda对应的接口
new Thread(( ) -> System.out.println("Lambda表达式")).start();
Lambda表达式和匿名内部类的区别 所需类型不同
匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
Lambda表达式:只能是接口
使用限制不同
如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
实现原理不同
匿名内部类:编译之后,产生一个单独的.class字节码文件
Lambda表达式:编译之后,没有一个单独的.class字节码文件
对应的字节码会在运行的时候动态生成
接口组成更新 接口中默认方法
格式:public default 返回值类型 方法名(参数列表) { }
注意:默认方法不是抽象方法,所以不强制被重写。但是可以被重写
重写的时候去掉default关键字;public可以省略,default不能省略
接口中静态方法
格式:public static 返回值类型 方法名(参数列表) { }
注意:静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
public可以省略,static不能省略
接口中私有方法
格式:
private 返回值类型 方法名(参数列表) { }
private static 返回值类型 方法名(参数列表) { }
注意:默认方法可以调用私有的静态方法和非静态方法,静态方法只能调用私有的静态方法
方法引用 产生原因 在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作
那么考虑一种情况:如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案
那是否还有必要再写重复逻辑呢?答案是没有必要。那我们如何使用已经存在的方案的呢?
这就是我们要讲解的方法引用,我们是通过方法引用来使用已经存在的方案
方法引用符 :: 该符号为引用运算符,而它所在的表达式被称为方法引用 使用方法 推导与省略 1. 如果使用Lambda,那么根据 “可推导就是可省略” 的原则
无需指定参数类型,也无需指定的重载形式,它们都将被自动推导
2. 如果使用方法引用,也是同样可以根据上下文进行推导
3. 方法引用是Lambda的孪生兄弟
引用类方法 格式:类名::静态方法 范例:
Integer::parseInt
Integer类的方法:public static int parseInt(String s) 将此String转换为int类型数据
说明:Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数 引用对象的实例方法 概述:引用对象的实例方法,其实就引用类中的成员方法 格式:对象::成员方法 范例:
"HelloWorld"::toUpperCase
String类中的方法:public String toUpperCase() 将此String所有字符转换为大写
说明:Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数 引用类的实例方法 概述:引用类的实例方法,其实就是引用类中的成员方法
格式:类名::成员方法 范例:
String::substring
public String substring(int beginIndex,int endIndex)
从beginIndex开始到endIndex结束,截取字符串
返回一个子串,子串的长度为endIndex-beginIndex
说明:
Lambda表达式被类的实例方法替代的时候
第一个参数作为调用者
后面的参数全部传递给该方法作为参数
引用构造器 概述:引用构造器,其实就是引用构造方法
格式:类名::new
范例:Student::new
说明:Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数
| 组成Lambda表达式三要素 | 形式参数,箭头,代码块 |
| 格式 | |
| 使用前提 | 有一个接口 接口中有且仅有一个抽象方法 |
| 省略模式 | 1. 类型可以省略。但是有多个参数的情况下,不能只省略一个 2. 如果参数有且仅有一个,那么小括号可以省略 3. 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字 |
| 注意事项 | 使用Lambda必须有接口,并且要求接口中有且仅有一个抽象方法 |
| 必须有上下文环境,才能推导出Lambda对应的接口 根据局部变量的赋值得知Lambda对应的接口 根据调用方法的参数得知Lambda对应的接口 | |
| Lambda表达式和匿名内部类的区别 | 所需类型不同 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类 |
| 使用限制不同 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类 | |
| 实现原理不同 匿名内部类:编译之后,产生一个单独的.class字节码文件 对应的字节码会在运行的时候动态生成 | |
| 接口组成更新 | 接口中默认方法 格式:public default 返回值类型 方法名(参数列表) { } 注意:默认方法不是抽象方法,所以不强制被重写。但是可以被重写 重写的时候去掉default关键字;public可以省略,default不能省略 |
| 接口中静态方法 格式:public static 返回值类型 方法名(参数列表) { } 注意:静态方法只能通过接口名调用,不能通过实现类名或者对象名调用 public可以省略,static不能省略 | |
| 接口中私有方法 格式: private 返回值类型 方法名(参数列表) { } private static 返回值类型 方法名(参数列表) { } 注意:默认方法可以调用私有的静态方法和非静态方法,静态方法只能调用私有的静态方法 |
| 方法引用 | 产生原因 | 在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作 那是否还有必要再写重复逻辑呢?答案是没有必要。那我们如何使用已经存在的方案的呢? |
| 方法引用符 | :: 该符号为引用运算符,而它所在的表达式被称为方法引用 | |
| 使用方法 | ||
| 推导与省略 | 1. 如果使用Lambda,那么根据 “可推导就是可省略” 的原则 无需指定参数类型,也无需指定的重载形式,它们都将被自动推导 | |
| 引用类方法 | 格式:类名::静态方法 | |
| 范例: Integer::parseInt | ||
| 说明:Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数 | ||
| 引用对象的实例方法 | 概述:引用对象的实例方法,其实就引用类中的成员方法 | |
| 格式:对象::成员方法 | ||
| 范例: "HelloWorld"::toUpperCase | ||
| 说明:Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数 | ||
| 引用类的实例方法 | 概述:引用类的实例方法,其实就是引用类中的成员方法 | |
| 格式:类名::成员方法 | ||
| 范例: String::substring 返回一个子串,子串的长度为endIndex-beginIndex | ||
| 说明: Lambda表达式被类的实例方法替代的时候 | ||
| 引用构造器 | 概述:引用构造器,其实就是引用构造方法 格式:类名::new 范例:Student::new 说明:Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数 |
内部类
概述:在一个类中定义一个类
举例:在一个类A的内部定义一个类B,类B就被称为内部类
定义格式 访问特点 成员内部类
(在类的成员位置)
创建成员内部类格式 推荐使用方案 将一个类,设计为内部类的目的,大多数都是不想让外界去访问
所以内部类的定义应该私有化,私有化之后
再提供一个可以让外界调用的方法,方法内部创建内部类对象并调用
局部内部类
(在类的局部位置)
匿名内部类 前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类 格式:
本质:是一个继承了该类或者实现了该接口的子类匿名对象 细节:
使用:匿名内部类的本质是一个继承了该类或者实现了该接口的【子类匿名对象】
既然是对象,那就可以作为参数传递。所以,当发现某个方法需要
接口或抽象类的子类对象,我们就可以传递一个匿名内部类过去
| 概述:在一个类中定义一个类 举例:在一个类A的内部定义一个类B,类B就被称为内部类 | ||
| 定义格式 | ||
| 访问特点 | ||
| 成员内部类 (在类的成员位置) | 创建成员内部类格式 | |
| 推荐使用方案 | 将一个类,设计为内部类的目的,大多数都是不想让外界去访问 所以内部类的定义应该私有化,私有化之后 再提供一个可以让外界调用的方法,方法内部创建内部类对象并调用 | |
| 局部内部类 (在类的局部位置) | ||
| 匿名内部类 | 前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类 | |
| 格式: | ||
| 本质:是一个继承了该类或者实现了该接口的子类匿名对象 | ||
| 细节: | ||
| 使用:匿名内部类的本质是一个继承了该类或者实现了该接口的【子类匿名对象】 既然是对象,那就可以作为参数传递。所以,当发现某个方法需要 接口或抽象类的子类对象,我们就可以传递一个匿名内部类过去 | ||
常用API
Math 概述:Math 包含执行基本数字运算的方法 调用方式 Math类中无构造方法
但内部的方法都是静态的
类名.进行调用 常用方法 System 说明:不能被实例化 常用方法
| Math | 概述:Math 包含执行基本数字运算的方法 | |
| 调用方式 | Math类中无构造方法 但内部的方法都是静态的 类名.进行调用 | |
| 常用方法 | ||
| System | 说明:不能被实例化 | |
| 常用方法 | ||
Object
概述:Object 是类层次结构的根,每个类都可以将 Object 作为超类。所有类都直接或者间接的继承自该类 构造方法 public Object() 常用方法 查看方法源码 选中方法,按下Ctrl + B 重写toString方法 1. Alt + Insert 选择toString
2. 在类的空白区域,右键 -> Generate -> 选择toString equals 作用:
用于对象之间的比较,返回true和false的结果
举例:s1.equals(s2); s1和s2是两个对象
重写equals的场景:不希望比较对象的地址值,想要结合对象属性进行比较的时候 重写equals方法:
1. alt + insert 选择equals() and hashCode(),IntelliJ Default,一路next,finish即可
2. 在类的空白区域,右键 -> Generate -> 选择equals() and hashCode(),后面的同上
| 概述:Object 是类层次结构的根,每个类都可以将 Object 作为超类。所有类都直接或者间接的继承自该类 | |
| 构造方法 | public Object() |
| 常用方法 | |
| 查看方法源码 | 选中方法,按下Ctrl + B |
| 重写toString方法 | 1. Alt + Insert 选择toString 2. 在类的空白区域,右键 -> Generate -> 选择toString |
| equals | 作用: 用于对象之间的比较,返回true和false的结果 |
| 重写equals的场景:不希望比较对象的地址值,想要结合对象属性进行比较的时候 | |
| 重写equals方法: 1. alt + insert 选择equals() and hashCode(),IntelliJ Default,一路next,finish即可 | |



