目录
一、反射
1.1 反射的概念
- 通过反射机制可以获取所有的资源
- 反射机制:获取类的各个部分,组成一个新的对象(Class对象)就是反射机制
- 流程图
1.2 获取Class对象和构造方法
- 实例化对象可以通过Class.forName的对象和构造方法对象创建
package qf22020310_test_class.Demo01;
import org.junit.Test;
import qf22020310_test_class.peanut.Student;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test01 {
@Test
public void test01() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Class<?> aClass = Class.forName("qf22020310_test_class.peanut.Student");
//Test01.class 方法2 类名.class
//new Test01().class 方法3 对象名.class
//获取单个共有的构造方法对象
Constructor gc = aClass.getConstructor();
System.out.println(gc);
//获取多个共有的构造方法对象
Constructor<?>[] arrGc = aClass.getConstructors();
System.out.println(arrGc);
//获取单个私有的构造方法对象
Constructor<?> gDc = aClass.getDeclaredConstructor();
System.out.println(gDc);
//获取多个私有的构造方法对象
Constructor<?>[] arrDc = aClass.getDeclaredConstructors();
System.out.println(arrDc);
//利用aClass类创建类对象
Student o = (Student)aClass.newInstance();
//利用gc类创建类对象
Student o1 = (Student)gc.newInstance();
o.get("afe");
o1.get("fea");
}
}
1.3 获取方法
- 获取方法
package qf22020310_test_class.Demo01;
import org.junit.Test;
import java.lang.reflect.Method;
public class Test02 {
@Test
public void test() throws ClassNotFoundException, NoSuchMethodException {
Class<?> aClass = Class.forName("qf22020310_test_class.peanut.Student");
//获取单个方法,String.class 方法中的参数类型
aClass.getMethod("方法名", String.class);
//获取全部共有的方法
Method[] methods = aClass.getMethods();
//获取单个私有方法
Method print = aClass.getDeclaredMethod("方法名");
System.out.println(print);
//获取全部私有方法
Method[] dms = aClass.getDeclaredMethods();
}
}
1.4 案例应用
-
问题:通过利用反射机制读取properties属性文件中的类路径、方法名、方法参数.class 类来创建出新的对象
-
属性配置文件
-
定义一个私有化构造的Student类
package qf22020310_properties;
public class Student {
private Student() {}
public void add(String name,Integer age){
System.out.println("姓名:"+name+"\t年龄:"+age);
}
public void get(){
System.out.println("无参数get方法");
}
}
- 定义工具类
package qf22020310_properties;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 利用反射和懒汉设计模式,实现加载资源文件工具类
*/
public class PropertiesUtils {
private static PropertiesUtils pu;
Properties p;
private PropertiesUtils() {
try {
p = new Properties();
//利用本身类对象方法加载资源文件
InputStream ras = PropertiesUtils.class.getResourceAsStream("properties.properties");
//加载到Properties
p.load(ras);
} catch (IOException e) {
e.printStackTrace();
}
}
//双重锁设计模式
public static synchronized PropertiesUtils getInstance() {
if (pu == null) {
synchronized (PropertiesUtils.class){
if(pu==null){
pu = new PropertiesUtils();
}
}
}
return pu;
}
public String getValue(String name) {
return p.getProperty(name);
}
}
- 反射来创建对象
package qf22020310_properties;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
/**
* @author 18480
*/
public class ReflectInstance {
public void createInstance() throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
PropertiesUtils instance = PropertiesUtils.getInstance();
//工具类获取参数
String classname = instance.getValue("classname");
String methodname = instance.getValue("methodname");
String par = instance.getValue("par");
//获取aClass类操作对象
Class<?> aClass = Class.forName(classname);
//获取单个构造方法对象
Constructor<?> constructor = aClass.getDeclaredConstructor();
//暴力去除私有,实例化对象
constructor.setAccessible(true);
//利用构造对象实例化类对象
Object o = constructor.newInstance();
//返回要调用方法的参数类型集
Class[] classes = classes(par);
if(classes==null||classes.length<=0){
//创建一个方法对象,调用invoke启动方法
aClass.getDeclaredMethod(methodname).invoke(o);
}else{
aClass.getMethod(methodname,classes).invoke(o,"小明",22);
}
}
public static Class[] classes(String par) {
if (par == null || "".equals(par)) {
return null;
}
String[] split = par.split(",");
List<Class> list = new ArrayList<>();
for (String s : split) {
if (s.equals("String")) {
list.add(String.class);
} else if (s.equals("Integer")) {
list.add(Integer.class);
} else {
list.add(Object.class);
}
}
return list.toArray(new Class[list.size()]);
}
}
- 测试类
package qf22020310_properties;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
/**
* @author 18480
*/
public class Test01 {
@Test
public void test() throws ClassNotFoundException, InvocationTargetException, InstantiationException, NoSuchMethodException, IllegalAccessException {
ReflectInstance ri = new ReflectInstance();
ri.createInstance();
}
}
二、jdk8和jdk9接口的新特性
2.1 jdk8:默认方法和静态方法
- 默认方法:可以实例化对象来调用或者在实现类中的其他方法中使用接口名.super.方法名调用,可以不用重写
- 静态方法:可以直接通过接口名称.方法名来调用,实现类不能重写接口中的静态方法
2.2 jdk9:私有的方法
- 私有的方法可以使用默认的方法来调用
- 私有的静态方法只能是默认方法或静态方法调用
三、Lambda表达式
- 本质:是一个匿名的接口
- 条件:必须是函数型接口(jdk默认的注解为@FunctionalInterface,自定义为:接口+一个抽象方法,实现类方法一个 参数为该接口),接口中只能有一个抽象方法,可以有其他方法
- 语法:(参数)->{方法体}
- (参数) 是接口中方法的参数
- -> 是指向方法体
- {} 执行方法的操作
3.1 Lambda表达式简化方式
3.1.1 一参有返回值
- 如果方法只有一个参数,小括号与数据类型可以省略(有参有返回值)
package qf22020310_demo.Demo02;
public interface Inner {
abstract int add(int num1);
}
package qf22020310_demo.Demo02;
public class Test01 {
public static void main(String[] args) {
System.out.println(add(10, num1 -> num1+1));
}
public static int add(int num,Inner inner){
return add(int num);
}
}
3.1.2 一参以上有返回值
- 如果方法参数一个以上,有参有返回值 { } 用在返回有执行的语句上
package qf22020310_demo.Demo03;
public interface Inner {
abstract int add(int num1,int num2);
}
package qf22020310_demo.Demo03;
public class Test01 {
public static void main(String[] args) {
System.out.println(add(10, 20, (num1, num2) -> num1 + num2));
}
public static int get(int num1,int num2,Inner inner){
return add(int num1,int num2);
}
}
3.1.3 无参无返回值
- 没有参数没有返回值的接口
package qf22020310_demo.Demo04;
public interface Inner {
abstract void add();
}
package qf22020310_demo.Demo04;
public class Demo01 {
public static void main(String[] args) {
add(()-> System.out.println("执行了"));
}
public static void add(Inner inner){
inner.add();
}
}
3.1.4 有参数没有返回值
- 有参数没有返回值
package qf22020310_demo.Demo05;
public interface Inner {
abstract void add(int num1,int num2);
}
package qf22020310_demo.Demo05;
public class Demo01 {
public static void main(String[] args) {
add(10, 20, (num1, num2) -> System.out.println(num1+num2));
}
public static void add(int num1,int num2,Inner inner){
inner.add(num1,num2);
}
}
3.1.5 无参数有返回值
- 无参数有返回值
package qf22020310_demo.Demo06;
public interface Inner {
abstract int add();
}
package qf22020310_demo.Demo06;
public class Demo01 {
public static void main(String[] args) {
System.out.println(add(()->2));
}
public static int add(Inner inner){
return inner.add();
}
}