JAVA反射常用方法详解

JAVA反射

1.定义

在《JAVA核心技术 卷一》这样写道:能够分析类能力的程序称为反射。
简单来说就是,可以动态的获取任意一个类的方法,属性,构造函数等信息。

2.反射用到的类

  • Class类:保存(获取)类的信息
  • Field类:保存(获取)类的成员变量
  • Method类:保存(获取)类的方法
  • Constructor类:保存(获取)类的构造器
    下面具体说一下以上各类:

重要的几个方法

Class这个类主要是通过对象或者字符串获取相关类的信息,人们可以通过Class中的方法对这个类进行相关的处理。
1.forName(String className):
这个方法大家应该在数据库的时候见到过,主要是通过传入类的全类名,从而加载这个类(注意这里并不是创建的这个类的对象,而是加载这个类并且赋值给Class的对象变量)。
比如:

try {
		Class s = Class.forName("com.cyk.text.Dog");
	} catch (Exception e) {
		// TODO: handle exception
	}

这个代码将com.cyk.text包下的Dog类进行加载并赋值给Class的对象变量s,该对象存储了Dog类的相关信息,并且初始化了Dog中的相关的实例域和代码块(比如静态代码块),但并不执行构造函数。
同时还有一个重点就是,这个forName方法在书写的时候必须要进行异常信息的处理,也就是添加try…catch方法。因为forName方法是一个已检查异常。
这里简单的说一些异常的分类:
异常大体上可以分为两种:
1.以检测异常:在编写的时候需要添加try…catch,如果程序出现异常将会通过catch进行抛出。这个在编写的时候编译器会进行提示是否需要添加try…catch.
2.未检测异常:在编写的时候并不需要一定的添加try…catch。在程序运行的时候出现错误,程序将会终止,并在控制台打印错误,比如:空指针异常。
当然有关异常的其他情况在这就不做详细的介绍了。

2.Object.getClass()
该方法将会返回一个Class类的对象,该对象将存储了Object类中的相关信息。

	Dog dog = new Dog();
	Class class1 = dog.getClass();

该方法和forName方法大同小异,一个是通过字符串,另一个直接通过类的对象。那么我们就会产生一个疑问,这两个生成的Class对象是相等吗?

if (class1==s) {
	System.out.println("11");
}

结果如下图所示,很明显,两个对象是相等的。也就是说用这两个方法哪一个都是一样的。
在这里插入图片描述
3.newInstance()
该方法将会动态的创建一个类的实例(通过调用无参的构造方法,如果没有无参的构造方法将会报错)。也就是直接就生成了该类的对象,例子如下:

	Dog dog = new Dog();
	try {
		Dog class1 = dog.getClass().newInstance();
	} catch (InstantiationException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	} catch (IllegalAccessException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}

以上的代码将会获得一个Dog对象,注意这个方法也是一个已检查异常,需要添加try…catch。
在上面说到getClass方法和froName方法的到的结果是一样的,但是在使用这个方法的时候却并不相同,下面是forName方法调用newInstance()方法的代码:

try {
	Dog s = (Dog) Class.forName("com.cyk.text.Dog").newInstance();
} catch (Exception e) {
	// TODO: handle exception
}

可以发现通过forName调用newInstance()方法返回的并不是一个dog对象,而是一个Object对象,需要通过强制转化成为Dog对象。

4.Field[] getFields()与Field[] getDelcaredFields()
这是两个相关的方法:
getFields():该方法将会记录该类以及其超类的公有域;
getDelcaredFields():该方法将会记录该类的所有的属性,但不能记录超类的属性。
实例:
在Animal类中:

public class Animal {
	
	public String ss="0";
	
	//动物的年龄
	private int age;
	
	//动物的性别
	private String gender;
	}

在Dog类中:

public class Dog extends Animal{
	public String b="11";
	
	//狗的名字
	private String name;
	}

测试类:

Dog dog = new Dog();

Class class1 = dog.getClass();

Field []aFields = class1.getDeclaredFields();
for (Field field : aFields) {
	System.out.println(field);
}

这里调用了getDeclaredField(),这个方法将会记录该类中的全部属性在Field的数组中,并循环输出,结果如下:

在这里插入图片描述
很明显返回了Dog类中的所以属性,并没有返回超类的。

接下来调用getFields方法:

Dog dog = new Dog();

Class class1 = dog.getClass();

