Java精粹--反射

点此查看全部文字教程、视频教程、源代码

1. 反射的概念

对于一个人来说,了解自己的能力、本事、特点,对于他去干事创业来说,是很重要的。

同样的,对于一门面向对象的语言来说,了解类(对象其实就是类的实现)本身也是重要的,可以在很多地方帮助程序更好的进行。

那么类/对象本身包含那些内容呢,无非就是类名称;父类;继承的接口;类的属性;类的方法,这些都属于是类的信息

好的,那么这些信息程序员都知道啊,类的信息在定义类的时候不是都写的明明白白的吗。但是反射的意义却是:在程序跑起来之后可以使用代码去获取类的信息。这个,没有反射可办不到。

Java是面向对象的,所有的东西都是有类别的。所以哦,类的信息也是一种类型(就像用户信息可以用UserInfo类描述),类的信息对应的Java类为Class类,注意不是关键字class哈。

举个最常见的栗子:

public class ClassDemo {
	public static void main(String[] args) {
		try {
			Class mysqlDriver=Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

这里Class.forName很明显是Class类的一个static方法,这个方法的意思就是按类名(完整的带包路径的类名)返回类对应的Class对象。因为forName的参数是可以随便写的嘛,所以会抛出一个ClassNotFoundException。

Class.forName方法是在程序运行时按类名称获取类的信息的方法,这就是反射机制。

2. 如何获取类的Class对象

我们定义一个普通类Student,可以有三种方式获取到Student的类型信息:

package temp;
public class Student {
	String studentName;
	public String getStudentName(){
		return studentName;
	}
	public static void main(String[] args) throws ClassNotFoundException {
		//方式1 利用类名称
		Class class1 = Class.forName("temp.Student");  
		//方式2 利用类
		Class class2=Student.class;
		//方式3 利用对象
		Student student=new Student();
		Class class3=student.getClass();
	}
}

3. 通过类的Class对象获取类的属性和方法

获取到Class(类的类型)之后,再获取属性和方法就简单了,直接使用Class类封装的方法即可。

getDeclaredFields():获取类属性
getDeclaredMethods():获取类方法

使用一个完整的程序演示如下:

package temp;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Student {
	String studentName;
	public String getStudentName(){
		return studentName;
	}
	public static void main(String[] args) throws ClassNotFoundException {
		Class classStu=Student.class;
		Field[] fields = classStu.getDeclaredFields();
		for(Field field:fields){
			System.out.println("属性类型:"+field.getType().getSimpleName()+",属性名称:"+field.getName());
		}
		Method[] methods=classStu.getDeclaredMethods();
		for(Method method:methods){
			System.out.println("方法名称:"+method.getName()+",返回类型"+method.getReturnType());
		}
	}
}

执行结果如下:

属性类型:String,属性名称:studentName
方法名称:main,返回类型void
方法名称:getStudentName,返回类型class java.lang.String

可见,通过Class类封装的方法,可以在程序运行时候直接获取类的信息。

4. 反射的意义

凡是都有正反两个方面,先说不好的消息吧,用了反射,性能肯定是会降低的。注意此处的性能低,并不是说通过反射获取类的信息性能低,因为除了反射也没有啥可以获取类的信息的机制了。

性能低是指通过反射调用方法性能低,看下面的例子,通过反射获取到方法之后,可以将该方法应用到一个对象上实现该对象的方法调用。本来可以直接调用,反射之后再调用肯定效率要低的。

Class classStu=Student.class;
Student student=new Student();
Method methodGet=classStu.getDeclaredMethod("getStudentName");
//可以通过Method类的invoke方法调用类方法,当然必须得提供对象
String name=(String)methodGet.invoke(student);
System.out.println(name);

但是反射的正面意义还是光辉的,首先提供了一种了解类的信息的手段,使程序运行编写、运行更加自由灵活,充满了更多可能性。

简单的想,在将对象转换为json时,键值对的键不就是对象的属性名称么,用反射获取对象的属性名称是多么爽快的事情啊。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员大阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值