java反射

1.反射理论

当程序完成编译之后,会在堆内存的方法区中生成一个Class对象,该对象包含了类的所有信息,我们可以通过该对象操作类在运行时的属性、行为。

2.类的加载

2.1类的生命周期

加载---->验证---->准备---->解析---->初始化---->使用----->卸载

2.2类加载器Classloader

2.2.1类加载器的分类

类加载器分为

  1. 启动类加载器(也叫根类加载器)Bootstrap Classloader
  2. 扩展类加载器
  3. 应用程序类加载器
  4. 自定义类加载器

启动类加载器:
由c/c++实现,我们是无法访问的,主要加载rt.jar文件下的class文件或者sun.boot.class.path路径下的内容。

扩展类加载器:
负责加载Java的扩展库JAVA_HOME/jre/lib/ext/*.jar或者java.ext.dirs路径下的内容。

应用程序类加载器:
加载我们自己编写的java文件产生的class文件

自定义类加载器:
用户自己定义的类加载器,用于满足一些特殊需求

获取类加载器:

/*
@author   Nian
@Date     2022/8/12 14:08
@purpose  
          
@Note     two method to get ClassLoader
*/
public class GetClassLoader {
    public static void main(String[] args) {
        //1.
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println("systemClassLoader = " + systemClassLoader);
        //2.
        ClassLoader classLoader = Person.class.getClassLoader();
        System.out.println("classLoader = " + classLoader);
    }
}

2.2.2类加载机制

类的加载机制为双亲委派机制
如下图:
在这里插入图片描述
双亲委派机制的大体意思就是:
我们在加载一个类的时候,不管能不能加载都会将加载任务一直向上委派,如果上面的加载不了再往回委派,最终回到可以加载这个类的类加载器。

3.Class类

官方文档:
在这里插入图片描述
Calss类常用方法解释:
getField:获取指定常用类属性
getDeclareFields:获取全部常用类属性
getMethod:获取指定类方法
getDeclareMethods:获取全部类方法
getDeclareConstructor:获取指定类的构造方法
getDeclareConstructors:获取全部类的构造方法

3.1获取Class对象的四种方式:

