Java中的枚举、注解、接口定义加强、Lambda表达式、方法引用

1.枚举

假设我们定义一个颜色类:

//三原色 典型的多例模式
class Color{
    private String title;
    private Color(String title){
        this.title = title;
    }
    public static final int RED_FLAG = 1;
    public static final int GREEN_FLAG = 5;
    public static final int BLUE_FLAG = 10;

    private static final Color RED = new Color("红");
    private static final Color GREEN = new Color("绿");
    private static final Color BLUE = new Color("蓝");
    public static  Color getInstance(int flag){
        switch (flag){
            case RED_FLAG:return RED;
            case GREEN_FLAG:return GREEN;
            case BLUE_FLAG:return BLUE;
            default:return null;
        }
    }

    @Override
    public String toString() {
        return this.title;
    }
}
public class Test{
    public static void main(String[] args) {
        Color color = Color.getInstance(Color.RED_FLAG);
        System.out.println(color);
    }
}

使用多例模式这种方法,扩展会非常的麻烦,JDK1.5之后产生了枚举类,使用枚举类修改以上代码:

enum Color{
    RED,BLUE,GREEN
}
public class Test{
    public static void main(String[] args) {
        Color color = Color.RED;
        System.out.println(color);
    }
}

1.1 语法

enum 类名{ 
    //属性通常大写
    属性1,属性2,属性3
}
  1. 使用enum关键字定义的枚举结构实际上是默认继承了Enum枚举类(java.long.Enum)
  2. Enum中存在两大属性
    name:枚举对象名称
    ordinal:枚举对象的数字下标
//枚举类.name() 取得枚举对象名称
public final String name() {return name; }
//取得枚举对象下标
public final int ordinal() {return ordinal;}
//枚举类.value()取得所有枚举类的对象
enum Color{
    RED,BLUE,GREEN
}
public class Test{
    public static void main(String[] args) {
        for(Color color : Color.values()){
            System.out.println(color);
        }
    }
}

在这里插入图片描述

1.2 enum和Enum的区别

enum是一个关键字,使用enum定义的枚举类本质上就相当于一个类继承了Enum这个抽象类而已。

1.3 枚举中定义其他结构

枚举类和普通类有很多相似的地方、可以定义成员、静态属性、方法

  1. 枚举中若定义构造方法,构造方法必须使用private封装(枚举类是多例类,枚举类外部不可以产生对象)
  2. 枚举类中若定义其他结构,枚举对象声明必须放在枚举类的首行
  3. 枚举可以实现接口
interface IColor{
    String color();
}
enum Color implements IColor{
    RED("红"),BLUE("蓝"),GREEN("绿");
    private String title;

    Color(String title) {
        this.title = title;
    }

    @Override
    public String color() {
        return this.name();
    }
}
public class Test{
    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.4 枚举类的应用与总结

/**
 4. 枚举类
 5. 1.枚举类型不能被用户实例化(用户不能new)
 6. 2.定义枚举对象(通常名字是大写)
 7. 3.使用枚举对象通过  枚举类.属性
 8. 4.枚举类是典型的多例设计、每个枚举对象有且只有一个
 9. 5.列举所有枚举对象 枚举类.values()
 10. 6.枚举对象名称 枚举对象.name()
 11. 7.通过枚举类的valueOf方法获取枚举对象(枚举常量),name必须要存在否则会有非法参数异常
 12. 8.枚举类和普通类有很多相似的地方、可以定义成员-静态属性-方法
 13. 9.枚举对象有一个方法ordinal可以表示一个下标,从0开始依次加1 在开发中避免使用,它的值基于枚举对象定义的顺序
 14. 10.枚举类继承自java.lang.Enum,不能继承其他类
 15. 11.枚举类的构造方法是私有的,外部不可以new
 16. 12.枚举类可以实现接口
 */
enum Color{
    RED("#dd0000"),GREEN("#00dd00"),BLUE("#0000dd");
    private String rgb;
    Color(String rgb) {
        this.rgb = rgb;
    }
    //为什么不提供set方法 枚举对象全局唯一 有且只有一个
    //要是有set方法,意味着我们可以改枚举对象,那么所有使用到它的地方都被改了
    public String getRgb() {
        return rgb;
    }

    public void print(){
        System.out.println(this+" 颜色的rgb为:"+this.rgb);
    }
}
public class Test {
    public static void main(String[] args) {
        Color color = Color.RED;
        Color color1 = Color.RED;
        System.out.println(color == color1);
        //列举所有枚举对象
        Color[] colors = Color.values();
        for(Color c:colors){
            //枚举对象名称
            System.out.println(c.name());
        }
        //通过枚举类的valueOf方法获取枚举对象(枚举常量),name必须要存在否则会有非法参数异常
        System.out.println(Color.valueOf("RED"));
        Color.RED.print();
        //ordinal:枚举对象的数字下标
        System.out.println(Color.RED.ordinal());
        System.out.println(Color.GREEN.ordinal());
        System.out.println(Color.BLUE.ordinal());
        System.out.println(Color.class.getSuperclass());
    }
}

在这里插入图片描述

2.注解

2.1 @Override 准确覆写

当子类覆写父类方法时,此注解检查覆写的方法是否正确声明,只有满足覆写方法要求才会编译通过,否则编译出错

2.2 @Deprecated 过期声明

建议用户不使用原有类或者方法时,可以在类或者方法上加@Deprecated表示在当前版本中不推荐使用
在这里插入图片描述

2.3 @SuppressWarnings 压制警告

调用某些操作可能产生问题的时候会出现警告信息,但是警告信息并不是异常

3. JDK1.8新特性

3.1 接口定义加强

JDK1.8之前,接口中只允许有抽象方法和常量,如果此时某一个接口想增加一个方法,就必须去父接口增加这个方法,但是父接口增加了这个方法,其他的子接口和子类又必须全部覆写这个方法,有些工具接口有成百上千个子接口,为了一个接口中有某一个方法,其他的接口和该都必须跟着改变,十分麻烦。
JDK1.8之后接口中允许出现以下两类构造方法

