反射:获取成员变量,构造方法,类的使用。

反射:将类的各个组成部分封装为其他对象。

好处:
1、可以在运行过程中,操作这些对象
2、可以解耦,提高程序的可扩展性

要对反射有一个比较深刻的理解,首先要了解Java代码在计算机中经历的三个阶段
在这里插入图片描述

一、获取Class对象的三种方式

1、Class.forName(“包名.类名”):
    将字节码文件加载进内存,返回Class对象(编译阶段)
2、类名.class:
    通过类名的属性class获取  (类加载阶段)
3、对象.getClass():
    getClass()方法在Object类中定义  (RunTime运行阶段)
public static void main(String[] args) throws Exception {
    //1、Class.forName(“包名.类名”)
    Class cls = Class.forName("com.csx.bean.Person");
    System.out.println(cls); //class com.csx.bean.Person
    //2、类名.class
    Class cls2=Person.class;
    System.out.println(cls2);//class com.csx.bean.Person
    //3、对象名.getClass()
    Person p=new Person();
    Class cls3=p.getClass();
    System.out.println(cls3);//class com.csx.bean.Person
    //==比较三个对象,三种获得的Class是一样的
    System.out.println(cls==cls2);//true 
    System.out.println(cls==cls3);//true
    //不同的Class是不一样的
    Class c= Student.class;
    System.out.println(c==cls); //false
}

二、获取成员变量们

1、获取成员变量们
Field[] getFields()   获取public修饰的,所有成员变量
Field getField(String name)  获取获取public修饰的,指定的成员变量
Field[] getDeclaredFields()  获取所有的成员变量,忽略修饰符
Field getDeclaredField(String name)

setAccessible(true)方法 设置为true表示可以访问其中的私有变量,(变量,构造器,方法都可以设置此方法)

public static void main(String[] args) throws Exception {
        //使用第一种方式,在编译阶段获取Class对象
        Class cls = Class.forName("com.csx.bean.Person");
        //获取成员变量们 只能获取public修饰的成员变量
        Field[] fields = cls.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        //获取指定的成员变量 只能获取public修饰的,指定的成员变量
        Field field = cls.getField("a");
        System.out.println(field);
        System.out.println("--------------------------------------");
        //获取成员变量,忽略修饰符
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

        //获取指定的成员变量,忽略修饰符
        Field d = cls.getDeclaredField("d");
        System.out.println(d);
        //利用反射为私有的成员变量赋值
        d.setAccessible(true); //设置为true表示可以访问其中的私有变量
        Person person = new Person();
        d.set(person,"张三");  //设置值
        Object value = d.get(person); //获取值
        System.out.println(value);
       
        String name = d.getName();  //获取成员变量名字
        System.out.println(name);
    }

三、获取构造方法们

2、获取构造方法们
    Constructor<?>[] getConstructors() 获取public修饰的,所有构造方法
    Constructor<T> getConstructor(类<?>... parameterTypes) 获取public修饰的指定的构造方法
    Constructor<?>[] getDeclaredConstructors()  获取所有构造方法,忽略修饰符
    Constructor<T> getDeclaredConstructor(类<?>... parameterTypes) 获取指定的构造方法,忽略修饰符
public static void main(String[] args) throws Exception {
       //使用第二种方式,在类加载阶段获取Class对象
        Class cls = Person.class;

        //获取构造方法们
        Constructor[] constructors = cls.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

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

        //获取指定的构造方法
        //获取指定的构造方法,需要传入构造方法对应位置数据类型的class
        Constructor constructor = cls.getConstructor(String.class,int.class);
        System.out.println(constructor);

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

        //用获取的构造方法创建对象
        Object person1 = constructor.newInstance("张三",23);
        System.out.println(person1);

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

        //如果获取的是默认的构造方法,简便方式
        Object pserson2 = cls.newInstance();
        System.out.println(pserson2);
    
        String name = constructor.getName(); //获取构造方法的全限定类名
        System.out.println(name);
    }

四、获取成员方法们

3、获取成员方法们
Method[] getMethods() 获取所有public修饰的方法,包括Object类的
Method getMethod(String name, 类<?>... parameterTypes)  获取public修饰的指定的方法
Method [] getDeclaredMethods()  获取所有方法,忽略修饰符
Method getDeclaredMethod(String name, 类<?>... parameterTypes) 获取指定的方法,忽略修饰符

4、获取类名
String getName() 
public static void main(String[] args) throws Exception {
        //用第三种方式,在运行阶段获取Class类
        Person person = new Person();
        Class cls = person.getClass();
        //2、获取指定名称的方法
        Method sleep = cls.getMethod("sleep");
        Person p=new Person();
        sleep.invoke(p);
        Method sleep2=cls.getMethod("sleep", String.class);
        sleep2.invoke(p,"饭");

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

        //获取所有public修饰的方法
        Method[] methods=cls.getMethods();
        for(Method method:methods){
            System.out.println(method);
            //获取方法的名字,包括Object类的public修饰的方法
            String name=method.getName(); 
            System.out.println(name);
        }
        //获取类名
        String className=cls.getName();
        System.out.println(className);
    }

获取成员方法的运行结果
在这里插入图片描述
在这里插入图片描述
今天看到的一个另外的用法,反射机制可以绕过泛型的检查

public class TestfansheArray {

	public static void main(String[] args) throws Exception {
		ArrayList<String> list = new ArrayList<String>();

		list.add("张三");
		list.add("李四");

		Class cls = list.getClass();
		Method m = cls.getMethod("add", Object.class);
		m.invoke(list, 1);
		for (Object s : list) {
			System.out.println(s);
		}

	}

}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值