反射中需掌握

反射

package com.person;

/**
 * @author 21115 @ date 2021/8/25
 */
// 改变值
@MyAnnotation(value = "hi")
public class Person extends Creature<String> implements Comparable<String>, 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, int age) {
        return interests + age;
    }

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

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

    private static void showDesc() {
        System.out.println("我是一个可爱的人");
    }

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

package com.reflection2;

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

import org.junit.Test;

import com.person.Person;

/**
 * @author 21115 @ date 2021/9/3
 */
public class ReflectionTest {

    /**
     * 不需要掌握
     */

    @Test
    public void testField() throws IllegalAccessException, InstantiationException, NoSuchFieldException {
        Class clazz = Person.class;

        // 创建运行时类的对象,此时的 p 是一个地址:com.person.Person@22927a81
        Person p = (Person)clazz.newInstance();

        // 获取指定的属性,要求运行时类中的属性声明为 public
        // 通常不采用此方法
        // 此时 id 为:public int com.person.Person.id
        Field id = clazz.getField("id");

        /**
         * 设置当前属性的值
         * 
         * set():参数1:指明设置哪个对象的属性
         * 
         * 。。。。参数2:将此属性值设置为多少
         */

        id.set(p, 1001);

        /**
         * 获取当前属性的值
         * 
         * get():参数1:获取哪个对象的当前属性值
         */

        int pId = (int)id.get(p);
        // 此时 pId 显示为:1001
        System.out.println(pId);

        /**
         * 
         */

    }

    /**
     * 如何操作运行时类中的指定的属性 -- 需要掌握
     */
    @Test
    public void testField1() throws IllegalAccessException, InstantiationException, NoSuchFieldException {
        Class clazz = Person.class;

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

        // 1.getDeclaredField(String fieldName):获取运行时类中指定变量名的属性
        Field name = clazz.getDeclaredField("name");

        // 2.保证当前属性是可访问的,无论属性是 public,private 都可以加此语句
        // 将 private 属性的变量变成可修改的
        name.setAccessible(true);

        // 3.获取、设置指定对象的此属性值
        name.set(p, "Tom");

        // Tom
        System.out.println(name.get(p));
    }

    /**
     * 如何操作运行时类中的指定的方法 -- 需要掌握
     */
    @Test
    public void testMethod()
        throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class clazz = Person.class;

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

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

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

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

        System.out.println("*** *** *** 如何调用静态方法 *** *** ***");

        // private static void showDesc()

        Method showDesc = clazz.getDeclaredMethod("showDesc");
        showDesc.setAccessible(true);
        // 如果调用的运行时类中的方法没有返回值,则此 invoke() 返回 null
        Object returnVal = showDesc.invoke(Person.class);
        // Object returnVal = showDesc.invoke(null);
        // null
        System.out.println(returnValue);
    }

    /**
     * 如何调用运行时类中的指定的构造器
     */
    @Test
    public void testCConstructor()
        throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class clazz = Person.class;

        // private Person(String name)
        // 1.获取指定的构造器
        // getDeclaredConstructor():参数:指明构造器的参数列表
        Constructor constructor = clazz.getDeclaredConstructor(String.class);

        // 2.保证此构造器是可访问的
        constructor.setAccessible(true);

        // 3.调用此构造器创建运行时类的对象
        Person per = (Person)constructor.newInstance("Tom");
        // Person{name='Tom', age=0, id=0}
        System.out.println(per);
    }
}
/**
 * 1.写出获取 Class 实例的三种常见方法
 * 
 * 。。。Class clazz1 = String.class;
 * 
 * 。。。Class clazz2 = person.getClass();//sout(person);//xxx.yyy.zzz.Person@...
 * 
 * 。。。Class clazz3 = Class.forName(String classPath);//体现反射的动态性
 * 
 * 
 * 2.谈谈你对 Class 类的理解
 * 
 * 。。。Class 实例对应着加载到内容中的一个运行时类
 * 
 * 
 * 3.创建 Class 对应运行时类的对象的通用方法,代码实现。以及这样操作,需要对应的运行类的构造器方面满足要求。
 * 
 * 。。。Object obj = clazz.newInstance()://创建了对应的运行时类的对象
 * 
 * 。。。1.必须有空参的构造器
 * 
 * 。。。2.权限修饰符的权限要够。通常设置为 public
 * 
 * 
 * 4.在工程或 module 的 src 下有名为 "jdbc.properties" 的配置文件,文件内容为:name = Tom。如何在程序中通过代码获取
 * 
 * 5.如何调用方法 show()
 * 
 * ..类声明如下:
 * 
 * package.com.atguigu.java;
 * 
 * class User{
 * 
 * public void show(){
 * 
 * System.out.println("我是一个中国人");
 * 
 * } }
 * 
 * 
 * User user = (User) clazz.newInstance();
 * 
 * Method show = clazz.getDeclaredMethod("show");
 * 
 * show.setAccessiable(true);
 * 
 * show.invoke(user):
 */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值