package com.liujing;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class ReflectTest {
/**
* @param 只要是在源程序中出现的类型都有各自的Class实例对象如 int[],void
*/
public static void main(String[] args)throws Exception {
String str1="abc";
//得到某个类型的Class实例对象的三种方式
Class cls1=str1.getClass();
Class cls2=String.class;
Class cls3=Class.forName("java.lang.String");
System.out.println(cls1==cls2);//true
System.out.println(cls2==cls3);//true
System.out.println(cls1.isPrimitive());//false
System.out.println(int.class==Integer.class);//false
System.out.println(int.class==Integer.TYPE);//true
System.out.println(int.class.isPrimitive());//true
System.out.println(int[].class.isArray());//true
//new String(new StringBuffer("abc"));
//构造方法的反射
//第一个StringBuffer:根据参数类型的Class实例对象得知需要对哪个构造方法反射
Constructor constructor= String.class.getConstructor(StringBuffer.class);
//第二个StringBuffer:调用获得的方法时需要用到上面相同类型的实例对象
String str2=(String)constructor.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(2));
String str3=String.class.newInstance();//调用String类的无参构造方法
//System.out.println(str3);
//成员变量的反射
ReflectPoint pt1=new ReflectPoint(3,5);
Field fieldY=pt1.getClass().getField("y");
//fieldY的值是多少?5 错,fieldY不是对象身上的值,而是类上的,要用它去取具体某个对象的变量的值
System.out.println(fieldY.get(pt1));
Field fieldX=pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);//暴力反射
System.out.println(fieldX.get(pt1));
changeStringValue(pt1);
System.out.println(pt1);
//成员方法的反射
Method methodCharAt=String.class.getMethod("charAt", int.class);
System.out.println(methodCharAt.invoke(str1, 1));//如果invoke方法一个参数为null,说明该Method对象对应的方法是一个静态方法
System.out.println(methodCharAt.invoke(str1, new Object[]{2}));
//TestArguments.main(new String[]{"aaa","bbb"});
//用反射的方式去执行另一个类的main方法(接受数组参数的成员方法),写代码时并不知道执行哪个类
String startingClassName=args[0];
Method mainMethod=Class.forName(startingClassName).getMethod("main",String[].class);
mainMethod.invoke(null, new Object[]{new String[]{"aaa","bbb","ccc"}});//编译器会将数组拆开,会出现参数不匹配,需做特殊处理
//数组的反射 (基本数据类型的数组不能转化成Object数组如int[],而引用数据类型可以如String[])
int[] a1=new int[]{1,2,3};
String []a2=new String[]{"a","b","c"};
System.out.println(Arrays.asList(a2));
printObj(a2);
printObj("xyz");
}
private static void printObj(Object obj) {
if(obj.getClass().isArray())
{
int len = Array.getLength(obj);
for (int i = 0; i < len; i++) {
System.out.println(Array.get(obj, i));
}
}else{
System.out.println(obj);
}
}
/**
* 用反射的方式将pt1中所有String类型的变量中的'b'改为'a'
*/
private static void changeStringValue(ReflectPoint pt1)throws Exception {
// TODO Auto-generated method stub
Field[]fields=pt1.getClass().getFields();
for(Field field:fields){
if(field.getType()==String.class){
String oldValue=(String)field.get(pt1);
String newValue=oldValue.replace('b', 'a');
field.set(pt1, newValue);
}
}
}
}
class TestArguments{
public static void main(String[] args) {
for (String arg:args) {
System.out.println(arg);
}
}
}
class ReflectPoint {
private int x;
public int y;
public String str1="ball";
public String str2="basketball";
public String str3="helloworld";
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public String toString()
{
return str1+" "+str2+" "+str3;
}
}
反射
最新推荐文章于 2021-10-02 22:32:26 发布