java反射运用详解

java反射运用详解,第1张

通过反射来:获取当前运行时类的属性结构,运行时类的方法结构

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

首先我们创建一个实体类Person来演示,同时我们要给Person类疯狂加buff

自定义注解:
package com.atguigu.java1;

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;

/**
 * @author ***
 * @create 2022-05-14 9:20
 */
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "hello";
}
Person父类:Creature
package com.atguigu.java1;

import java.io.Serializable;

/**
 * @author ***
 * @create 2022-05-14 9:10
 */
public class Creature implements Serializable {
    private char gender;
    public double weight;

    private void breath(){
        System.out.println("生物呼吸");
    }
    public void eat(){
        System.out.println("生物吃东西");
    }
}
MyInterface接口:
package com.atguigu.java1;

/**
 * @author ***
 * @create 2022-05-14 9:14
 */
public interface MyInterface {
    void info();
}
 
Person类: 
package com.atguigu.java1;

/**
 * @author ***
 * @create 2022-05-14 9:09
 */
@MyAnnotation(value = "hi")
public class Person extends Creature implements Comparable,MyInterface{
    private String name;
    int age;
    public int id;

    public Person() {
    }

    @MyAnnotation(value = "abc")
    private Person(String name) {
        this.name = name;
    }

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

    @MyAnnotation
    private String show(String nation){
        System.out.println("我的国籍是:" + nation);
        return nation;
    }

    public String display(String interests){
        return interests;
    }

    @Override
    public int compareTo(String o) {
        return 0;
    }

    @Override
    public void info() {
        System.out.println("我是一个人");
    }

    private static void showDesc(){
        System.out.println("我是一个可爱的人");
    }
}
 
获取当前运行时类的属性结构: 
package com.atguigu.java2;

import com.atguigu.java1.Person;
import org.junit.Test;

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

/**
 * 获取当前运行时类的属性结构
 *
 * @author ***
 * @create 2022-05-14 9:26
 */
public class FieldTest {
    @Test
    public void test1(){
        Class clazz = Person.class;

        //获取属性结构
        //getFields():获取当前运行时类及其父类所有public的属性
        Field[] fields = clazz.getFields();
        for(Field f : fields){
            System.out.println(f);
        }

        System.out.println("```````````````");

        //getDeclaredFields():获取当前运行时类中所有的属性,不考虑权限(不考虑父类中的属性)
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field f : declaredFields){
            System.out.println(f);
        }
    }
    //权限修饰符 数据类型 变量名
    @Test
    public void test2(){
        Class clazz = Person.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field f : declaredFields){
            //1.权限修饰符
            int modifier = f.getModifiers();
            System.out.print(Modifier.toString(modifier) + "\t");

            //2.数据类型
            Class type = f.getType();
            System.out.print(type.getName() + "\t");

            //3.变量名
            String fName = f.getName();
            System.out.print(fName);


            System.out.println();
        }
    }
}

运行时类的方法结构:
package com.atguigu.java2;

import com.atguigu.java1.Person;
import org.junit.Test;

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

/**
 * 运行时类的方法结构
 *
 * @author ***
 * @create 2022-05-14 9:44
 */
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.println("``````````````");

        //getDeclaredMethods()获取当前运行时类中所有的方法,不考虑权限(不考虑父类中的方法)
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method m : declaredMethods){
            System.out.println(m);
        }
    }

    /*
    @Xxxx
    权限修饰符 返回值 方法名(参数1,参数2....)throws XxxException
     */
    @Test
    public void test2(){
        Class clazz = Person.class;
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method m : declaredMethods){
            //1.获取方法声名的注解
            Annotation[] annos = m.getAnnotations();
            for(Annotation a : annos){
                System.out.println(a);
            }

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

            //3.返回值类型
            System.out.print(m.getReturnType().getName() + "\t");

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

            //5.形参列表
            System.out.print("(");
            Class[] parameterTypes = m.getParameterTypes();
            if(!(parameterTypes == null && parameterTypes.length == 0)){
                for (int i = 0;i < parameterTypes.length;i++){
                    System.out.print(parameterTypes[i].getName() + "args_" + i);
                }
            }
            System.out.print(")");

            //6.抛出异常
            Class[] exceptionTypes = m.getExceptionTypes();
            if(!(exceptionTypes == null && exceptionTypes.length == 0)){
                System.out.println("throws");
                for(int i = 0 ; i < exceptionTypes.length ; i++){
                    System.out.println(exceptionTypes[i].getName());
                }
            }

            System.out.println();
        }

    }
}

