目录:
1.枚举
2.注解
3.Lambda表达式
4.方法引用
1.枚举—引用类型
首先回顾多例设计模式的特点:构造方法私有化,类内部需要提供若干个实例化对象,后面通过static方法返回。
例:
class Color{
private String title;
public static final int RED_FLAG = 1;
public static final int BLUE_FLAG = 5;
public static final int GREEN_FLAG = 10;
private static final Color RED = new Color("RED");
private static final Color BLUE = new Color("BLUE");
private static final Color GREEN = new Color("GREEN");
private Color(String title) {
this.title = title;
}
public static Color getColor(int flag){
switch(flag){
case RED_FLAG:
return RED;
case BLUE_FLAG:
return BLUE;
case GREEN_FLAG:
return GREEN;
default:
return null;
}
}
@Override
public String toString() {
return this.title;
}
}
public class Test2{
public static void main(String[] args) {
System.out.println(Color.getColor(Color.RED_FLAG));
}
}
以上做法是在JDK1.5以前的做法,这样做的目的是限制本类实例化对象的产生个数。但是从JDK1.5开始有了枚举,以上代码可以使用枚举来取代。
语法:
enum Color{
RED,BLUE,GREEN;
}
使用enum关键字定义的枚举结构实际上是默认继承了Enum类的枚举类。
Enum类中存在两大属性:
name:枚举对象名称
ordinal:枚举对象数字下标
public final String name():取得枚举对象名称
public final int ordinal():取得枚举对象下标
例:证明enum是否为Enum的子类,使用Enum的方法即可
enum Color{
RED,BLUE,GREEN;
}
public class Test1{
public static void main(String[] args) {
Color color = Color.RED;
System.out.println(color.ordinal()+"="+color.name());
}
}
例:取得所有枚举类对象:枚举类.values()
enum Color{
RED,BLUE,GREEN;
}
public class Test1{
public static void main(String[] args) {
for(Color color: Color.values()){
System.out.println(color);
}
}
}
enum与Enum的区别:
enum是一个关键字,使用enum定义的枚举类本质上就相当于一个类继承了Enum这个抽象类而已。
1.1枚举类中定义其他结构
枚举中若定义构造方法,构造方法必须用private封装(枚举类是多例类,枚举类外部无法产生对象)
枚举类若定义其他结构,枚举对象声明必须放在枚举类的首行。
enum Color{
RED("红"),BLUE("蓝"),GREEN("绿");
private String title;
private Color(String title){
this.title = title;
}
//不覆写toString会调用父类的toString,父类的toString输出的是名字
@Override
public String toString() {
return this.title;
}
}
public class Test1{
public static void main(String[] args) {
for(Color color: Color.values()){
System.out.println(color);
}
}
}
1.2枚举实现接口
枚举中的对象自动变为接口对象
interface IColor{
String color();
}
enum Color implements IColor{
RED("红"),BLUE("蓝"),GREEN("绿");
private String title;
private Color(String title){
this.title = title;
}
//不覆写toString会调用父类的toString,父类的toString输出的是名字
@Override
public String toString() {
return this.title;
}
@Override
public String color() {
return this.name();
}
}
public class Test1{
public static void main(String[] args) {
for(Color color: Color.values()){
System.out.println(color);
}
IColor color = Color.RED;
System.out.println(color.color());
}
}
1.3枚举应用
枚举的最大特点是只有指定的几个对象可以使用。
例:定义一个表示性别的枚举类,只能有两个对象
enum Sex{
MALE("男"),FEMALE("女");
private String title;
private Sex(String title) {
this.title = title;
}
@Override
public String toString() {
return this.title;
}
}
class Person1{
private String name;
private int age;
private Sex sex;
public Person1(String name, int age, Sex sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
public class Test2{
public static void main(String[] args) {
Person1 per = new Person1("张三",20,Sex.FEMALE);
System.out.println(per);
}
}
2.注解(关键看有没有@)
2.1@Override 准确覆写
当子类覆写父类方法时,此注解检查覆写的方法是否正确声明,只有满足覆写方法要求才会编译通过,否则编译出错。
2.2@Deprecated 过期声明
建议用户不使用原有的类&方法时,可以在类或方法上@Deprecated表示当前版本中不推荐使用。
2.3@SuppressWarings压制警告
调用某些操作可能产生问题的时候会出现警告信息,但是警告信息并不是异常。
3.JDK1.8新特性
3.1接口定义增强
JDK1.8之后接口允许出现以下两类方法:
a.使用default定义的普通方法,需要通过接口对象来调用。
b.使用static定义的静态方法,直接使用接口名调用。
interface IInterface{
void test();
//通过接口对象调用
default void fun(){
System.out.println("JDK1.8新增的普通方法");
}
//直接通过接口名调用
static void method(){
System.out.println("JDK1.8新增的静态方法");
}
}
class InterfaceImpl implements IInterface{
public void test(){
System.out.println("子类覆写抽象方法");
}
}
public class Test1{
public static void main(String[] args) {
IInterface iInterface = new InterfaceImpl();
iInterface.test();
//通过接口对象调用
iInterface.fun();
//一些工具方法,直接通过接口调用
IInterface.method();
}
}
3.2Lambda表达式
要想使用函数式编程有一个前提:接口必须只有一个方法。如果存在两个以上的方法,无法使用函数式编程。
interface Add{
void add(int x, int y);
}
public class Test1{
public static void main(String[] args) {
Add add = (x,y) -> System.out.println(x+y); //Lambda表达式
add.add(10,20);
}
}
如果现在某个接口就是为了函数式编程而生的,在定义时只能存在一个方法,因此有一个新的注解@FunctionalInterface,此注解会检查该接口中是否只存在一个抽象方法,存在两个抽象方法以上编译报错。
语法:
方法体只有一行代码时:(方法参数)->具体的方法体代码实现;
当方法有返回值时,单行代码的Lambda表达式可以省略return语句。
当方法体有多行代码时,
(方法参数)->{
...
...
[return 语句];
}
@FunctionalInterface
interface IMessage{
void print();
}
interface IAdd{
int add(int x, int y);
}
public class Test1{
public static void main(String[] args) {
IMessage msg = () -> System.out.println("hello world");
msg.print();
IAdd add = (x,y) -> x+y;
System.out.println(add.add(10,20));
IAdd add1 = (x,y) -> {
int result = x+y;
result += 20;
return result;
};
System.out.println(add1.add(10,20));
}
}
4.方法引用—前提是与Lambda表达式搭配使用
方法引用就是给现有方法起个别名。
方法引用一共有四种形式:
4.1引用类中静态方法
类名称 :: 静态方法名称
interface IUtil<P,R>{
//将一个p类型转为R类型
R switchPara(P p);
}
public class Test1{
public static void main(String[] args) {
//将String类的valueOf方法转给switchPara
IUtil<Integer,String> util = String :: valueOf;
//相当于调用String.valueOf(10);
String str = util.switchPara(10);
//证明是否转为字符串
System.out.println(str.startsWith("1"));
}
}
4.2引用某个对象的方法(和对象强相关)
实例化对象 :: 普通方法
interface IUtil<R>{
R switchPara();
}
public class Test1{
public static void main(String[] args) {
IUtil<String> util = "hello" :: toUpperCase;
//相当于调用hello.toUpperCase();
System.out.println(util.switchPara());
}
}
4.3调用类中普通方法
类名称 :: 普通方法名
interface IUtil<R,P>{
R compare(P p1, P p2);
}
public class Test1{
public static void main(String[] args) {
IUtil<Integer,String> util = String :: compareTo;
//相当于调用String.compareTo();
System.out.println(util.compare("H","h"));
}
}
4.4引用类中构造方法
类名称 :: new
class Person{
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
interface IUtil<R,PN,PR>{
R createPer(PN p1, PR p2);
}
public class Test1{
public static void main(String[] args) {
IUtil<Person,String,Integer> util = Person :: new;
System.out.println(util.createPer("zhangsan",40));
}
}