java基础——反射常用操作

首先定义一些类和接口

package reflection1;

public interface MtInterface {
    void info();
}
package reflection1;

import java.io.Serializable;

public class Creature<T> implements Serializable {
    private char gender;
    public double weight;
    
    
    
    public Creature() {
        super();
    }
    private void breath() {
        System.out.println("呼吸");
    }
    public void eat() {
        System.out.println("吃饭");
    }
}
package reflection1;


public class Person extends Creature<String> implements Comparable<String>,MtInterface {
    
    private String name;
    int age;
    public int id;
    
    public Person() {
        super();
    }
    private Person(String name) {
        super();
        this.name = name;
    }
    Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person(String name, int age, int id) {
        super();
        this.name = name;
        this.age = age;
        this.id = id;
    }
    
    private String show(String nation) throws Exception{
        System.out.println("nation="+nation);
        return nation;
    }
    public String display(String interests) {
        return interests;
    }
    
    @Override
    public void info() {
        System.out.println("我是人");
    }

    @Override
    public int compareTo(String o) {
        return 0;
    }
    
    private static void showDesc() {
        System.out.println("static method");
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", id=" + id + "]";
    }
    
}

反射获取运行时类的属性

package reflection2;

import java.lang.reflect.Field;

import org.junit.jupiter.api.Test;

import reflection1.*;

/*
 * 获取当前运行时类的属性结构
 * */

public class FieldTest {
    @Test
    public void test1() {
        Class clazz = reflection1.Person.class;
        Field [] fields = null;
        
        //获取属性结构
        //getFields():获取当前运行时类及其父类中所有public的属性
        fields = clazz.getFields();
        for(Field f:fields)
            System.out.println(f);
        
        System.out.println("");
        
        //getDeclaredFields():获得当前运行时类的所有属性,不包含父类的属性,不考虑权限
        fields = clazz.getDeclaredFields();
        for(Field f:fields)
            System.out.println(f);
        
        System.out.println("");
    }
    
    //权限修饰符:数据类型 变量名
    @Test
    public void test2() {
        Class clazz = reflection1.Person.class;
        Field [] fields = clazz.getDeclaredFields();
        for(Field f:fields) {
            System.out.println(f);
            /*
             *
             * 1.权限修饰符
             *  PUBLIC: 1
                PRIVATE: 2
                PROTECTED: 4
                STATIC: 8
                FINAL: 16
                SYNCHRONIZED: 32
                VOLATILE: 64
                TRANSIENT: 128
                NATIVE: 256
                INTERFACE: 512
                ABSTRACT: 1024
                STRICT: 2048
             * */
            int modifiers = f.getModifiers();
            System.out.println(modifiers);
            
            //2.数据类型
            Class type = f.getType();
            System.out.println(type);
            
            //3.变量名
            String name = f.getName();
            System.out.println(name);
            
            System.out.println("");
        }
    }
}

反射获得运行时类的方法

package reflection2;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.junit.jupiter.api.Test;

import reflection1.Person;

/*
 * 获取运行时类的方法结构
 * 
 * */

public class MethodTest {
    @Test
    public void test1() {
        Class clazz = Person.class;
        //getMethods():获取当前类及其父类所有public方法
        Method[] methods = clazz.getMethods();
        for(Method m:methods) {
            System.out.println(m);
        }
        System.out.print('
');
        
        //获取当前运行时类中的所有方法
        methods = clazz.getDeclaredMethods();
        for(Method m:methods) {
            System.out.println(m);
        }
    }
    /*
     * 权限修饰符,返回值类型,方法名(参数类型1   参数1,参数类型2  参数2,参数类型3  参数3...)
     * */
    @Test
    public void test2() {
        //1.获取方法声明的注解
        Class clazz = Person.class;
        Method[]methods = clazz.getDeclaredMethods();
        for(Method m:methods) {
            System.out.println(m);
            //1.获得方法声明的注解
            Annotation[] annos = m.getAnnotations();
            for(Annotation a:annos) {
                System.out.println("注解:"+a);
            }
            
            //2.获取权限修饰符
            int modifier = m.getModifiers();
            System.out.println("权限:"+modifier);
            
            //3.返回值类型
            System.out.println("返回值类型:"+m.getReturnType().getName());
            
            //4.方法名
            System.out.println("方法名字:"+m.getName());
            
            //5.形参列表
            Class [] parameterTypes = m.getParameterTypes();
            if(!(parameterTypes == null && parameterTypes.length==0)) {
                System.out.println("形参列表:");
                for(int i=0;i<parameterTypes.length;i++) {
                    Class p = parameterTypes[i];
                    System.out.println(p.getName()+" args_"+i);
                }
            }
            
            //6.抛出的异常
            Class [] exceptionTypes = m.getExceptionTypes();
            for(Class e:exceptionTypes)
                System.out.println("异常:"+e.getName());
            
            System.out.println("");
        }
    }
    
}

反射获得运行时类的构造器,父类,泛型信息,接口,包等信息

package reflection2;

import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;

import reflection1.Person;

public class OtherTest {
    /*
     * 获取构造器结构
     * */
    @Test
    public void test1() {
        Class clazz = Person.class;
        //获得public的构造器(无父类)
        Constructor[] constructors = clazz.getConstructors();
        for(Constructor c:constructors)
            System.out.println(c);
        
        System.out.println();
        
        //获得所有构造器
        constructors = clazz.getDeclaredConstructors();
        for(Constructor c:constructors)
            System.out.println(c);
    }
    /*
     * 获取运行时类的父类
     * */
    @Test
    public void test2() {
         Class clazz = Person.class;
         Class superClass = clazz.getSuperclass();
         System.out.println(superClass);
         
    }
    
