一、接口默认方法&静态方法
Java8允许在接口中存在具有具体实现的方法,需要使用default修饰符进行修饰。
接口默认方法的“类优先”原则:
若一个接口中定义了一个默认方法,而另外一个父类或接口中又定义了一个同名方法时:
- 选择父类中的方法。如果一个父类提供了具体的实现,那么接口中具有相同名称和参数的默认方法会被忽略。
- 接口冲突。如果一个父接口提供一个默认方法,而另一个接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么必须覆盖该方法来解决冲突。
MyFun.java
package com.its.java8;
public interface MyFun {
default String getName() {
return "哈哈哈";
}
}
MyClass.java
package com.its.java8;
public class MyClass {
public String getName() {
return "嘿嘿嘿";
}
}
SubClass.java
package com.its.java8;
public class SubClass extends MyClass implements MyFun {
}
TestDefaultInterface.java
package com.atguigu.java8;
public class TestDefaultInterface {
public static void main(String[] args) {
SubClass sc = new SubClass();
System.out.println(sc.getName()); // 嘿嘿嘿
}
}
接口中方法冲突问题演示:
MyInterface.java
package com.its.java8;
public interface MyInterface {
default String getName() {
return "呵呵呵";
}
}
SubClass.java
package com.its.java8;
// 实现多个接口,多个接口中具有相同名称和参数列表的默认方法,出现接口冲突
public class SubClass implements MyFun, MyInterface {
// 此时就必须要覆盖接口方法来解决冲突
@Override
public String getName() {
return MyInterface.super.getName();
}
}
接口中静态方法演示:
package com.its.java8;
public interface MyInterface {
default String getName() {
return "呵呵呵";
}
// Java8允许在接口中定义静态方法,调用方式不变,还是:类名.方法
public static void show() {
System.out.println("接口中的静态方法");
}
}
二、重复注解与类型注解
Java8对注解处理提供了两点改进:可重复的注解以及可用于类型的注解。
演示重复注解和类型注解:
MyAnnotation.java
package com.its.java8.annotation;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.TYPE_PARAMETER;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE, TYPE_PARAMETER })
public @interface MyAnnotation {
String value() default "its";
}
MyAnnotations.java
package com.its.java8.annotation;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE })
public @interface MyAnnotations {
MyAnnotation[] value();
}
TestAnnotation.java
package com.its.java8.annotation;
import java.lang.reflect.Method;
import org.junit.Test;
/*
* 重复注解与类型注解
*/
public class TestAnnotation {
// 获取show方法上的@MyAnnotation注解的value
@Test
public void test1() throws Exception {
Class<TestAnnotation> clazz = TestAnnotation.class;
Method m1 = clazz.getMethod("show");
MyAnnotation[] myAnnotations = m1.getAnnotationsByType(MyAnnotation.class);
for (MyAnnotation myAnnotation : myAnnotations) {
System.out.println(myAnnotation.value());
// Hello
// World
}
}
// 重复注解&类型注解
@MyAnnotation("Hello")
@MyAnnotation("World")
public void show(@MyAnnotation("abc") String str) {
}
}