Java 的反射机制

一、什么是反射?

Java 的反射机制,就是在运行状态中,

  • 对于任意一个类,都能够知道它的所有属性和方法;
  • 对于任意一个对象,都能够调用它的任意一个属性和方法;

这种动态获取信息以及动态调用对象方法的功能称为 Java 的反射机制

Tips:

反射就是把 Java 类中的各种成分(成员变量、方法、构造方法等)映射成一个个的 Java 对象。

二、反射的基本功能

  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时判断任意一个对象所属的类;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理。

三、反射的使用

反射的实现主要借助四个类:Class、Constructor、Field 和 Method。Class 类位于 java.lang 包下,Constructor、Field 和 Method 类位于 java.lang.reflect 包下。从类名就能知道它们的功能:Class 类用来获取类对象、Constructor 用来获取构造方法、Field 类用来获取类中的属性、Method 类用来获取类的方法。

1、通过 Class 类获取类对象

三种方式:

(1)通过实例对象获得:Class<?> class = object.getClass();
(2)任何数据类型(包括基本数据类型)都有一个“静态”的 class 属性,通过类名获得 Class<?> class = 类名.class;
(3)通过类名的相对路径(即 包名.类名)获得:Class<?> class = Class.forName(“包名.类名”);

创建一个 Star 类用来测试。

package reflect_Test;

public class Star {

}

测试如下:

package reflect_Test;

public class reflectTest {
	public static void main(String[] args) {
		// (1)通过实例对象获取 Class 对象:
		Star star = new Star();
		Class starClass1 = star.getClass();
		// getName() 是 Class 类的一个方法,返回对象的类名
		System.out.println(starClass1.getName());
		
		// (2)通过类名获取 Class 对象,类的 class 属性:
		Class starClass2 = Star.class;
		System.out.println(starClass2.getName());
		
		// (3)通过类名的相对路径获取 Class 对象:
		try {
			// 括号里的字符串是类的相对路径,即 包名.类名
			Class starClass3 = Class.forName("reflect_Test.Star");
			System.out.println(starClass3.getName());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

测试结果:

reflect_Test.Star
reflect_Test.Star
reflect_Test.Star

注意:

1、在运行期间,一个类,只有一个类对象产生。

2、第三种方式是最常用的。 第一种方式,已经有对象了,就不用反射了;第二种需要导入类的包,依赖性太强,不导包就抛编译错误(上面的例子,Star 类和 reflectTest 类在同一个包下,不用导包);第三种方式最常用,知道类的路径就可以了。

2、通过 Constructor 类获取类的构造方法

给 Star 类添加构造方法:

package reflect_Test;

public class Star {
	// 默认的构造方法(默认构造方法的访问修饰符继承自类的访问修饰符)
	Star(boolean b){
		System.out.println(b);
	}
	
	// 无参的构造方法
	public Star(){}
	
	// 有参的构造方法
	public Star(String name, int number){
		System.out.println(name +" = " + number);
	}
	
	// 私有的构造方法
	private Star(String name){
		System.out.println(name);
	}
	
	// 受保护的构造方法
	protected Star(int number){
		System.out.println(number);
	}
}

测试代码:

package reflect_Test;

import java.lang.reflect.Constructor;

public class constructorTest {
	
	public static void main(String[] args) throws Exception {
		// 加载类对象
		Class sClass = Class.forName("reflect_Test.Star");
		
		// 1、获取所有的构造方法(默认的、公共的、受保护的、私有的):
		System.out.println("1、所有的构造方法:");
		Constructor[] array1 = sClass.getDeclaredConstructors();
		for(Constructor c : array1){
			System.out.println(c);
		}
		
		// 2、获取所有公共的构造方法:
		System.out.println("2、所有公共的构造方法:");
		Constructor[] array2 = sClass.getConstructors();
		for(Constructor c : array2){
			System.out.println(c);
		}
		
		// 3、获取公共、无参的构造方法:
		System.out.println("3、公共、无参的构造方法:");
		Constructor con = sClass.getConstructor();
		System.out.println(con);
		// 可以用得到的构造方法new一个Star实例,调用Constructor类的newInstance()方法
		Object o = con.newInstance();
		Star s = (Star)o;// 要转换类型
		
		// 4、获取指定参数类型的构造方法:
		// getDeclaredConstructor(Class<?>... parameterTypes)方法可以指定参数类型,
		// 该方法返回和指定参数类型相符的构造方法
		System.out.println("4、指定参数类型的构造方法:");
		Constructor con1 = sClass.getDeclaredConstructor(String.class);
		System.out.println(con1);
	}

}

测试结果:

1、所有的构造方法:
protected reflect_Test.Star(int)
private reflect_Test.Star(java.lang.String)
public reflect_Test.Star(java.lang.String,int)
public reflect_Test.Star()
reflect_Test.Star(boolean)
2、所有公共的构造方法:
public reflect_Test.Star(java.lang.String,int)
public reflect_Test.Star()
3、公共、无参的构造方法:
public reflect_Test.Star()
4、指定参数类型的构造方法:
private reflect_Test.Star(java.lang.String)

3、通过 Field 类获取成员变量

Field 类的使用方法和 Constructor 类是类似的。图片来自 Java API。
在这里插入图片描述
在这里插入图片描述

4、通过 Method 类获取成员方法

Method 类的使用方法和 Constructor 类是类似的。图片来自 Java API。
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值