其他(获取构造器,获取运行时类的父类,获取运行时类的带泛型父类,获取运行时类的带泛型父类的泛型,获取运行时类实现的接口,获取运行时类所在的包,获取运行时类声名的注解,):
package com.atguigu.java2;

import com.atguigu.java1.Person;
import org.junit.Test;

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

/**
 * @author ***
 * @create 2022-05-14 10:11
 */
public class OtherTest {
    /*
    获取构造器
     */
    @Test
    public void test1(){
        Class clazz = Person.class;
        //getConstructors():获取当前运行时类中public的构造器
        Constructor[] constructors = clazz.getConstructors();
        for(Constructor c : constructors){
            System.out.println(c);
        }
        System.out.println();

        //getDeclaredConstructors():获取当前运行时类中所有的构造器
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for(Constructor c : declaredConstructors){
            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 genericSuperclass = clazz.getGenericSuperclass();
        System.out.println(genericSuperclass);
    }

    /*
    获取运行时类的带泛型父类的泛型
     */
    @Test
    public void test4(){
        Class clazz = Person.class;

        Type genericSuperclass = clazz.getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) genericSuperclass;
        //获取泛型类型
        Type[] actualTypeArguments = paramType.getActualTypeArguments();
        System.out.println(actualTypeArguments[0].getTypeName());
    }

    /*
    获取运行时类实现的接口
     */
    @Test
    public void test5(){
        Class clazz = Person.class;
        Class[] interfaces = clazz.getInterfaces();
        for(Class i : interfaces){
            System.out.println(i);
        }
    }

    /*
    获取运行时类所在的包
     */
    @Test
    public void test6(){
        Class clazz = Person.class;

        Package aPackage = clazz.getPackage();
        System.out.println(aPackage);
    }

    /*
    获取运行时类声名的注解
     */
    @Test
    public void test7(){
        Class clazz = Person.class;

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

*** 作运行时类指定的属性和方法,调用运行时类中的指定的构造器:
package com.atguigu.java2;

import com.atguigu.java1.Person;
import org.junit.Test;

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

/**
 * 调用运行时类中指定的结构:属性,方法,构造器
 *
 * @author ***
 * @create 2022-05-14 10:34
 */
public class ReflectionTest {
    /*

     */
    @Test
    public void test1() throws Exception {
        Class clazz = Person.class;
        
        //创建运行时类的对象
        Person person = (Person) clazz.newInstance();

        //获取指定的属性:要求运行时类属性声名为public
        Field id = clazz.getField("id");

        //设置当前属性的值
        id.set(person,1001);

        //获取当前属性的值
        int pId = (int)id.get(person);
        System.out.println(pId);
    }

    /*
    如何 *** 作运行时类指定的属性
     */
    @Test
    public void test2() throws Exception {
        Class clazz = Person.class;

        //创建运行时类的对象
        Person person = (Person) clazz.newInstance();

        //获取指定的属性
        Field name = clazz.getDeclaredField("name");

        //保证当前属性是可访问的
        name.setAccessible(true);

        name.set(person,"Tom");

        System.out.println(name.get(person));
    }

    /*
    如何 *** 作运行时类指定的方法
     */
    @Test
    public void test3() throws Exception {
        Class clazz = Person.class;
        //创建运行时类的对象
        Person p = (Person)clazz.newInstance();

        /*
        获取指定的方法
        getDeclaredMethod():
            参数1:指明获取的方法名
            参数2:指明获取的方法的参数列表
         */
        Method show = clazz.getDeclaredMethod("show", String.class);

        //保证当前方法是可访问的
        show.setAccessible(true);

        /*
        invoke():
            参数1:方法的调用者
            参数2:给方法形参赋值的实参
        invoke()方法的返回值即为对应类中调用的方法的返回值
         */
        Object chn = show.invoke(p, "CHN");
        System.out.println(chn);

        System.out.println("***********************如何调用静态方法*************");
        Method showDesc = clazz.getDeclaredMethod("showDesc");
        showDesc.setAccessible(true);
        showDesc.invoke(Person.class);
    }

    /*
    如何调用运行时类中的指定的构造器
     */
    @Test
    public void test4() throws Exception {
        Class clazz = Person.class;
        //1.获取指定构造器
        Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);

        //2.保证可访问
        declaredConstructor.setAccessible(true);

        //3.调用此构造器创建运行时类对象
        Person person = (Person)declaredConstructor.newInstance("Tom");
    }
}
					
										


					

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/921410.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存