Java 反射

Java反射在网上有很多的例子 在这里就简单的谈一下我自己的理解再粘贴一些自己的代码好了

我对反射的接触是在WEB开发中,当时是需要读取XML请求配置文件来实现业务逻辑类自动实例化和调用;

在几乎所有的Java WEB框架里都会用到反射,在对Java编写程序进行反编译时也会用到反编译;

总而言之Java中的反射在开发中用到的地方还是很多很多的,希望各位朋友进行深入的研究;

下边就是一下代码:

1:这个例子提到反射中调用 有参和无参方法和有返回值的有参方法

import java.lang.reflect.Method;

public class ClssModel {
	//测试方法
	public static void main(String[] args) {
		new ClssModel().test("com.A");;
		new ClssModel().test("com.B");;
	}
	
	public void test(String string) {
		System.out.println("Java反射!");
		try {
			//加载类
			Class<?> clsA = Class.forName(string);
			//实例化
			Object object = clsA.newInstance();
			
			/**
			 * 没有返回值的方法
			 */
			//无参数方法
			Method meth0 = clsA.getDeclaredMethod("meth");
			meth0.invoke(object);
			
			//有参数方法
			Method meth1 = clsA.getDeclaredMethod("meth", int.class);
			meth1.invoke(object, 1);
			
			Method meth2 = clsA.getDeclaredMethod("meth", new Class[]{int.class, int.class});
			meth2.invoke(object, new Object[]{1,2});
			
			/**
			 * 有返回值的方法
			 */
			Method meth4 = clsA.getDeclaredMethod("meth", new Class[]{String.class});
			Object returnObject1 = meth4.invoke(object, new Object[]{"Hello world!"});
			System.out.println(returnObject1);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


//@OtherClass
class A {
	public void meth() {
		System.out.println("A : "+" A!");
	}
	public void meth(int i) {
		System.out.println("A : "+" "+i+"!");
	}
	public void meth(int i, int j) {
		System.out.println("A : "+" "+i+" "+j+"!");
	}
	public String meth(String str){
		return "A : "+str;
	}
}

class B {
	public void meth() {
		System.out.println("B : "+" B !");
	}
	public void meth(int i) {
		System.out.println("B : "+" "+i+" !");
	}
	public void meth(int i, int j) {
		System.out.println("B : "+" "+i+" "+j+" !");
	}
	public String meth(String str){
		return "B : "+str;
	}
}

2:这个例子介绍了反射有参构造方法 无参构造方法在实例化的时候就可以调用;还介绍了反射更改属性值,这个一定要注意访问权限的问题

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

import org.junit.Test;

public class ClassModel {
	
	/**
	 * 调用有参构造方法
	 */
	@Test
	public void test0() {
		try {
			//调用有参构造方法
			Class<?> cla = Class.forName("com.BeanModel");
			//找到对应的构造方法
			Constructor<?> constructor = cla.getConstructor(new Class[] {String.class, int.class});
			//实例化找到的构造方法
			Object object = constructor.newInstance(new Object[] {"name", 20});
			System.out.println(object.getClass());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 更改属性值
	 */
	//@Test
	public void test1() {
		try {
			Class<?> cla = Class.forName("com.BeanModel");
			Object object = cla.newInstance();
			//获取name属性
			Field field = cla.getDeclaredField("name");
			//设置name属性的可访问权限
			field.setAccessible(true);
			//为name设置"name"值
			field.set(object, "name");
			//获取name属性的值
			System.out.println(field.get(object));
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}
}
//BeanModel类
class BeanModel {
	private String name;
	private int age;
	
	public BeanModel() {
		System.out.println("访问无参构造!");
	}
	public BeanModel(String name, int age) {
		System.out.println("访问有参构造");
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}



3:在这个例子中提到反射的各种拓展,说实话-除了测试在项目中几乎没用过

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

public class ClssUtil {
	
	/**
	 * 打印 类的信息 成员函数 成员变量
	 */
	public void test1(Object object) {
		//获取类的信息 传递子类对象 cls为类类型
		Class<?> cls = object.getClass();
		//基本数据类型
		//Class<?> cls = Integer.TYPE;
		
		//获取类名称
		System.out.println(cls.getName());
		
		//获取类的所有方法信息
		Method[] methods = cls.getMethods();//cls.getDeclaredMethods();[自己的方法,不包括父类]
		for (Method method : methods) {
			//得到返回类型
			Class<?> clsReturn = method.getReturnType();
			System.out.print(clsReturn.getName()+" : ");
			
			//得到方法名
			System.out.print(method.getName()+" (");
			
			//获取方法参数类型--参数列表的类型的类类型
			Class<?>[] methodTypes = method.getParameterTypes();
			for (Class<?> methodType : methodTypes) {
				System.out.print(methodType+", ");
			}
			System.out.println(")");
		}
	}
	
	/**
	 * 获取成员变量的信息 Field
	 */
	public void test2(Object object) {
		Class<?> cls = object.getClass();
		
		//自己声明的成员变量信息
		Field[] fields = cls.getDeclaredFields();//cls.getFields();-[获去所有public成员变量信息]
		for (Field field : fields) {
			//成员变量的类型的类类型
			Class<?> fieldType = field.getType();
			System.out.print(fieldType.getName()+" : ");
			//成员变量的名称
			System.out.println(field.getName());
		}
	}
	
	/**
	 * 构造函数信息
	 */
	public void test3(Object object) {
		Class<?> cls = object.getClass();
		
		//获取所有的构造函数信息
		Constructor<?>[] constructors = cls.getDeclaredConstructors();//cls.getConstructors();
		for (Constructor<?> constructor : constructors) {
			//构造函数名
			System.out.print(constructor.getName()+"(");
			
			//构造函数参数列表
			Class<?>[] paramTypes = constructor.getParameterTypes();
			for (Class<?> paramType : paramTypes) {
				System.out.print(paramType.getName()+",");
			}
			System.out.println(")");
		}
	}

	/**
	 * 得到类的其它信息
	 * 其它雷同
	 */
	
	//测试
	public static void main(String[] args) {
		String s = "1";
		new ClssUtil().test3(s);
		System.out.println("-------------------");
		Integer i = 1;
		new ClssUtil().test3(i);
	}
	
}

在大部分框架核心都会用到反射,因为它实在太方便了!


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值