Reflect

/*
 *反射,用于获取Java类中各个成员。反射的意义在于替换。
 */

package classfile;

import java.lang.reflect.*;
import java.util.*;

public class ReflectDemo
{
	public static void main(String[] args)
	{
		method_getClass();
		method_Constructor();
		method_Field();
		method_Method();
		method_Array();
	}
	
	private static void method_getClass()
	{
		String str = new String();
		
		//获取Class对象的三种方式
		Class clazzOne = String.class;
		Class clazzTwo = str.getClass();
		Class clazzThree = null;
		try
		{
			clazzThree = Class.forName("java.lang.String");
		}
		catch (ClassNotFoundException e)
		{
			e.printStackTrace();
		}
		
		//获取到的三个对象是同一个类对象
		System.out.println("clazzOne == clazzTwo:"+(clazzOne == clazzTwo));
		System.out.println("clazzOne == clazzThree:"+(clazzOne == clazzThree));

		//判断一个Class对象是否属于基本数据类型
		System.out.println("Sting是否属于基本数据类型:"+clazzOne.isPrimitive());
		System.out.println("int是否属于基本数据类型:"+int.class.isPrimitive());
	}
	
	//构造函数的反射
	private static void method_Constructor()
	{
		//获取指定参数的公有构造方法
		Constructor<String> constructor = null;
		try
		{
			constructor = String.class.getConstructor(String.class);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		System.out.println("构造方法的名称:"+constructor.getName());

		Type[] type = constructor.getGenericParameterTypes();
		System.out.println("构造方法参数列表的长度:"+type.length);

		//使用构造方法对象构造一个实例
		String str = null;
		try
		{
			str = constructor.newInstance("a string");
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		System.out.println("用构造方法的对象构造实例:"+str);

		//获取所有的公有构造方法
		Constructor[] constructors = null;
		try
		{
			constructors = String.class.getConstructors();
		}
		catch (SecurityException e)
		{
			e.printStackTrace();
		}
		
		System.out.println("String类构造方法的数量:"+constructors.length);

		//直接用Class对象使用空参数的构造方法构造一个对象
		try
		{
			System.out.println(String.class.newInstance().getClass().getName());
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	//字段的反射
	private static void method_Field()
	{
		ReflectObject reflectObjectOne = new ReflectObject(3,5);
		
		//获取一个对象的私有成员变量的对象实例
		Field fieldY = null;
		try
		{
			fieldY = reflectObjectOne.getClass().getDeclaredField("y");
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
		//获取该对象的确定的私有成员变量的取值,此处使用暴力反射
		fieldY.setAccessible(true);
		int fieldYValue = 0;
		try
		{
			fieldYValue = (int)fieldY.get(reflectObjectOne);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		System.out.println("获取一个对象的私有字段的取值:"+fieldYValue);

		//批量修改某一个对象的相同类型字段的取值
		changeStringValue(reflectObjectOne);
		System.out.println("被修改后的所有String类型字段的取值:"+reflectObjectOne.toString());
	}

	//成员方法的反射
	private static void method_Method()
	{
		ArrayList<Integer> al = new ArrayList<Integer>();
		
		//获取单个方法,并使用该方法
		Method method = null;

		try
		{
			method = al.getClass().getDeclaredMethod("add",Object.class);

			//向泛型为Integer的集合中添加一个String
			method.invoke(al,"This is a String.");
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
		System.out.println(al.get(0));

		//获取该集合的所有方法
		Method[] methods = null;
		try
		{
			methods = al.getClass().getDeclaredMethods();
		}
		catch (SecurityException e)
		{
			e.printStackTrace();
		}

		System.out.println("ArrayList集合的方法的数量:"+methods.length);
	}
	
	//数组的反射
	private static void method_Array()
	{
		//相同类型的相同维数的数组属于同一份字节码文件
		int[] arrIntOne = new int[]{1,2,3};
		int[] arrIntTwo = new int[4];
		int[][] arrIntThree = new int[2][3];
		String[] arrStringFour = new String[]{"a","b","c"};

		System.out.println("arrIntOne.getClass() == arrIntTwo.getClass():"+(arrIntOne.getClass() == arrIntTwo.getClass()));
		
		System.out.println("int型一维数组的类文件:"+arrIntOne.getClass());
		System.out.println("int型二维数组的类文件:"+arrIntThree.getClass());
		System.out.println("String型一维数组的类文件:"+arrStringFour.getClass());
		
		//所有数组的父类都是Object
		System.out.println("数组的父类:"+arrIntOne.getClass().getSuperclass().getName());
		System.out.println("数组的父类:"+arrIntThree.getClass().getSuperclass().getName());
		System.out.println("数组的父类:"+arrStringFour.getClass().getSuperclass().getName());

		//基本数据类型数据不属于Object
		Object objectOne = arrIntOne;
		Object objectTwo = arrIntThree;
		//Object[] objectThree = arrIntOne;//此项编译不通过
		Object[] objectFour = arrIntThree;
		Object[] objectFive = arrStringFour;

		//打印数组中的元素
		System.out.println(Arrays.asList(arrIntOne));
		System.out.println(Arrays.asList(arrStringFour));
		printObject(arrIntOne);
		printObject(arrStringFour);
		printObject("abc");

	}

	//将一个对象的所有String类型的字段的值中的b替换成a
	private static void changeStringValue(Object obj)
	{
		Field[] fields = null;
		try
		{
			fields = obj.getClass().getDeclaredFields();
		}
		catch (SecurityException e)
		{
			e.printStackTrace();
		}

		for(Field field:fields)
		{
			//暴力反射
			field.setAccessible(true);

			//同一份字节码的比较用“==”
			if(field.getType() == String.class)
			{
				try
				{
					String oldValue = (String)field.get(obj);

					//将旧值中的b全部替换成a
					String newValue = oldValue.replace('b','a');

					//将新值赋给该对象的这个字段
					field.set(obj,newValue);
				}
				catch (IllegalArgumentException | IllegalAccessException e)
				{
					e.printStackTrace();
				}
			}	
		}
		
	}

	//打印一个对象
	private static void printObject(Object obj)
	{
		Class clazz = obj.getClass();

		if(clazz.isArray())
		{
			int length = 0;
			try
			{
				//数组的反射
				length = Array.getLength(obj);
			}
			catch (IllegalArgumentException e)
			{
				e.printStackTrace();
			}

			for(int i=0;i<length;i++)
			{
				Object objValue = null;
				try
				{
					//数组的反射
					objValue = Array.get(obj,i);
				}
				catch (IllegalArgumentException |ArrayIndexOutOfBoundsException e)
				{
					e.printStackTrace();
				}
				System.out.println(objValue);
			}
		}
		else
		{
			System.out.println(obj);
		}
	}
}

//此类用于反射相关方法的简单使用
class ReflectObject
{
	private int x;
	private int y;

	private String strOne = "ball";
	private String strTwo = "basketball";
	private String strThree = "itheima";

	public ReflectObject(int x,int y)
	{
		this.x = x;
		this.y = y;
	}
	
	//此处重写toString方法是为了方便查询String类型的变量的取值
	public String toString()
	{
		return strOne+" : "+strTwo+" : "+strThree;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值