  1. 用default定义的普通方法,需要通过接口对象来调用
  2. 用static定义的静态方法,直接使用接口名调用
interface IInterface{
    void test();
    //用default定义的普通方法,需要通过接口对象来调用
    //default不可以省略
    default void fun(){
        System.out.println("JDK1.8新增的普通方法,通过接口对象调用");
    }
    //用static定义的静态方法,直接使用接口名调用
    static void method(){
        System.out.println("JDK1.8新增的静态方法,通过接口名称调用");
    }
}
class InterfaceImpl implements IInterface{
    @Override
    public void test() {
        System.out.println("子类覆写抽象方法");
    }
}
public class Test {
    public static void main(String[] args) {
        IInterface iInterface =
                new InterfaceImpl();
        iInterface.fun();
        iInterface.test();
        IInterface.method();
    }
}

在这里插入图片描述

3.2 Lambda表达式

interface Add{
    void add(int x,int y);
}
class AddImpl implements Add{
    @Override
    public void add(int x, int y) {
        System.out.println(x+y);
    }
}
public class Test {
    public static void main(String[] args) {
        Add add = new AddImpl();
        add.add(10,20);
    }
}

此程序用于计算两个数的加法,如果此时想要计算两个数的和再加10,为了不影响其他数据求和,就必须重新写一个专门的类来计算x+y+10,当然也可以使用匿名内部类来实现

interface Add{
    void add(int x,int y);
}
public class Test {
    public static void main(String[] args) {
        Add add = new Add() {
            @Override
            public void add(int x, int y) {
                System.out.println(x+y);
            }
        };
        add.add(10,20);
    }
}

在JDK1.8之后有了一种新的方法:函数式编程

interface Add{
    void add(int x,int y);
}

public class Test {
    public static void main(String[] args) {
        //(x,y)--掉膘参数  System.out.println(x+y)函数实现
       Add add = (x,y)-> System.out.println(x+y);
       Add add1 = (x,y)-> System.out.println(x+10+y);
       add.add(10,20);
       add1.add(10,20);
    }
}

在这里插入图片描述
要想使用函数式编程有一个前提,接口必须只有一个抽象方法,如果存在两个以上的抽象方法就无法使用函数式编程,如果某个接口就是为函数编程而生的,在定义时只能存在一个抽象方法,因此有一个新的注解**@FunctionalInterface**,此注解会检查该接口是否只存在一个抽象方法,存在两个抽象方法以上编译出错。

3.2.1 语法

当方法体中只有一行代码时:(方法参数)->具体的方法体实现
当方法有返回值时,单行代码的lambda表达式可以省略return语句

@FunctionalInterface
interface Add{
    void add(int x,int y);
}
@FunctionalInterface
interface AddTest{
    int add(int x,int y);
}
public class Test {
    public static void main(String[] args) {
        //(x,y)--参数  System.out.println(x+y)函数实现
       Add add = (x,y)-> System.out.println(x+y);
       add.add(10,20);

       AddTest add1 = (x,y)-> x+y+10;
        System.out.println(add1.add(10,20));
    }
}

在这里插入图片描述
当方法体中有多行代码时:

(方法参数) ->{
.......
.......
[return 语句];
};
@FunctionalInterface
interface Add{
    int add(int x,int y);
}
public class Test {
    public static void main(String[] args) {
        Add add = (p1,p2) ->{
            int result = p1+p2;
            result+=20;
            return result;
        };
        System.out.println(add.add(20,20));
    }
}

在这里插入图片描述

4.方法引用

方法引用只是给现有方法起别名
方法引用一共有四大形式:

4.1 引用类中的静态方法

类名称::静态方法名称
interface IUnit<P,R>{
    R switchPara(P p);
}
public class Test {
    public static void main(String[] args) {
        //相当于给String类的valueOf方法起了一个别名switchPara
        IUnit<Integer,String> util
                = String::valueOf;
        //相当于调用String.valueOf()   将Integer类型的值变成String类
        String str = util.switchPara(123);
        System.out.println(str);
    }
}

在这里插入图片描述

4.2 引用类中的普通方法

类名称::普通方法名
//调用类中普通方法
interface IUnit<R,P>{
    R compare(P p1,P p2);
}
public class Test {
    public static void main(String[] args) {
        IUnit<Integer,String> util
                = String::compareTo;
        //相当于调用String.comparTo
        System.out.println(util.compare("a","v"));
    }
}

在这里插入图片描述

4.3 引用类中的构造方法

类名称::new
class Person{
    private String name;
    private int age;

    public Person(String name, int 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 Test {
    public static void main(String[] args) {
        IUtil<Person,String,Integer> util =
                Person::new;
        System.out.println(util.createPer("张三",12));
    }
}

在这里插入图片描述

4.4 引用某个对象的方法

实例化对象::普通方法
// 引用某个对象的方法
interface IUnit<R>{
    R switchPara();
}
public class Test {
    public static void main(String[] args) {
        IUnit<String> util
                = "hello"::toUpperCase;
        //相当于调用"hello".toUpperCase(10)
        System.out.println(util.switchPara());
    }
}

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值