Java反射详解

本文深入解析Java反射机制,介绍如何通过反射获取类信息、实例化对象、调用构造方法、普通方法及属性,同时探讨反射在破坏封装上的应用。

什么是反射

以往我们使用类和对象的顺序都是,先创建好类,然后再通过类创建对象。和这不同的是,反射的工作主要是先拿到对象然后根据对象倒推类的组成。
也许你会问,虽然我拿到了对象,但是我怎么知道类里有啥呢?发射的核心处理在于每个类都继承了Object类
这种操作就很像盗版的操作:原创是先有的构想,然后设计图纸,然后创建出模型,再生产出产品。而盗版却是已经拿到了产品,但是想利用这个产品倒退出模型然后再创作出新的产品。
哇,反射肯定比正常使用麻烦吧?不一定哦

如何取得对象的Class对象

1.实例化对象.getClass()
任何类得对象都可以直接通过调用Object类提供的getClass()取得该类的Class对象。
2.类名.class
可以直接根据某个具体类名称类取得它的Class类对象
3.Class.forName("类的全路径名称")
调用Class类的静态方法Class.forName(String className)通过传入类的全路径名称类来获取Class对象
为什么可以通过.getClass(),或者.class取得呢?
因为每一个我们创建的类都继承类Object类,而Object中提供了获取类对象的本地方法,也就是说一个类里包含的东西,不只是我们看到的那么几个哦~
在这里插入图片描述
任何一个类的Class对象都是由JVM皆在类后就产生了,而且这个类的Class对象在JVM中全局唯一,用户只能通过调用我们上述提供的三种方法来获取该对象,是不能够自己创造的哦

通过Class对象反射产生实例化对象

1.Class类中提供public T newInstance()方法来调用类中公有public属性的无参数的构造方法来实例化对象。

Class<?> cls = emp.getClass();
Object obj = cls.newInstancle();

2.Constructor类提供类public T newInstance(Object...initargs)方法来调用类中有参数的构造方法来实例化对象。

//调用emp类的带有String类型参数的构造方法
Class<?> cls = emp.getClass();
Constructor<?> constructor =cls.getConstructor(String.class);
Object obj = constructor.newInstance("name");

通过这个方法只要拿到类的全路径和名称,就可以实例化一个对象了。

通过反射取得父类、以及父接口信息-Class类提供

1.取得父类名称
public Package getPackage()
2.取得父类的Class对象 <? super T>设置了下限
public native Class<? superT > getSuperclass()
3.取得实现了的父接口 --不一定是一个哦,实现接口没有单继承局限哦
public Class<?>[] getInterfaces()

通过反射调用类中构造方法-Constructor类提供

1.取得类中指定参数类型的public权限的构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes)
2.可以取得类中指定参数的构造方法,会在所有构造中找,包括私有权限的
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)throws NoSuchMethodException, SecurityException
3.取得类中所有public权限的构造方法
public Constructor<?>[] getConstructors() throws SecurityException
4.取得类中所有构造方法包括私有,默认,继承,共有权限的
public Constructor<?>[] getDeclaredConstructors() throws SecurityException
5.通过对应构造实例化对象
public T newInstance(Object ... initargs)
6.提供动态破坏封装,想要破坏封装参数传true就删除了指定构造方法的私有权限,但是只能通过本类提供的方法来调用。
public void setAccessible(boolean flag) throws SecurityException

通过反射调用类中普通方法-Method类提供

1.取得类中制定名称的公有普通方法
public Method getMethod(String name, Class<?>... parameterTypes)
2.取得类中指定名称的不限权限的普通方法
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
3.取得本类以及父类中所有public方法
public Method[] getMethods() throws SecurityException
4.取得本类中全部普通方法,包括私有方法
public Method[] getDeclaredMethods() throws SecurityException
5.⭐Methrod类提供调用类的普通方法的方法,不然我通过上述操作拿到了Method类型的方法,但是不能使用,因为没有啊,因为普通方法的调用和对象有关,所以需要我们第一个参数传入想要调用这个类的对象,而可变参数则是这个普通方法实际需要传入的参数。
public Object invoke(Object obj, Object... args)
举个例子:

import java.lang.reflect.Method;
class Person{
	private String name;
	public String getName() {
		return name;
	}	
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return getClass()+"\t:"+name;
	}
}
public class Test{
	public static void main(String[] args)throws Exception{
		Class<?> cls = Person.class;
		Person person = (Person) cls.newInstance();
		Method setMethod = cls.getMethod("setName", String.class);
		setMethod.invoke(person,"hahaha");
		System.out.println(person);
	}
}

6.提供动态破坏封装,想要破坏封装参数传true就删除了指定普通方法的私有权限,但是只能通过本类提供的方法调用。
public void setAccessible(boolean flag) throws SecurityException

通过反射调用类中属性-Field类提供

1.取得类中指定名称的public权限的属性
public Field getField(String name)
2.取得类中指定属性在所有权限中找
public Field getDeclaredField(String name)
3.取得类中全部属性取得类中全部公有属性
public Field[] getFields() throws SecurityException
4.取得本类中全部普通属性,包含私有属性
public Field[] getDeclaredFields()
5.设置取得属性

//设置属性:
public void set(Object obj, Object value)
//取得属性:
public Object get(Object obj)

6.取得属性类型
public Class<?> getType()
7.提供动态破坏封装,想要破坏封装参数传true就删除了指定属性的私有权限,但是只能通过本类提供的方法修改,拿到对应值。
public void setAccessible(boolean flag) throws SecurityException

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值