【浅学Java的反射机制】


前言

早在学习Java基础部分就听过,了解过反射这个概念,但是它的具体作用和使用方法没有很明白。刚好最近在学习反射这部分,学完后有了点自己的想法。如下:


一、反射是什么?

概念:反射是Java的一种机制,让我们可以在运行时就能够获取类的信息。

二、作用

在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;它是一种动态获取的信息和动态调用对象的方法的机制。

三、使用方法

1.获取class对象

举例代码:

package com.etime.reflex.demo;
//学生类
public class Student {
	private String name;
	private String sid;
	private int age;
	//后面的get/set等省略
	
	....
	
package com.etime.reflex.demo;
public class GetClazz {
	public static void main(String[] args) {
		//获取class对象的三种方式
		Student stu1= new Student ("aa", "123", 12);
		Student stu2= new Student ("bb", "456", 11);

方法一:利用getClass()方法获取对象的class 对象

        //1、利用getClass()方法获取对象的class 对象
		Class c1 = stu1.getClass();
		Class c2 = stu2.getClass();
		System.out.println(c1==c2);

方法二:利用类名.class这种获取方式只有在编译前已经声明了该类的类型才能获取到 Class 对象

        //2、利用class属性获取字节码文件(
		//类.class:需要输入一个明确的类,任意一个类型都有一个静态的class属性)
		Class c3 = Student.class;
		System.out.println(c1==c3);

方法三:利用Class.forName()获取–最常用的方式

        //3、利用Class.forName()获取--最常用的方式
		//通过Class类的一个forName(String className)静态方法返回一个Class对象,
		//className必须是全路径名称;
		//Class.forName()有异常:ClassNotFoundException,这里没抛
	    Class c4 = Class.forName("com.etime.reflex.demo.Student");

2.通过反射实例化对象

方法一:Class 对象调用newInstance()方法

            Object obj = c3.newInstance();
 //一般这个Object要转换为对应的具体对象即 Student obj = (Student)c3.newInstance();强转一下
			System.out.println(obj.toString())

注意:通过Class对象的newInstance()方法来创建Class对象对应类的实例。这个方法是使用Class对象对应类的默认构造器创建对象,这就要求Class对象对应类必须要有默认构造器(无参数的构造方法)。

方法二:调用Constructor对象的newInstance()方法来创建Class对象对应类的方法

Constructor construct =c3.getConstructor(String.class,String.class,int.class);
			Object obj = construct.newInstance("cc","567",13);
			System.out.println(obj.toString());

注意:调用Constructor对象的newInstance()方法来创建Class对象。这个方法当Class对象有默认构造器(无参构造方法)时,仍可以使用,把getConstructor()的参数不写即可。

3.通过反射获取类的所有信息

方法一:Field:反编译一个类的属性

        //获取class对象
		Class c1 = Class.forName("com.etime.reflex.demo.Student");
		//反射创建类的实例
		Student stu= (Student) c1.newInstance();	
		//获取公有属性
		Field[] fileds = c1.getFields();
		for(Field f :fileds){
			System.out.println("公有属性:"+f.getName());
		}
		//获取私有属性
		Field[] fileds2 = c1.getDeclaredFields();
		for(Field f :fileds2){
			System.out.println("私有属性:"+f.getName());
		}

注意:
Field[] getFields():获取类中所有被public修饰的所有变量
Field[] getField(String name):根据变量名获取类中的一个变量,该变量必须被public修饰
Field[] getDeclaredFields():获取类中所有的变量,但无法获取继承下来的变量
Field[] getDeclaredField(String name):根据姓名获取类中的某个变量,无法获取继承下来的变量

方法二:Method:获取类中的方法

Class c2= Class.forName("com.etime.reflex.demo.Student");
// 创建对象
Object obj = c2.newInstance();
// 获取Method
Method method = c2.getDeclaredMethod();
Object res = method.invoke();//注:方法返回值是void 结果是null
System.out.println(resValues);

注意:
Method[] getMethods():获取类中被public修饰的所有方法

Method getMethod(String name, Class…<?>paramTypes):根据名字和参数类型获取对应方法,该方法必须被public修饰

Method[] getDeclaredMethods():获取所有方法,但无法获取继承下来的方法

Method getDeclaredMethod(String name, Class…<?>paramTypes):根据名字和参数类型获取对应方法,无法获取继承下来的方法

方法三:Constructor:获取类的构造器

Class c2= Class.forName("com.etime.reflex.demo.Student");
Constructor obj1 = c2.getDeclaredConstructor();
Object obj2 = obj.newInstance();
System.out.println(obj2);

注意:
Constuctor[] getConstructors():获取类中所有被public修饰的构造器

Constructor[] getConstructor(Class…<?> paramTypes):根据参数类型获取类中某个构造器,该构造器必须被public修饰

Constructor[] getDeclaredConstructors():获取类中所有构造器

Constructor[] getDeclaredConstructor(class…<?> paramTypes):根据参数类型获取对应的构造器


总结

写的时候感觉自己越写越蒙,特别是和同学们讨论了一下后发现自己还是有很多东西不是很理解。所以我知道我上面所述肯定有很多错误,希望大佬指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值