Java中的反射

      反射指的是对对象的反向处理操作,没有反射,就没有Java中的任何框架。

      通过反射,可以取得对象身后的组成,例如(类、构造方法、普通方法、成员)。

      为了实例化类,我们先要取得Class类的对象,即类名。

      取得Class实例化对象有以下三种方法:   ①   Class类对象。getClass()。

                                                     ② 类名。class

                                                     ③ class.forName(String className)

       取得了Class实例化对象,我们就可以用反射实例化对象  。方法是 Class实例化对象。newInstance()。

     使用以上提供反射的方法,可以写一个简单的反射工厂设计模式:

    

package test;


interface friut{
	public void eat();
}
class Orange implements friut{

	public void eat() {
		System.out.println("吃橘子");
	}
	
}
class apple implements friut{

	public void eat() {
		System.out.println("吃苹果");
	}
}
class Factory{
	public static friut getInstance(String className) throws InstantiationException, IllegalAccessException {
		friut friut=null;
		try {
			Class<?> cls = Class.forName(className);
			cls = Class.forName(className);
			friut=(friut)cls.newInstance();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return friut;
	}
}
public class Test {
	public static void main(String[] args) throws Throwable, IllegalAccessException {
	
		friut friut=Factory.getInstance("test.Orange");
		friut.eat();
	}
}

反射实现工厂设计模式的好处是,每当新增接口子类,无需修改工厂类代码就可以方便的进行接口子类的扩容了。

 

反射可以取得对象中你所需要的一切,例如:方法,父类信息,属性等等。

取得父类信息:  取得包名:  Class类对象。getPackage().getName();

                           取得父类名称:   Class类对象。getSuperclass().getName();

取得方法:        取得指定参数构造方法: Class类对象.getConstructor(参数类型以及个数)


import java.lang.reflect.Constructor;

class person{
	private String name;
	private int age;
	public person (String name,int age) {
		this.name=name;
		this.age=age;
	}
	public String toString() {
		return name+age;
		
	}
}

public class Test {	
	public static void main(String[] args) throws Exception {
		Class<?>cls=person.class;
		Constructor<?>cons=cls.getConstructor(String.class, int.class);
		person person=(person) cons.newInstance("human",20);
		System.out.println(person);
	}

}

                取得所有构造方法:Class类对象.getConstructors();

                处理取得构造方法,还可以取得普通方法:

                 取得全部普通方法:Class类对象.getMethods();

                 取得指定普通方法:Class类对象.getMethod(方法名,方法参数);

                 取得了方法以后,我们可以通过invoke来调用方法 :方法对象.invoke(类实例化对象,方法具体参数)。

     例如:

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

class Person{
	private String name;
	private int age;
	public Person(String name){
		this.name=name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String toString(){
		return "Person="+name+","+"age="+age;
	}
}

public class Test {	
	public static void main(String[] args) throws Exception {
		Class<?>cls=Person.class;
		Constructor<?> constructor=cls.getDeclaredConstructor(String.class);
		Person person=(Person) constructor.newInstance("higher");
		Method setMethod=cls.getMethod("setAge", int.class);
		setMethod.invoke(person, 45);
		System.out.println(person);
	}

}

      反射还可以调用类中属性:

                               取得类中全部属性:  Class对象。getFilds()。

                               取得类中指定名称属性:  Class对象。getFild(属性名称)。

  例如:

                  

import java.lang.reflect.Field;
class Person{
	private String name;
	public int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

public class Test {	
	public static void main(String[] args) throws Exception {
		//1.取得class对象
		Class<?> cls=Person.class;
		//2.取得具体类实例化对象
		Person person=(Person)cls.newInstance();
		//3.取得Field对象
		Field field=cls.getField("age");
		//4.设置以及取得属性
		field.set(person, 40);
		//Object object=field.get(person);
		System.out.println(field.get(person));
	}
}

 

至此,反射中的相关操作就已经介绍完毕了,通过以上反射调用的方法,我们可以用反射操作VO。

  设计一个反射操作VO,输入字符串,统一设置属性值:

  

public class Test {

		public static void main(String[] args) throws Exception {
		String value="emp.name:superman|emp.job:Java coder";
		EmpAction empAction=new EmpAction();
		empAction.setValue(value);
		System.out.println(empAction.getEmp());
	}
}
	public class Emp {
		private String name;
		private String job;
		public String getName() {
			return name;
				}
		public void setName(String name) {
			this.name = name;
		}
		public String getJob() {
			return job;
		}
		public void setJob(String job) {
			this.job = job;
		}
@Override
	public String toString() {
		return "Emp [name=" + name + ", job=" + job + "]";
}
  
}
public class EmpAction {

