java学习_part01_java核心卷_day03_lambda表达式&内部类&异常&泛型

1.lambda 表达式

1.1 语法举例

(String first, String second) -> first.length()-second.length()

(参数类型 参数名) ->{代码语句}.使用lambda表达式,实际就是创建该接口的实例对象

1.2 函数式接口

函数式接口用@FunctionalInterface注解,且接口内只有一个抽象方法

1.3 常见情况

情况 举例
无参数,无返回值 () -> System.out.println();
一个参数,无返回值 (x) -> 操作
如果只有一个参数,小括号也可以省略 x -> 操作
一个以上参数,且操作较复杂 (x,y) ->
一个以上参数,只有一条操作,有返回值,return,{}可以省略 (x,y) -> Integer.compare(x,y)
参数列表的数据类型可以不写,jvm会根据上下文进行推断

1.4 四大核心函数式接口

函数式接口名 抽象方法 方法说明
Consumer:消费型接口 void accept(T t) 一个参数,无返回值类型
Supplier:供给型接口 T get() 无参数,指定返回值类型T
Function<T, R>:函数型接口 R apply(T t) 一个参数,根据参数T类型返回R类型
Predicate:断言型接口 boolean test(T t) 判断T类型

1.5 举例

Consumer<String> consumer =s -> System.out.println(s);  //使用lambda表达式就是创建该接口的实例对象,因此consumer为Consumer接口的实例对象,Consumer接口抽象方法accept规定传入一个参数,且无返回值,lambda表达式需要满足该规则

consumer.accept("hello, world!");  //调用accept方法,输出"hello,world!"
Supplier<String> supplier = ()-> s//使用lambda表达式就是创建该接口的实例对象,supplier是Supplier接口的实例对象,Consumer接口抽象方法get规定无参数,且返回指定类型,lambda表达式需要满足该规则

String s = supplier.get("hello, world!")    //调用get,s值为"hello,world!"

使用总结

  • lambda返回的就是接口的实例对象
  • 根据参数个数(0,1,...),是否有返回值,返回值类型选择函数式接口,或自己写函数式接口
  • 实现lambda表达式逻辑(符合参数个数要求,返回值类型即可,具体可以实现不同的逻辑)

2. 内部类

参考:

https://zhuanlan.zhihu.com/p/57859259

https://zhuanlan.zhihu.com/p/26260645

2.1 成员内部类

与成员变量类似.如果内部类持有外部类的引用,可能导致内部类没有执行完,外部类无法释放,有内存泄露风险.需要在外部类生命周期结束时候手动结束内部类生命周期.

public class Outer{
    String s;
    //成员内部类
    class Inner{
        
    }
}

2.2 局部内部类

定义在方法或作用域里的类,与局部变量类似,存在内存泄漏风险

public class Outter{
    //成员内部类
    class Inner{
        String s;
    }
    
    public Innner getInner2(){
        //局部内部类
        class Inner2 extends Inner{
            String s = "Inner2";
        }
        return new Inner2();
    }
}

2.3 静态内部类

成员内部类前加static.静态内部类不会持有外部类的引用.不会造成内存泄漏

public class Outter{
    String s;
    static class Inner{
        
    }
}

2.4 匿名内部类

只能使用一次,必须继承一个父类或实现一个接口,通俗理解为new一个接口

常用于多线程

public class Outter{
    void test(){
        new Thread(new Runnable(){
            String s;
            public void run(){}
        }).start();
    }
}
abstract class Person{
    public abstract void eat();
}

public class Demo{
    public static void main(String[] args){
        Person p = new Person(){
            //直接重写实现抽象方法
            public void eat(){
                System.out.println("eat something");
            }
        };
        
        p.eat();
    }
}

3. 异常

参考

https://zhuanlan.zhihu.com/p/56115804

3.1 层次与相关概念

异常层次

概念 说明
受查异常 在编译时被检测,必须在编译时进行处理,否则编译无法通过,通过try-catch或throws处理
非受查异常 不会再编译时被检测,通常为程序错误导致,Error,RuntimeException为非受查异常,其余为受查异常
Throwable 所有异常类的基类
Error Java程序运行时系统的内部错误,通常比较严重,如StackOverflowError,系统崩溃等
Exception 狭义异常
运行时异常(仅针对Exception) RuntimeException及其子类,如空指针,下标越界等,一般为程序逻辑错误导致,一般不用人为处理
非运行时异常(仅针对Exception) RuntimeException以外的Exception子类.必须处理,如IO异常,SQL异常等

3.2 异常处理

  1. 在方法声明位置使用throws.抛给方法调用者,调用者处理异常

    private static void readFile(String filepath) throws IOException{
        //读取文件代码
    }
    
  2. 方法体中throw手动抛出异

    public static void main(String[] main){
        try{
            throw new Exception("异常");
        }catch(Exception e){
            System.out.println(e);
        }
    }
    
  3. try-catch-finally语句

    private static void readFIle(String filePath){
        try{
            //code
        }catch(FileNotFoundException | UnknownHostException e){
            //处理异常
        }catch(IOException e){
            //处理异常
        }finally{
            //最终一定执行的部分
        }
    }
    

注:

  • catch异常有多个时,从上到下遵从异常有小到大的顺序
  • 方法重写以后,不能比原方法抛出更多,更宽泛的异常,可以不抛,可以抛相同异常或异常子类
  • catch中有return语句,finally依然会执行,如果finally中也有return语句,会覆盖前面的return语句(最好不要在finally中写return语句)

3.3 自定义异常

  • 定义类继承Throwable或其子类

  • 定义两个构造函数,一个无参,一个带有描述信息

    public class MyException extends Exception{
        public MyException(){}
        
        public MyException(String msg){
            super(msg);
        }
        
        //...
    }
    

4. 泛型

理解:泛型就是把类型明确这一工作推迟到创建对象或调用方法的时候.类型化参数,即把类型当做参数进行传递.

好处:在编译时检查类型安全,并且所有强制类型转换都是自动,隐式的.

4.1 泛型类,接口,方法

  • 常用泛型类:ArrayList,HashMap,HashSet
  • 常用泛型接口:List,Map,Set
  • 泛型方法:参数中需要多少泛型,返回值前面就要定义多少泛型
//泛型类
public class Test<T>{
    
}

//泛型接口
public interface Test<T>{
    
}

//泛型方法
public <T,K,V> void Test(T name, K value, V value){
    
}

4.2 通配符与类型参数

  • ? : 无界通配符,不确定的java类型,通常用于泛型方法的调用和形参
  • T : 具体的java类型,通常用于泛型类和方法的定义
  • K V : 键值对
  • E : element元素
  • ? entends E : 上界通配符,表示参数化类型是E或其子类
  • ? super E : 下界通配符,表示参数化类型是E或其父类
posted @ 2020-12-27 11:28  OLeeO97  阅读(42)  评论(0编辑  收藏  举报