java构造方法、成员变量、方法所对应的反射实例

最原始的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;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值