    /*
     * 获取运行时带泛型的父类
     * */
    @Test
    public void test3() {
         Class clazz = Person.class;
         Type superClass = clazz.getGenericSuperclass();
         System.out.println(superClass);
         
    }
    /*
     * 获取运行时带泛型的父类的泛型
     * 关于ParameterizedType的理解
     *     https://www.jianshu.com/p/da21b3a59b47 定义
     *     https://www.jianshu.com/p/cfa74c980b25 理解
     * */
    @Test
    public void test4() {
         Class clazz = Person.class;
         Type superClass = clazz.getGenericSuperclass();
         ParameterizedType paramType = (ParameterizedType)superClass;
         //getActualTypeArguments()可以去掉最外面一层<>获得里面的Type数组
         Type[] types = paramType.getActualTypeArguments();
         System.out.println(types[0].getTypeName());
    }
    
    /*
     * 获取运行时类的接口
     * */
    @Test
    public void test5() {
        Class clazz = Person.class;
        Class[] interfaces = clazz.getInterfaces();
        for(Class c:interfaces)
            System.out.println(c);
        
        System.out.println();
        Class[] interfaces1 = clazz.getSuperclass().getInterfaces();
        for(Class c:interfaces1)
            System.out.println(c);
    }
    
    /*
     * 获取类运行时所在包
     * */
    @Test
    public void test6() {
        Class clazz = Person.class;
        Package package1 = clazz.getPackage();
        System.out.println(package1);
    }
}

反射调用运行时类的属性,方法,构造器(反射打破封装性)

package reflection2;


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

import org.junit.jupiter.api.Test;

import reflection1.Person;

/*
 * 调用运行时类中指定的结构:属性,方法,构造器
 * */

public class ReflectionTest {
    
    /*
     * 反射调类属性
     * 
     * */
    @Test
    public void test1() 
            throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException 
    {
        Class clazz = Person.class;
        
        //创建运行时类对象
        Person person = (Person)clazz.newInstance();
        
        //获取指定变量名的属性
        Field name = clazz.getDeclaredField("name");
        
        //将该属性权限修改为可获得
        name.setAccessible(true);
        
        //设置当前对象的属性值:set()方法:参数1:指明设置哪个对象的属性,参数2:将属性设置为多少
        name.set(person, "Tom");
        
        /*
         * 获取当前属性值get():参数1:获取哪个对象的属性值
         * */
        Field age = clazz.getDeclaredField("age");
        age.setAccessible(true);
        int pAge = (int)age.get(person);
        System.out.println(pAge);
        
        name.setAccessible(false);//还要再改回去
    }
    
    /*
     * 操作运行时类中指定的方法
     * */
    @Test
    public void test2() 
            throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException 
    {
        Class clazz = Person.class;
        
        //创建运行时类对象
        Person person = (Person)clazz.newInstance();
        
        //获取指定的某个方法
        //参数1:指明获取方法的名称,参数2:指明获取方法的形参列表
        Method show = clazz.getDeclaredMethod("show", String.class);
        
        //将权限改为可访问
        show.setAccessible(true);
        
        //invoke():参数1:方法调用者 参数2:给方法形参赋值的实参
        //返回值 为调用的方法的返回值
        String nation = (String)show.invoke(person,"CHN");
        System.out.println(nation);
        
        
        System.out.println("*********************调用静态方法**********************");
        //得到这个方法的步骤是一样的
        Method showDesc = clazz.getDeclaredMethod("showDesc");
        showDesc.setAccessible(true);
        //由于是静态,直接用这个类去调用就行
        showDesc.invoke(Person.class);
    }
    
    /*
     * 调用运行时类的指定的构造器
     * */
    @Test
    public void test3() 
            throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException 
    {
        Class clazz = Person.class;
        
        //获取指定的构造器:参数:指明构造器的参数列表
        Constructor constructor = clazz.getDeclaredConstructor(String.class);
        
        //将权限改为可访问
        constructor.setAccessible(true);
        
        Person person = (Person)constructor.newInstance("Tom");
        System.out.println(person);
    }
    
}
原文地址:https://www.cnblogs.com/zsben991126/p/12156958.html