java基础-反射-day15

发布时间 2023-10-09 22:36:35作者: chenwen0511


JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,
都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

1. 案例引入

点外卖 有多种支付方式
微信支付 支付宝支付 。。。

接口

package com.msb.test01;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 20:46
 * @Description: com.msb.test01
 * @version: 1.0
 */
public interface Pay {
    void payOnline();
}

支付宝支付

package com.msb.test01;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 20:48
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class AliPay implements Pay {
    @Override
    public void payOnline() {
        System.out.println("Ali pay");
    }
}

微信支付

package com.msb.test01;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 20:47
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class WeChart implements Pay {
    @Override
    public void payOnline() {
        System.out.println("We Chart pay");
    }
}

银行卡支付

  package com.msb.test01;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 20:49
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class BankPay implements Pay {
    @Override
    public void payOnline() {
        System.out.println("bank card pay");
    }
}

实现支付的方式1

package com.msb.test01;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 20:50
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class Test01 {
    public static void main(String[] args) {
        String str = "wechart";
        if ("wechart".equals(str)){
            pay(new WeChart());
        }

    }
    public static void pay(WeChart wc){
        wc.payOnline();
    }

    public static void pay(AliPay ap){
        ap.payOnline();
    }

    public static void pay(BankPay bp){
        bp.payOnline();

    }
}

实现支付的方式2 多态

package com.msb.test01;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 20:50
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class Test02 {
    public static void main(String[] args) {
        String str = "wechart";
        if ("wechart".equals(str)){
            pay(new WeChart());
        }

    }
    public static void pay(Pay p){
        p.payOnline();
    }

}

实现支付的方式3 反射

package com.msb.test01;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 20:58
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class Test03 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        String str = "com.msb.test01.AliPay";
        Class clazz = Class.forName(str);
        Object o = clazz.newInstance();
        Method payOnline = clazz.getMethod("payOnline");
        payOnline.invoke(o);
    }
}

2. Class 的理解

Class 是对所有类的后抽象 所有的类 例如 Person Student 都只是Class 的一个实例而已

3. 反射的详细使用

获取 类的字节码

package com.msb.test01;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 21:30
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class Test04 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person p = new Person();
        Class c1 = p.getClass();
        System.out.println(c1);

        Class c2 = Person.class;
        System.out.println(c2);

        Class c3 = Class.forName("com.msb.test01.Person");
        System.out.println(c3); //最常用


        ClassLoader classLoader = Test04.class.getClassLoader();
        Class c4 = classLoader.loadClass("com.msb.test01.Person");
        System.out.println(c4);

        //字节码只加载一次 所以 都是同一个 字节码 c1 == c2


    }
}

4. Class 类都有哪些实例

Class类的具体的实例:
(1)类:外部类,内部类
(2)接口
(3)注解
(4)数组
(5)基本数据类型
(6)void

package com.msb.test01;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 21:36
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class Test05 {
    public static void main(String[] args) {
        
        Class c1 = Person.class;
        Class c2 = Comparable.class;
        Class c3 = Override.class;
        
        
        int[] arr1 = {1,2,3};
        Class c4 = arr1.getClass();
        
        Class c6 = int.class;
        Class c7 = void.class;
    }
}

5. 详细使用

注解

package com.msb.test01;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 21:41
 * @Description: com.msb.test01
 * @version: 1.0
 */
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    String value();
}

接口

package com.msb.test01;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 21:43
 * @Description: com.msb.test01
 * @version: 1.0
 */
public interface MyInterface {
    void myMethod();
}

父类

package com.msb.test01;

import java.io.Serializable;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 21:24
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class Person implements Serializable {
    private int age;
    public String name;

    public void eat(){
        System.out.println("eating");
    }

    public void sleep(){
        System.out.println("Sleeping");
    }
}

子类

package com.msb.test01;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 21:25
 * @Description: com.msb.test01
 * @version: 1.0
 */
@MyAnno(value="hello")
public class Student extends Person implements MyInterface {

    private int sno;
    double height;
    protected double weight;
    public double score;

    @MyAnno(value="himethod")
    public String ShowInfo(){
        return "我是 一名三好学生";
    }

    private void work(){
        System.out.println("Working");
    }

    public Student(){
        System.out.println("空参 构造器");
    }

    public Student(int sno){
        this.sno = sno;
    }

