/*
*反射,用于获取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;
}
}Reflect
最新推荐文章于 2025-07-30 09:31:04 发布
1145

被折叠的 条评论
为什么被折叠?



