最原始的class类中包含着一些构造器,包,方法,属性等等内容,我们可以通过字节码文件得到对应的一个构造器
,并指明是那种构造器通过参数进行设置,然后通过Constructior类进行实例对象
package test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* @author Dqd
* 构造方法的反射 Constructor类
* 成员变量的反射 Field类
* 方法的反射 Method类
* 通过反射的方式调用main方法
*
*/
public class test {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
//构造方法的反射,通常通过类得到构造器然后通过newInstance()来创建实例
Constructor<?>[] con = stu.class.getConstructors();
stu st1 = (stu)con[0].newInstance(3,4);
//通过getField来得到可以访问的变量,然后Field变量对应到相应的实力上取出对应值
//如果我们通过st1.getClass().getField("x"),因为X为私有所以不能访问但是可以通过DeclaredField访问
//尚若查看需要用到包级反射,修改权限,最后才能打印
Field f = st1.getClass().getDeclaredField("x");
f.setAccessible(true);
System.out.println(f.get(st1));
//通过修改字节码文件来对String类型中的'a'改变成为'b'
changeCharAtoB(st1);
System.out.println(st1);
//方法的反射
String str="abc";
Method methodCharAt = String.class.getMethod("charAt", int.class);
//invoke作用于那个对象的身上(对象和方法没有什么关系)
System.out.println(methodCharAt.invoke(str, 1));
//如果invoke()的第一个参数为null,那么意味是静态的方法
//正常的情况下我们调用main方法
/*TestArguements.main(new String[]{"123","456"});*/
//通过反射来调用,为什么要通过反射去掉用呢?我们可能会遇到给main方法传一些参数但是不知道去执行哪个类
String starClassName = args[0];
Method mainMethod = Class.forName(starClassName).getMethod("main", String[].class);
//这里使用一个object[]的原因是java传进去数组,会自动的拆开String相当于传了两个参数而实际上只需要一个
mainMethod.invoke(null,new Object[]{ new String[]{"123","456"}});
//或者使用下面的
//mainMethod.invoke(null,( Object)new String[]{"123","456"});
int [] a1 = {1,2,3};
int[][] a2 = new int[2][3];
String[] a3 = {"123","456"};
//输出的结果分别是[[I@10eb6ae],[123, 456]后者属于Object[](因为接收时分为Object[]和<T>类型),而String[]符合
//但是int[]不符合只能按照jdk1.4的以对象形式输出
System.out.println(Arrays.asList(a1));
System.out.println(Arrays.asList(a3));
}
public static void changeCharAtoB(Object obj) throws IllegalArgumentException, IllegalAccessException{
Field[] fields = obj.getClass().getFields();
for(Field f:fields){
//if(f.getType().equals(String.class){
//字节码的比较使用等号因为实用的字节码
if(f.getType()==String.class){
String oldVal = (String) f.get(obj);
String newVal = oldVal.replace('a', 'b');
f.set(obj, newVal);
//System.out.println(newVal);
}
}
}
}
class TestArguements{
public static void main(String[] args){
for(String s:args){
System.out.println(s);
}
}
}
stu:
package test;
public class stu {
private int x;
public int y;
public String str1="ball";
public String str2 = "basket";
public stu(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return str1 +'\n'+" "+str2;
}
}