    public Student(int sno, double weight){
        this.sno = sno;
        this.weight = weight;

    }
    protected Student(int sno,double height,double weight){
        this.sno = sno;
    }

    @Override
    public void myMethod() {
        System.out.println("Student override myMethod!!!");
    }

    @Override
    public String toString() {
        return "Student{" +
                "sno=" + sno +
                ", height=" + height +
                ", weight=" + weight +
                ", score=" + score +
                '}';
    }
}

package com.msb.test01;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 21:49
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class Test06 {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        Class cls = Student.class;

        // 构造器的获取
        Constructor[] constructors = cls.getConstructors();//只能获取当前运行时类的被public修饰的构造器
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        Constructor constructor1 = cls.getConstructor();
        System.out.println(constructor1);//空参构造器

        Constructor constructor = cls.getDeclaredConstructor(double.class, double.class);
        System.out.println(constructor);//两个double参数的构造器

        Constructor declaredConstructor = cls.getDeclaredConstructor(int.class);
        System.out.println(declaredConstructor);//private修改的构造器

        Object o1 = constructor1.newInstance();
        System.out.println(o1);//创建对象

        Object o2 = constructor.newInstance(180.0, 170.1);
        System.out.println(o2);


    }
}


6. 获取属性

package com.msb.test01;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 22:01
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class Test07 {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        Class cls = Student.class;

        Field[] fields = cls.getFields();//获取运行时类和父类中被public修饰的属性
        for (Field field : fields) {
            System.out.println(field);
        }

        Field[] declaredFields = cls.getDeclaredFields();
        System.out.println(declaredFields);//获取运行时类中的所有属性

        Field score = cls.getDeclaredField("score");
        System.out.println(score);

        Field sno = cls.getDeclaredField("sno");
        System.out.println(sno);

        //修饰符 modifiers
        int modifiers = sno.getModifiers();
        System.out.println(modifiers);
        System.out.println(Modifier.toString(modifiers));

        //获取filed的数据类型
        Class type = sno.getType();
        System.out.println(type.getName());

        String name = sno.getName();
        System.out.println(name);


        Field score1 = cls.getField("score");
        Object o = cls.newInstance();
        score1.set(o, 98);
        System.out.println(o);
        
    }
}

7. 获取方法

package com.msb.test01;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 22:10
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class Test08 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {

        Class cls = Student.class;
        Method[] methods = cls.getMethods();//取运行时类的方法还有所有父类中的方法(被public修饰)
        for (Method method : methods) {
            System.out.println(method);
        }

        Method[] declaredMethods = cls.getDeclaredMethods();//获取运行时类中的所有方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        Method showInfo = cls.getMethod("ShowInfo");
        System.out.println(showInfo);

        Method work = cls.getDeclaredMethod("work", int.class);
        System.out.println(work);

        String name = work.getName();//方法的名字
        System.out.println(name);

        int modifiers = work.getModifiers();//方法的修饰符
        System.out.println(Modifier.toString(modifiers));

        Class<?> returnType = work.getReturnType();
        System.out.println(returnType);

        Class<?>[] parameterTypes = work.getParameterTypes();//方法的参数类型
        for (Class<?> parameterType : parameterTypes) {
            System.out.println(parameterType);
        }

        Object o = cls.newInstance();
        Method myMethod = cls.getMethod("myMethod");
        myMethod.invoke(o);


    }
}

8 获取类的 接口 注解 所在的包

  package com.msb.test01;

import java.lang.annotation.Annotation;

/**
 * @Auther: jack.chen
 * @Date: 2023/10/9 - 10 - 09 - 22:23
 * @Description: com.msb.test01
 * @version: 1.0
 */
public class Test09 {
    public static void main(String[] args) {
        Class cls = Student.class;

        Class[] interfaces = cls.getInterfaces();
        for (Class anInterface : interfaces) {
            System.out.println(anInterface);
        }

        Class superclass = cls.getSuperclass();
        System.out.println(superclass);

        Class[] interfaces1 = superclass.getInterfaces();
        for (Class c : interfaces1) {
            System.out.println(c);

        }

        Package aPackage = cls.getPackage();
        System.out.println(aPackage);
        System.out.println(aPackage.getName());

        Annotation[] annotations = cls.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

    }
}

9. 思考

反射是否破坏了 封装
private proteted属性方法外部还是能访问到