/*
@author   Nian
@Date     2022/8/12 10:07
@purpose  four method to get class
          
@Note     
*/
public class GetClass {
    private String name;
    public static void main(String[] args) throws NoSuchFieldException {
        //1.
        Class<Person> personClass = Person.class;
        System.out.println("method1 = " + personClass);

        //2.get class by class instance
        Person person = new Person();
        Class<? extends Person> aClass = person.getClass();
        System.out.println("method2 = " + aClass);

        //3.get class by Class static method forName(),forName need the class path
        try {
            Class<?> aClass1 = Class.forName("com.etime.reflect.getclassinfo.Person");
            System.out.println("method3 = " + aClass1);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //4.get class by classloader
        //get classloader have two method :(1)ClassLoader.getSystemClassLoader()      (2)youClass.class.getClassLoader
        //(1)
        try {
            Class<?> aClass1 = ClassLoader.getSystemClassLoader().loadClass("com.etime.reflect.getclassinfo.Person");
            System.out.println("method4.1 = " + aClass1);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //(2)
        try {
            Class<?> aClass1 = Person.class.getClassLoader().loadClass("com.etime.reflect.getclassinfo.Person");
            System.out.println("method4.2 = " + aClass1);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    class InnerClass{

    }
}

4.反射的使用

目标类:


import java.io.Serializable;

/*
@author   Nian
@Date     2022/8/12 11:34
@purpose  
          
@Note     
*/
public class Person implements Serializable {
    private String name;
    private String idCard;
    private int age;

    public Person(){

    }

    private Person(String name, String idCard, int age){
        this.name = name;
        this.idCard = idCard;
        this.age = age;
    }

    private Person(int age){

    }

    public String getName() {
        return name;
    }

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

    private String getIdCard() {
        return idCard;
    }

    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }

    private int getAge() {
        return age;
    }

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

    private void emo(String s){
        System.out.println(s+"emo");
    }

    private static int add() throws ArithmeticException{
        return 0;
    }

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

4.1获取类的全限定名称以及所在包的名字
/*
@author   Nian
@Date     2022/8/12 15:04
@purpose  
          
@Note     
*/
public class FullyQualifiedNameAndPackage {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        //get full qualified name
        String name = personClass.getName();
        System.out.println("name = " + name);

        //get package name
        Package aPackage = personClass.getPackage();
        System.out.println("aPackage = " + aPackage);
        String name1 = aPackage.getName();
        System.out.println("name1 = " + name1);
    }
}

4.2获取类的基本信息

import java.lang.reflect.Modifier;

/*
@author   Nian
@Date     2022/8/18 18:59
@purpose  get class's modifiers,super class,
          
@Note     
*/
public class getClassBasicInfo {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        //get class's modifiers,like public,static,final and so on
        int modifiers = personClass.getModifiers();     //it return a int type data
        String string = Modifier.toString(modifiers);   //get modifier String by use Modifier class's toString method
        System.out.println(string);
        System.out.println(modifiers);
        //judge this class isPublic
        boolean aPublic = Modifier.isPublic(modifiers);//like method isPublic in class Modifier is have isPrivate,isFinal...
        System.out.println(aPublic);
        System.out.println("--------------------------");

        //get class's super class
        Class<? super Person> superclass = personClass.getSuperclass();
        System.out.println(superclass);
        System.out.println("---------------------------\n");

        //gets interfaces implemented by Person class
        Class<?>[] interfaces = personClass.getInterfaces();
        for(Class<?> i : interfaces){
            System.out.println(i);
        }
    }
}

4.3获取并操作类的属性


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

/*
@author   Nian
@Date     2022/8/18 19:29
@purpose  
          
@Note     
*/
public class GetFields {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;

        //get public field
        Field[] fields = personClass.getFields();
        for(Field field : fields){
            System.out.println(field.getName());
            Class<?> type = field.getType();    //get field type
            System.out.println(type);
        }
        PrintLine.printLine();

        //get all field
        Field[] declaredFields = personClass.getDeclaredFields();
        for(Field field : declaredFields){
            System.out.println(field.getName());
        }
        PrintLine.printLine();


        //get field modifiers
        for(Field field : declaredFields){
            int modifiers = field.getModifiers();
            System.out.print(field.getName() + ":");
            System.out.println(Modifier.toString(modifiers));
        }
        PrintLine.printLine();


        //access class fields and get or set field value
        try {
            //use constructor new a instance(this knowledge point is at getConstructor)
            Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class, String.class, int.class);
            declaredConstructor.setAccessible(true);
            Person person = declaredConstructor.newInstance("王五", "5303", 19);
            //get field
            Field field = personClass.getDeclaredField("name");
            //get field value
            field.setAccessible(true);
            Object o = field.get(person);
            System.out.println(o);          //王五

            //set field value
            field.set(person, "赵四");
            System.out.println(person);     //Person{name='赵四', idCard='5303', age=19}
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

4.4获取并操作类的方法

4.4.1 获取并操作类的普通方法

import java.lang.reflect.Method;

/*
@author   Nian
@Date     2022/8/18 21:09
@purpose  
          
@Note     
*/
public class GetMethod {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;

        //get all declared method
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for(Method method : declaredMethods){
            System.out.println(method.getName());
            //get method parameter types,name,exception types,return type,modifiers
            //here just get exception type and return type,because others is got in getConstructor,they are same
            //get exception types
            Class<?>[] exceptionTypes = method.getExceptionTypes();
            for(Class<?> exception: exceptionTypes){
                System.out.println(exception.getName());
            }
            //get return type
            Class<?> returnType = method.getReturnType();
            System.out.println(returnType.getName());
        }

        //get specified method and invoke this method
        try {
            //get a specified method need this method name and it's parameters type
            Method emo = personClass.getDeclaredMethod("emo",String.class);
            emo.setAccessible(true);
            Person person = personClass.newInstance();
            //ues method invoke() to let this method run,invoke() method need a class object
            //and parameter if it have parameter,and the class object is this method included class's object
            emo.invoke(person,"oh~~~~");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.4.2 获取并操作类的构造方法


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

/*
@author   Nian
@Date     2022/8/18 19:43
@purpose  get Constructor object by Class class object
          
@Note     if want to get Constructor object that constructor is private,need use method getDeclaredConstructor
*/
public class GetConstructor {
    public static void main(String[] args) {
        Class<Person> personClass = Person.class;
        //get public constructors
        Constructor<?>[] constructors = personClass.getConstructors();  //this method just get public constructor
        for(Constructor<?> constructor : constructors){
            constructor.setAccessible(true);        //let this construct can accessible
            System.out.println(constructor.isAccessible());
            System.out.println("constructor:" + constructor.getName());

            //get constructor modifiers
            int modifiers = constructor.getModifiers();
            System.out.println("modifiers:" + Modifier.toString(modifiers));

            //get constructor parameter types
            Class<?>[] parameterTypes = constructor.getParameterTypes();
            System.out.print("parameterTypes: ");
            for(Class<?> type : parameterTypes){
                System.out.print(type.getName() + "\t");
            }
            System.out.println("\n");
        }

        //get Constructor object which constructor have parameter then
        // use this Constructor object construct class instance
        try {
            Constructor<Person> declaredConstructor =
                    personClass.getDeclaredConstructor(String.class, String.class, int.class);
            declaredConstructor.setAccessible(true);    //if not cancel security check,this constructor can't use
            Person person = declaredConstructor.newInstance("王五","142525",18);
            System.out.println(person.getName());
        } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

4.4解析类的注解

目标类:


/*
@author   Nian
@Date     2022/8/21 15:16
@purpose  
          
@Note     
*/

import java.lang.annotation.*;

@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD,ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String author();
}



/*
@author   Nian
@Date     2022/8/21 15:21
@purpose  
          
@Note     
*/
@MyAnnotation(author = "念")
public class MyClass {

}

测试类:

/*
@author   Nian
@Date     2022/8/21 15:26
@purpose  
          
@Note     
*/
public class GetAnnotationInfoTest {
    public static void main(String[] args) {
        Class<MyClass> myClassClass = MyClass.class;
        //judge class is use an annotation
        boolean isAnnotationPresent = myClassClass.isAnnotationPresent(MyAnnotation.class);
        System.out.println(isAnnotationPresent);       //true
        if(isAnnotationPresent){
            MyAnnotation annotation = myClassClass.getAnnotation(MyAnnotation.class);
            //get annotation field value
            String author = annotation.author();
            System.out.println(author);     //念
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

念犯困

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

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

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

打赏作者

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

抵扣说明:

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

余额充值