	private Emp emp=new Emp();
	public void setValue(String value) throws Exception {
		BeanOperation.setBeanValue(this,value);
	}
	public Emp getEmp(){
		return emp;
	}
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import com.sun.org.apache.xml.internal.security.Init;


 class BeanOperation{
	private BeanOperation(){}
	
	public static void setBeanValue(Object actionObject,String msg) throws Exception{
		String[]result=msg.split("\\|");
		for(int i=0;i<result.length;i++){
			String[]temp=result[i].split(":");
			String value=temp[1];
			String []finalResult=temp[0].split("\\.");
			String realClassName=finalResult[0];
			String attr=finalResult[1];
			Object realObject=getRealObject(actionObject, realClassName);
			String realAttr=finalResult[1];
			Field realField=realObject.getClass().getDeclaredField(realAttr);
			String setMethodNameString="set"+initCap(realAttr);
			Method setMethod=realObject.getClass().getDeclaredMethod(setMethodNameString, realField.getType());
			setMethod.invoke(realObject, value);
		}
	}
	public static Object getRealObject(Object actionObject,String realClassName) throws Exception {
		
		Object realObject=null;
		Class<?>cls=actionObject.getClass();
		Field field=null;
		field=cls.getDeclaredField(realClassName);
		if(field==null){
			field=cls.getField(realClassName);
			if(field==null){
				return null;
			}
		}
			String methodName="get"+initCap(realClassName);
			Method method=cls.getDeclaredMethod(methodName);
			return realObject=method.invoke(actionObject);
	}
	public static  String initCap(String str) {
		
		return str.substring(0, 1).toUpperCase()+str.substring(1);
	}

	public static void setObjectvalue(Object obj,String attribute,String value) throws Exception{
		Field field=obj.getClass().getDeclaredField(attribute);
		if(field==null){
			field=obj.getClass().getField(attribute);
		}
		if(field==null){
			return;
		}
		String methodName="set"+initCap(attribute);
		Method setMethod=obj.getClass().getMethod(methodName, field.getType());
		setMethod.invoke(obj, value);
	}
}

综合使用反射调用方法,类,属性来达到我们的需求。

 

### 三级标题:Java反射的定义与工作原理 Java中的反射机制是一种允许程序在运行时动态地检查和操作类、接口、字段、方法等内部信息的技术。通过这种机制,可以在不知道对象具体类型的情况下创建对象、调用方法以及访问其属性,甚至包括私有成员。这一特性赋予了Java程序极大的灵活性和扩展性,是构建复杂系统时不可或缺的一部分[^1]。 当一个类被加载到JVM(Java虚拟机)中后,每个类都会对应生成一个`Class`对象。这个`Class`对象包含了该类的所有信息,如构造函数、方法列表、属性等。正常情况下,我们使用类来创建实例;而在反射机制下,则可以通过获取到的`Class`对象来反向了解并操作对应的类及其对象。这意味着开发者能够在应用程序执行期间对类的行为进行修改或增强,例如读取文件内容存入Bean再存储至数据库的过程中遇到字段名不匹配的问题时,可以利用反射动态处理不同命名规则之间的映射关系[^4]。 实现反射功能的核心在于`java.lang.reflect`包提供的APIs,它支持动态地加载类、获取类的信息、创建实例及调用方法等功能。比如,若想通过反射调用某个方法,首先需要获得目标类的`Class`对象,然后查找所需的方法,并设置访问权限(对于私有方法),最后才能完成实际的调用过程。下面是一个简单的示例展示了如何使用反射来调用一个方法: ```java public class ReflectionExample { public void sayHello() { System.out.println("Hello from reflection!"); } public static void main(String[] args) throws Exception { // 获取ReflectionExample类的Class对象 Class<?> clazz = Class.forName("ReflectionExample"); // 创建实例 Object instance = clazz.getDeclaredConstructor().newInstance(); // 获取sayHello方法 Method method = clazz.getMethod("sayHello"); // 调用方法 method.invoke(instance); } } ``` 上述代码演示了从加载类到最终调用其公共方法的基本流程。值得注意的是,在涉及私有成员时还需额外调用`setAccessible(true)`以绕过Java语言的安全限制。 综上所述,Java反射机制基于每个类唯一的`Class`对象,使得程序具备了在运行时刻分析类的能力,从而实现了高度灵活的应用开发模式。然而,尽管反射提供了强大的功能,但过度依赖可能会导致性能下降以及安全风险增加等问题,因此应当谨慎使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值