1、可以为接口方法提供一个默认实现。用default修饰符标记。方法未被覆盖时,使用default方法
例:public interface Comparable<T>{
default int compareTo(T other){ return 0;}
}
当一个接口含有多个方法,又不希望所有方法被实现时,default方法生效。
2、解决默认方法冲突
先在一个接口中将一个方法定义为默认方法,然后在超类或另一个接口中定义了同样的方法
1)超类优先
如果超类提供了具体方法,则忽略默认方法
2)接口冲突
编译器会报错,必须覆盖这个方法
3、Comparator接口
已经实现了Comparable接口,又想使用另一种排序方式,此时可以实现Comparator接口,实现compare方法
4、对象克隆
Cloneable接口
浅拷贝:默认的克隆操作是浅拷贝,并没有克隆对象中引用的其他对象。这样克隆对象与原对象共享的子对象发生变化时,就不安全。
深拷贝:克隆所有子对象,实现CloneAble接口,重新定义clone方法,并指定public访问修饰符
所有数组都有一个public的clone方法,
5、lambda表达式
处理代码块
形式:参数->表达式(代码块)
例:()->{for(int i=100;i>=0;i–){sout(i);}}没有参数仍要提供空括号
6、函数式接口
对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式
例如:Arrays.sort(),第二个参数需要一个Comparator实例,
Arrays.sort(words,(first,second)->first.length()-second.length());
底层,Arrays.sort()会实现Comparator的某个类的对象。然后在这个对象上调用compare()执行lambda表达式的体
7、方法引用
已经有现成的方法可以完成想要传递代码到其他代码的某个操作
例:Timer t=new Timer(1000,event->System.out.println(event));等价于Timer t=new Timer(1000,System.out::println);
使用::分隔方法名与对象或类名
object::instanceMethod System.out::println==x->System.out.println(x)
Class::staticMethod Math::pow==(x,y)->Math.pow(x,y)
Class::instanceMethod String::compareToIgnoreCase==(x,y)->x.compareToIgnoreCase(y)
8、构造器引用
与方法引用类似,只不过方法名为new
9、变量作用域
lambda表达式可以捕获外围作用域中变量的值,但这个值在lambda表达式中不能被改变(表达式外也不能改变)
例:public static void repeatMessage(String text,int delay){
ActionListener listener=event->{
System.out.println(text);
...
}
}
10、编写方法处理lambda表达式
使用lambda表达式的重点是延迟执行
例:重复一个动作n次repeat(10,()->System.out.println(“Hello!”));
要接收lambda表达式,需要选择一个函数式接口(偶尔需要自己写)
Java Api提供的接口如下:

public static void repeat(int n,Runnable action){
for(int i=1;i<n;i++){
action.run();
}
}
11、内部类
1)内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据
2)内部类可以对同一个包中的其他类隐藏起来
3)当想定义一个回调函数时,使用匿名内部类比较便捷
12、局部内部类
内部类只在一个方法中调用一次时,可以在这个方法中在定义局部类。
public void start(){
class TimePrinter implements ActionListener{
System.out.println(new Date());
}
}
局部类不能用public或private说明
13、匿名内部类
只创建这个类的一个对象,就不必命名了
接口 对象名=new 接口(){
接口方法实现;
}
14、代理
代理类可以在运行时创建全新的类,这样的代理类能够实现指定的接口。
不能在运行时定义这些方法的新代码,而要提供一个调用处理器(invocation handler)。调用处理器是实现了InvocationHandler接口的类对象,实现invoke(Object proxy,Method method,Object[] args)方法。
无论合适调用代理对象的方法,InvocationHandler的invoke方法都会被调用。
创建代理对象:使用Proxy类的newProxyInstance(参数1,参数2,参数3)方法
参数1:类加载器,null表示默认的类加载器
参数2:Class对象数组,每个元素都是需要实现的接口
参数3:调用处理器(invocation handler)
也可以使用cglib实现动态代理
Enhancer.create(代理类.getClass(),new MethodInterceptor{
// 使用匿名内部类实现intercept方法
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {}
});返回一个代理对象
所有代理类都覆盖了Object类中的方法toString(),equals(),hashcode()
本文深入探讨Java接口的default方法,解决方法冲突,Comparator与Cloneable接口使用,lambda表达式,函数式接口,方法引用,构造器引用,变量作用域,内部类,局部内部类,匿名内部类及代理的概念与应用。
1197

被折叠的 条评论
为什么被折叠?



