Web基础之Java中的反射机制

Web基础之Java中的反射

一、Java中的反射机制

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,

能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。



二、反射机制的功能:

· 在运行时获取任意一个对象所属的类;

· 在运行时构造任意一个类的对象;

· 在运行时获取任意一个类所具有的成员变量和方法;

· 在运行时调用任意一个对象的方法;

· 生成动态代理。(了解)


三、反射API(后面会有代码演示)
通过一个对象或类获取完整的包名和类名
在运行时实例化一个类的对象
获取一个类的父类和实现的接口
获取某个类的全部构造方法
获取某个类的全部属性和方法
通过反射机制调用某个类的方法
通过反射机制操作某个类的属性

四、反射机制的应用
     在泛型为 Integer ArrayList 中存放一个其他类型的对象
     通过反射取得并修改数组的信息
     通过反射机制修改数组的大小
     在 DAO 中,优化对象的封装



五、代码演示Java反射API以及简单应用
新建一个Person类,该类的属性和方法如下;
为了后面的测试,我们实现了序列化接口:
package com.hx.ref;

import java.io.Serializable;

public class Person implements Serializable{
	
	private static final long serialVersionUID = 1L;

	public static String schname;
	
	private  String name;
	
	private int age;
	
	private String sex;
	
	private float weight;
	
	public Person() {
		
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public Person(String name, int age, String sex, float weight) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.weight = weight;
	}

	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;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public float getWeight() {
		return weight;
	}

	public void setWeight(float weight) {
		this.weight = weight;
	}
	
	public String toString() {
		String str="Person:"+"Name:"+name+"Age:"+age+"Sex:"+sex+"Weight:"+weight;
		return str;
	}
}

package com.hx.ref;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

public class Test {

	public static void main(String[] args) throws Exception{
		
//		String [] str={"123","345","678","789"};
//		String [] copyStr=arrayCopyandIncres(str, 2,String.class);
//		
//		priArray(copyStr);
//		
//		Integer [] ints={1,2,3,4,5};
//		Integer[] inscopy=arrayCopyandIncres(ints, 4, Integer.class);
//		priArray(inscopy);
		
		test6();
	}

