反射(JAVA)

概念

在这里插入图片描述

功能

在这里插入图片描述

反射主要API

在这里插入图片描述

CLASS类

1.Class本身也是一个类
2.Class对象只能由系统创建
3.一个类再JVM中只会有一个Class实例
4.一个Class对象对应的是一个加载到JVM中的一个.class文件
5.每个类的实例都会记得自己是由哪个Class实例所生成
6.通过Class可以完整地得到一个类中的完整结构

java.lang.Class是反射的源头,.class文件加载到虚拟机后就会产生一个运行时类,通过这个类我们可以:
1.创建该类对象
2.获取对应运行时类的完整结构(属性、方法、内部类、父类,注解等)

在这里插入图片描述

实例

注解类

@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.TYPE })
public @interface MyAnnotation {
    int id() default 1;
    String name();
    // 定义枚举
    public enum EnumType {
        util, entity, service, model
    }
    // 设置默认值
    public EnumType classType() default EnumType.util;
    // 数组
    int[] arr() default { 3, 7, 5 };
    String methodUrl() default "";

}

接口类

public interface Myinterface extends Serializable{
    void show();
}

泛型类

public class Creature<T> {
    T cname;
    public void printT(){
        System.out.println("泛型打印:"+cname);
    }
    public void setCname(T cname) {
        this.cname = cname;
    }
}

父类

@MyAnnotation(name = "Parent")
public class Parent extends Creature<String> implements Myinterface {

    private String name;
    private Integer age;
    public String pPub;
    @Override
    public void show() {
        System.out.println("*******我是"+name+"******");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public static void printSta(){
        System.out.println("我是静态方法!!");
    }

    private static void printPri(){
        System.out.println("我是私有方法!!");
    }

    @Override
    public String toString() {
        return "Parent{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", pPub='" + pPub + '\'' +
                '}';
    }

}

子类

@MyAnnotation(name = "Child")
public class Child extends Parent{

    private String name;
    private String add;
    public String pub;

    public Child() {
    }

    public Child(String name) {
        this.name = name;
    }

    private void privateMethod() throws IllegalAccessException{
        System.out.println("这是一个私有方法");
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    public String getAdd() {
        return add;
    }

    public void setAdd(String add) {
        this.add = add;
    }
    @MyAnnotation(name = "方法注解",arr = {1,2,3,4,5},methodUrl = "com.zy.demo.AnnotationDemo#Anprint")
    public void printMsg(){
        System.out.println("######我是"+name+"#####");
    }

    @Override
    public String toString() {
        return "Child{" +
                "name='" + name + '\'' +
                ", add='" + add + '\'' +
                '}';
    }
}

获取Class类四种方式

    public void test() throws ClassNotFoundException {
        //1若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
        Class<Child> c1 = Child.class;

        //2若已知类的实例,通过getClass获取
        Child child = new Child();
        Class<? extends Child> c2 = child.getClass();

        //3若已知类的全类名,且该类在类路径下,可通过forName获取,需处理异常ClassNotFoundException
        Class<?> c3 = Class.forName("com.zy.reflection.Child");

        //4其他,通过类加载器来实现
        ClassLoader classLoader = this.getClass().getClassLoader();
        Class<?> c4 = classLoader.loadClass("com.zy.reflection.Child");

        System.out.println("c1 = " + c1);
        System.out.println("c2 = " + c2);
        System.out.println("c3 = " + c3);
        System.out.println("c4 = " + c4);
    }
}

在这里插入图片描述

实例化对象

    public void test() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        Class<Child> c1 = Child.class;
        //1.无参实例化对象
        Child child = c1.newInstance();
        System.out.println("child = " + child);
        //2.有参实例化对象
        Constructor<Child> ct = c1.getConstructor(String.class);
        Child child1 = ct.newInstance("孩子");
        System.out.println("child1 = " + child1);

    }

在这里插入图片描述

获取类的完整结构

1.属性获取

在这里插入图片描述

    public void test() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<Child> c1 = Child.class;
        //只能获取运行时类中及其父类中声明为Public的属性
        Field[] fields = c1.getFields();
        for (Field f:fields) {
            //1.获取每个属性权限修饰符
            int Num = f.getModifiers();//权限对应数字
            String str = Modifier.toString(Num);//数字转换权限
            System.out.println("str = " + str);
            //2.获取属性的类型
            Class<?> type = f.getType();
            System.out.println("type = " + type.getName());
            //3.获取属性名
            System.out.println("f.getName() = " + f.getName());

        }
        System.out.println("----------------------------------");
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field f:declaredFields) {
            int Num = f.getModifiers();
            String str = Modifier.toString(Num);
            System.out.println("str = " + str);
            Class<?> type = f.getType();
            System.out.println("type = " + type.getName());
            System.out.println("f.getName() = " + f.getName());
        }
    }

