反射机制的应用,jdk8和jdk9接口的新特性接口属性,Lambda表达式

一、反射

1.1 反射的概念

  1. 通过反射机制可以获取所有的资源
  2. 反射机制:获取类的各个部分,组成一个新的对象(Class对象)就是反射机制
  3. 流程图在这里插入图片描述

1.2 获取Class对象和构造方法

  1. 实例化对象可以通过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 获取方法

  1. 获取方法
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 案例应用

  1. 问题:通过利用反射机制读取properties属性文件中的类路径、方法名、方法参数.class 类来创建出新的对象

  2. 属性配置文件在这里插入图片描述

  3. 定义一个私有化构造的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方法");
    }
}


  1. 定义工具类
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);
    }
}

  1. 反射来创建对象
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()]);
    }
}

  1. 测试类
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:默认方法和静态方法

  1. 默认方法:可以实例化对象来调用或者在实现类中的其他方法中使用接口名.super.方法名调用,可以不用重写
  2. 静态方法:可以直接通过接口名称.方法名来调用,实现类不能重写接口中的静态方法

2.2 jdk9:私有的方法

  1. 私有的方法可以使用默认的方法来调用
  2. 私有的静态方法只能是默认方法或静态方法调用

三、Lambda表达式

  1. 本质:是一个匿名的接口
  2. 条件:必须是函数型接口(jdk默认的注解为@FunctionalInterface,自定义为:接口+一个抽象方法,实现类方法一个 参数为该接口),接口中只能有一个抽象方法,可以有其他方法
  3. 语法:(参数)->{方法体}
  4. (参数) 是接口中方法的参数
  5. -> 是指向方法体
  6. {} 执行方法的操作

3.1 Lambda表达式简化方式

3.1.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 一参以上有返回值
  1. 如果方法参数一个以上,有参有返回值 { } 用在返回有执行的语句上
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 无参无返回值
  1. 没有参数没有返回值的接口
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 有参数没有返回值
  1. 有参数没有返回值
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 无参数有返回值
  1. 无参数有返回值
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();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT阿生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值