	// 获取Person类的Class对象
	@SuppressWarnings({ "unused", "rawtypes" })
	private static void test1() {
		// Class类的获取方法:通过[对象的getClass()方法]获取Class对象
		Person p = new Person();
		Class clazz = p.getClass();
		System.out.println(clazz.getName());
		
		//获取Person类的修饰
		int m = clazz.getModifiers();
		System.out.println(Modifier.isPublic(m));
		
		// Class类的获取方法:通过对象的[类.class方法]获取Class对象
		System.out.println(Person.class.getSimpleName());
		System.out.println(Person.class.getName());
		
		//  Class类的获取方法:通过Class.forName("+全限定名")获取Class对象
		try {
			System.out.println(Class.forName("com.hx.ref.Person").getName());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	// 通过Class类创建对象
	@SuppressWarnings({ "unused", "rawtypes" })
	private static void test2() throws InstantiationException,
			IllegalAccessException {
		Class clazz = Person.class;
		Person p = (Person) clazz.newInstance();
		System.out.println(p);
	}

	// 获取Class类的父类以及实现的接口
	@SuppressWarnings({ "unused", "rawtypes" })
	private static void test3() throws InstantiationException,
			IllegalAccessException {
		Class clazz = Person.class;
		Class supclazz = clazz.getSuperclass();
		Class[] intefaces = clazz.getInterfaces();
		System.out.println(supclazz);
		priArray(intefaces);
	}

	// 获取Person类构造函数
	@SuppressWarnings({ "unused", "rawtypes" })
	private static void test4() throws InstantiationException,
			IllegalAccessException {
		Class clazz = Person.class;
		Constructor[] cons = clazz.getConstructors();
		priArray(cons);
	}

	// 获取字段和方法
	@SuppressWarnings({ "unused", "rawtypes" })
	private static void test5() throws InstantiationException,
			IllegalAccessException {
		Class clazz = Person.class;
		Field[] fiels = clazz.getDeclaredFields();
		priArray(fiels);

		Method[] methods = clazz.getDeclaredMethods();
		priArray(methods);
	}

	// 获取构造函数并构造对象
	@SuppressWarnings({ "unused", "rawtypes" })
	private static void test6() throws InstantiationException,
			IllegalAccessException, IllegalArgumentException,
			InvocationTargetException {
		//获取Class类对象
		Class clazz = Person.class;
		//获取构造函数
		Constructor[] cons = clazz.getDeclaredConstructors();
		priArray(cons);
		//拿到一个构造函数
		Constructor c = cons[0];
		//获取该构造函数的参数列表的类类型
		Class[] paraClazz = c.getParameterTypes();
		//如果参数列表为0,则直接new对象
		if (paraClazz.length == 0) {
			Object o = c.newInstance(new Object[] {});
			System.out.println(o);
		} else {
			// 构建参数列表
			Object[] paras = new Object[paraClazz.length];
			for (int i = 0; i < paraClazz.length; i++) {
				//通过GETVALUE方法,该每个参数列表付初始值
				paras[i] = getValue(paraClazz[i]);
			}
			Object result = c.newInstance(paras);
			System.out.println("result:" + result);
		}
	}

	// 操作字段
	@SuppressWarnings({ "rawtypes", "unused" })
	private static void test7() throws Exception {
		Class clazz = Person.class;
		//构造实例
		Object person = clazz.newInstance();
		//获取所有字段
		Field[] field = clazz.getDeclaredFields();

		//遍历所有属性
		for (int i = 0; i < field.length; i++) {
			int m = field[i].getModifiers();
			//排除Static属性异己非私有属性
			if (Modifier.isStatic(m) || !Modifier.isPrivate(m)) {
				continue;
			}
			//拿到属性名字
			String fieldname = field[i].getName();
			//拼set方法
			String setterName = "set"
					+ Character.toUpperCase(fieldname.charAt(0));
			if (fieldname.length() > 1) {
				setterName = setterName + fieldname.substring(1);
			}
			@SuppressWarnings("unchecked")
			//获取set方法
			Method m1 = clazz.getDeclaredMethod(setterName,
					new Class[] { field[i].getType() });
			//通过方法为属性设置值
			m1.invoke(person, new Object[] { getValue(field[i].getType()) });
		}

		System.out.println("person:" + person);
	}

	// 操作字段2
	@SuppressWarnings("unused")
	private static void test8() throws InstantiationException,
			IllegalAccessException {
		@SuppressWarnings("rawtypes")
		Class clazz = Person.class;
		Object p1 = clazz.newInstance();
		Field[] fields = clazz.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			int m = fields[i].getModifiers();
			if (Modifier.isStatic(m) || !Modifier.isPrivate(m)) {
				continue;
			}
			// 破坏了封装性
			fields[i].setAccessible(true);
			fields[i].set(p1, getValue(fields[i].getType()));
		}

		System.out.println("p1:" + p1);
	}

	// 操作数组
	@SuppressWarnings("unused")
	private static void test9() throws Exception{
		List<String> plist = new ArrayList<String>();
		plist.add("张三");
		plist.add("李四");

		Class<?> clazz = plist.getClass();
		Method m = clazz.getMethod("add", Object.class);
		//说明了泛型只在编译阶段会检查,运行阶段没有泛型一说
		m.invoke(plist, new Integer(999));

		System.out.println("plist:" + plist);
	}

	//数组的拷贝
	@SuppressWarnings({ "unused", "unchecked" })
	private static <T> T[] arrayCopyandIncres(T[] array, int times,Class<T> clazs) {
		// 获取数组中的存储类型
		Class<?> clazz = array.getClass().getComponentType();
		Object newArray = Array.newInstance(clazz, array.length * times);
		for (int i = 0; i < array.length; i++) {
			Array.set(newArray, i, array[i]);
		}
		return (T[]) newArray;
	}

	@SuppressWarnings("rawtypes")
	private static Object getValue(Class clazz) {
		if (clazz == Boolean.class || clazz == Boolean.TYPE) {
			return Boolean.TRUE;
		}
		if (clazz == Byte.class || clazz == Byte.TYPE) {
			return Byte.valueOf((byte) 100);
		}
		if (clazz == Short.class || clazz == Short.TYPE) {
			return Short.valueOf((short) 200);
		}
		if (clazz == Character.class || clazz == Character.TYPE) {
			return Character.valueOf('a');
		}
		if (clazz == Integer.class || clazz == Integer.TYPE) {
			return Integer.valueOf(300);
		}
		if (clazz == Long.class || clazz == Long.TYPE) {
			return Long.valueOf(400L);
		}
		if (clazz == Float.class || clazz == Float.TYPE) {
			return Float.valueOf(50.0F);
		}
		if (clazz == Double.class || clazz == Double.TYPE) {
			return Double.valueOf(100.0);
		}
		// String 类型
		if (clazz == String.class) {
			return "Hello";
		}
		// 如果还没匹配到,那该类型一定是引用类型,返回null
		return null;
	}

	
	private static void priArray(Object[] obj) {
		for (int i = 0; i < obj.length; i++) {
			System.out.println(obj[i]);
		}
	}
}


六、部分运行结果:













七、总结
Java反射是Java中比较高级的知识;第一次接触会有点不可思议;会觉得不太好理解;
我觉得首先的得对反射这块的知识有所了解,然后通过自己写代码掌握好这些反射的API以及使用;
其实反射这块我也花了很长的时间才能慢慢理解;写这篇博客的时候,我已经前后两次接触Java反射了;
今天写博客再次整理这块知识的时候觉得比以前好很多了;
所以,坚持不要放弃,到最后你总会懂的;就像以前初中学知识,我感觉好多地方学得模模糊糊的,后来 来到大学给初中生做家教的时候再去看那些知识,觉得好简单;我觉得这有两个方面的原因:一是随着年龄的增长,自己的理解力变强了;二是因为通过高中的学习以及大学的学习,不断的学习让自己的思维发生了很大的变化;我觉得第二点更能说明;所以,只要坚持不懈的努力学习,任何难点都不会是难点;我们的技术也会越来越强;
共勉!
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值