在这里插入图片描述

2.方法获取

在这里插入图片描述

    public void test(){
        Class<Child> c1 = Child.class;
        Method[] declaredMethods = c1.getDeclaredMethods();
        for (Method m : declaredMethods) {
            //1.注解
            Annotation[] annotations = m.getAnnotations();
            for (Annotation a: annotations) {
                System.out.println(a);
            }

            //2.权限修饰符
            String str = Modifier.toString(m.getModifiers());
            System.out.print(str + " ");

            //3.返回值类型
            Class<?> returnType = m.getReturnType();
            System.out.print(returnType.getName()+" ");

            //4.方法名
            System.out.print(m.getName()+" ");

            //5.形参列表
            System.out.print("(");
            Class<?>[] parameterTypes = m.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                System.out.print(parameterTypes[i].getName() + " args-"+i+" ");
            }

            //6.异常类型
            Class<?>[] exceptionTypes = m.getExceptionTypes();
            if(exceptionTypes.length != 0){
                System.out.print("throws ");
            }
            for (int i = 0; i < exceptionTypes.length; i++) {
                System.out.print(exceptionTypes[i].getName());
            }
            System.out.print(") ");
            System.out.println();
        }
    }

在这里插入图片描述

3.构造器获取

在这里插入图片描述

    public void test(){
        Class<Child> c1 = Child.class;
        Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor c : declaredConstructors) {
            System.out.println(c);
        }
    }

在这里插入图片描述

父类、接口、泛型获取

在这里插入图片描述

public void test(){

        //1.获取运行时类的父类
        Class<Child> c1 = Child.class;
        Class<? super Child> superclass = c1.getSuperclass();
        System.out.println("superclass = " + superclass);

        //2.获取带泛型的父类
        Type genericSuperclass = c1.getGenericSuperclass();
        System.out.println("genericSuperclass = " + genericSuperclass);

        //3.获取父类的泛型
        Class<Parent> parentClass = Parent.class;
        Type type1 = parentClass.getGenericSuperclass();
        ParameterizedType param = (ParameterizedType)type1;
        Type[] actualTypeArguments = param.getActualTypeArguments();
        System.out.println(((Class)actualTypeArguments[0]).getName());

        //4.获取实现的接口
        Class<?>[] interfaces = parentClass.getInterfaces();
        for (Class i : interfaces) {
            System.out.println("i = " + i);
        }

        //5.获取所在的包
        Package aPackage = parentClass.getPackage();
        System.out.println("aPackage = " + aPackage);
    }

在这里插入图片描述

调用

1.属性调用

在这里插入图片描述

    public void test7() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        Class<Parent> pc = Parent.class;
        //1.获取运行时类中声明为public的指定属性并设置值
        Field pPub = pc.getField("pPub");
        Parent parent = pc.newInstance();
        pPub.set(parent,"公共变量");
        System.out.println(parent);

        //2.获取运行时类中的指定属性并设置值
        Field age = pc.getDeclaredField("age");
        age.setAccessible(true);//必须设置,不然访问不了private
        age.set(parent,22);
        System.out.println(parent);
    }

在这里插入图片描述

2.方法调用

在这里插入图片描述
在这里插入图片描述

    public void test8() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        Class<Parent> pc = Parent.class;
        //1.调用无返回值方法
        Parent parent = pc.newInstance();
        Method show = pc.getMethod("show");
        show.invoke(parent);
        //2.调用返回值方法
        Method toString = pc.getMethod("toString");
        Object invoke = toString.invoke(parent);
        System.out.println("invoke = " + invoke);
        //3.调用静态方法
        Method printSta = pc.getMethod("printSta");
        printSta.invoke(pc);
        //4.调用私有方法
        Method printPri = pc.getDeclaredMethod("printPri");
        printPri.setAccessible(true);
        Object invoke1 = printPri.invoke(parent);
        System.out.println("invoke1 = " + invoke1);
    }

在这里插入图片描述

后续继续更新…

参考:
反射—Java高级开发必须懂的
Java 反射详解
深入理解Java反射
Java基础之—反射(非常重要)

猜你喜欢

转载自blog.csdn.net/u010247166/article/details/86245888