Field []aFields = class1.getFields();
for (Field field : aFields) {
	System.out.println(field);
}

结果如下:
在这里插入图片描述
可以发现结果中是该类和超类中的public的属性。

5.Method[] getMethods() 与 Method[] getDeclaredMethods()
这是两个相关的方法:
getMethods():该方法将会记录该类以及其超类的共有方法;
getDeclaredMethods():该方法将会记录该类的所有的方法,但不能记录超类的方法。
我们给Animal和Dog类中的属性添加get和set方法(都是publice),并给Dog中添加一个私有的方法:

private void name() {
	System.out.println("这个是狗的私有方法");
}

在测试类中调用getMethods方法,并将结果循环输出

Dog dog = new Dog();

Class class1 = dog.getClass();

Method []methods = class1.getMethods();
for (Method method : methods) {
	System.out.println(method);
}

结果如下图所示:
在这里插入图片描述
可以发现Dog和Animal的共有方法都展现出来了,当然也会有Object中的共有方法,因为所有的类都继承与Object。
接下来调用另一个方法getDeclaredMethods,并循环输出:

Dog dog = new Dog();

Class class1 = dog.getClass();

Method []methods = class1.getDeclaredMethods();
for (Method method : methods) {
	System.out.println(method);
}

结果如下图所示:
在这里插入图片描述
可以很清楚的发现,这个方法返回了Dog类中的所有方法。

6.Constructor[] getConstructors() 与 Constructor[] getDeclaredConstructors()
这是两个相关的方法:
getConstructors():该方法将会记录该类以及其超类的公有构造器;
getDeclaredConstructors():该方法将会记录该类的所有的构造器,但不能记录超类的构造器。
在狗类中添加相应的构造器方法:

private Dog(String name){
	System.out.println("这是狗的名字"+name);
}
public Dog() {
	System.out.println("这是狗的方法");
}

在Animal中也添加相应的构造器方法:

public Animal() {
	System.out.println("这是动物的构造方法");
}

在测试类中调用getConstructors方法

Dog dog = new Dog();

Class class1 = dog.getClass();

Constructor [] constructors = class1.getConstructors();
for (Constructor constructor : constructors) {
	System.out.println(constructor);
}

结果如下:
在这里插入图片描述

该方法会显示出Dog类中的所有的共有构造器方法。
下面利用测试类调用getDeclaredConstructorsf方法

Constructor [] constructors = class1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
	System.out.println(constructor);
}

结果如下:
在这里插入图片描述
可以发现该方法将会展现出Dog类张的所有的构造器。

当然还有很多的方法:

getModifiers():该方法将返回一个描述方法的修饰符的整型数值(可以利用toString(Class对象.getgetModifiers)方法返回修饰符,既可以返回publice,private等);
getName():返回相应的方法,属性的名字;
getParameterTypes():返回一个用于描述参数类型的对象
getReturnType():用于一个描述返回类型的对象

还有很多的方法在这就不做一一的介绍了,

总结

本文列举了反射一些常用的方法,渎职可以进行借鉴,反射可以动态的获取一些类的信息,从而获取类中的方法,属性,构造器等信息。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java反射机制是指在运行时动态地获取一个类的信息,并可以操作类的属性、方法和构造器等。Java反射机制可以使程序员在运行时动态地调用类的方法和属性,扩展类的功能,并可以实现注解、工厂模式以及框架开发等。 Java反射机制的原理如下:首先,Java编译器将Java源代码编译为字节码文件,字节码文件中包含着类的信息,这些信息包括类的名称、方法、属性和构造器等等。接着,Java虚拟机将字节码文件加载到内存中,然后通过类加载器将类加载到内存中形成一个类对象,这个类对象可以操作字节码文件中的信息。 使用Java反射机制的过程如下:首先获取类对象,通过类对象来获取类的构造器、属性、方法等信息,然后调用构造器来创建对象,通过属性获取和设置类的成员属性,通过方法调用类的方法等。 Java反射机制的优点是可以在运行时动态地得到类的信息,使得程序员在程序运行时能够对类进行更加灵活的操作,并可以使得程序更加通用化,同时也存在着一定的性能问题,因为Java反射机制需要Java虚拟机进行一定的额外处理,所以在程序运行时需要进行额外的时间和资源消耗。 总之,Java反射机制是Java语言的一项重要特性,在Java开发中广泛应用,在代码编写、框架开发以及API开发中具有重要作用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值