注解(Annotation)
Annotation可以说是JDK发展的重要技术,从现在的开发来讲,Annotation的使用已经变得非常常见。
JDK三个内置注解
1. @Override 准确覆写
当子类覆写父类方法时,此注解检查覆写的方法是否正确声明,只有满足覆写方法要求才会编译通过,否则编译出错。
2. @Deprecated 过期声明
建议用户不使用原有的类&方法时,可以在类或方法上@Deprecated表示在当前版本中不推荐使用
eg:观察过期声明
class Person {
private String name;
@Deprecated//表示该方法已经不建议使用了,但你使用了也不会出错
public Person() {//不推荐使用的构造方法
System.out.println("*******");
}
public Person(String name) {
System.out.println("#########");
}
}
public class Test_11_6 {
public static void main(String[] args) {
Person per1 = new Person();//明确的标记出过期
Person per2 = new Person("hello");
}
}
3. @SuppressWarings 压制警告
调用某些操作可能产生问题的时候会出现警告信息,但是警告信息并不是异常
常见的压制警告关键字
deprecation 使用了不赞成使用的类或方法时的警告
unchecked 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics)
来指定集合保存的类型。
rawtypes 使用类时忽略没有指定相应的类型
fallthrough 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告。
path 在类路径、源文件路径等中有不存在的路径时的警告。
serial 当在可序列化的类上缺少 serialVersionUID 定义时的警告。
finally 任何 finally 子句不能正常完成时的警告。
all 关于以上所有情况的警告。
接口定义增强
JDK1.8之后接口允许出现以下两种方法:
- 使用default定义的普通方法,需要通过接口对象来调用。
- 使用static定义的静态方法,直接使用接口名调用。
eg:
/**
* 接口定义增强
*/
interface ICompute {
default void fun() {
System.out.println("接口中的普通方法,需要通过接口对象来调用,并且不需要被覆写");
}
static ICompute test() {
System.out.println("接口中的静态方法,直接通过接口调用,不需要被覆写");
return new Computer();
}
void print();//接口中的抽象方法
}
class Computer implements ICompute {
@Override
public void print() {
System.out.println("覆写了接口中的抽象方法");
}
}
public class Test_11_7 {
public static void main(String[] args) {
ICompute iCompute = ICompute.test();
System.out.println(iCompute);
iCompute.fun();
iCompute.print();
}
}
Lambda表达式
-
Lambda是JDK1.8推出的重要新特性。很多开发语言都开始支持函数式编程,其中最具备代表性的就是haskell。
函数式编程和面向对象编程可以理解为两大开发阵营。很多人认为面向对象的概念过于完整,结构操作不明确。 -
要想使用函数式编程有一个前提:接口必须只有一个方法。
如果存在两个以上的方法,无法使用函数式编程。 -
如果现在某个接口就是为了函数式编程而生的,在定义时只能存在一个方法,
因此有一个新的注解@FunctionalInterface,此注解会检查该接口中是否只存在
一个抽象方法,存在两个抽象方法以上编译报错。
语法:
方法体只有一行代码时:
(方法参数) -> 具体的方法体实现
当方法有返回值时,单行代码的Lambda表达式可以省略return语句。
当方法体有多行代码时:
(方法参数) -> {
....
....
....
[return 语句];
};
eg:
/**
* Lambda表达式
*/
@FunctionalInterface//是一个函数式编程接口,只允许有一个方法
interface IAdd {
int add(int x, int y);//抽象方法
}
public class Test_11_7 {
public static void main(String[] args) {
IAdd iAdd = (p1, p2) -> {
System.out.print("p1 + p2 = ");
return(p1+p2);
};
System.out.println(iAdd.add(10,20));
}
}
方法引用
从最初开始,只要是进行引用都是针对于引用类型完成的,也就是只有数组、类、接口具备引用操作。但是JDK1.8 开始追加了方法引用的概念。实际上引用的本质就是别名。所以方法的引用也是别名的使用。而方法引用的类型有 四种形式:
- 引用类中静态方法
类名称 :: 静态方法名称
/**1.
* 引用String类的静态方法将Integer转化成String
* @param <R> Integer类
* @param <P> String类
*/
@FunctionalInterface
interface IUsb<R,P> {
P switchPara(R r);//接口的抽象方法
}
public class Test_11_8 {
public static void main(String[] args) {
IUsb<Integer,String> iUsb = String :: valueOf;
String str = iUsb.switchPara(1000);//相当于调用了String.valueOf(1000)
System.out.println(str.length());
}
}
- 引用某个对象的方法
实例化对象 :: 普通方法
/**2.
* 引用对象的普通方法 (String类的toUpperCase方法为对象方法)
* @param <T> 返回String类
*/
@FunctionalInterface//是一个函数式编程接口,只允许有一个方法
interface IUsb<T> {
T switchPara();
}
public class Test_11_8 {
public static void main(String[] args) {
IUsb<String> iUsb = "hello" :: toUpperCase;
String str = iUsb.switchPara();
System.out.println(str);
}
}
- 引用类中普通方法
类名称 :: 普通方法名`
/**3.
* 引用类中的普通方法(String类的compareTo方法)
* @param <T> 返回Integer类型
* @param <R> 传入两个String类比较
*/
@FunctionalInterface// 是一个函数式编程接口,只允许有一个方法
interface IUsb<T, R> {
T switchPara(R r1, R r2);
}
public class Test_11_8 {
public static void main(String[] args) {
IUsb<Integer, String> iUsb = String :: compareTo;
Integer integer = iUsb.switchPara("李","曹");
System.out.println(integer);
}
}
- 引用类中构造方法
类名称 :: new
class Per {
@SuppressWarnings("unused")
private String name;
@SuppressWarnings("unused")
private Integer age;
@SuppressWarnings("all")
public Per(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "name:"+this.name+" "+"age:"+this.age;
}
}
/**4.
* 引用构造方法
* @param <T> 返回类名
* @param <Rp> String类
* @param <Rn> Integer类
*/
@FunctionalInterface //是一个函数式编程接口,只允许有一个方法
interface IPer<T, Rp, Rn> {
T switchPara(Rp rp, Rn rn);
}
public class Test_11_8 {
public static void main(String[] args) {
IPer<Per, String, Integer> iPer = Per :: new;
Per p = iPer.switchPara("李",18);
System.out.println(p);
}
}