Java反射机制(2)

反射的定义:反射就是把Java类中的各种成分映射成相应的Java类


(1)如何获取某一个类的所有的构造方法:

   

public class Test {
     public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		String str1 = new String(new StringBuffer("abc"));//正常的New一个字符串为“abc”
		/**得到参数为Stringbuffer的构造方法**/
		//得到String参数为StringBuffer的构造方法的字节码
		Constructor constructor = String.class.getConstructor(StringBuffer.class);
		//通过对应的字节码的构造方法直接去创建一个值为“abc”的对象
		String str2 = (String) constructor.newInstance(new StringBuffer("abc"));
		char a = str1.charAt(0);
		char b = str2.charAt(0);
		System.out.println(a==b);//true
		System.out.print(str1 == str2);//由于是两个不同的对象,所以返回的是false
		
		/***直接获取一个没有参数的String构造方法的对象****/
		Object obj2 = Constructor.class.newInstance();
	}
}


(2)通过相应的反射去获取对应的属性

     

package com.omg.demo;

public class ReflectPoint {
	private int x;
	private int y;
    private String a = "basketball";
    private String b = "behiand";
    private String c = "brave";
    public String d = "all";
	
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
    
	public String toString(){
		return "a:"+a+"b:"+b+"c:"+c+"d:"+d;
	}
	
}


package com.omg.demo;

import java.lang.reflect.Field;

/**
 * @author Administrator
 * 
 */
public class ChangeStringValueTest {
	public static void main(String[] args) throws Exception {
		 ReflectPoint reflectPoint = new ReflectPoint(2, 3);
		 /*****针对私有的成员变量,我们可以用getDeclaredField()获取其对应的一份字节码*****/
	     Field field = ReflectPoint.class.getDeclaredField("x");
	     field.setAccessible(true);//为了方便获取该属性的值,必须对其进行暴力反射
	     Integer a = (Integer) field.get(reflectPoint);//获得该对象上的a的属性的值
	     System.out.println(a);
         change(reflectPoint);
         System.out.println(reflectPoint.toString());
	}
	/**
	 * 这个例子主要将ReflectPoint对象中的属性为String类型中带有a的字符串全部替换成b
	 * @param obj
	 * @throws Exception
	 */
	public static void change(Object obj) throws Exception{
		Field[] fields = obj.getClass().getDeclaredFields();
	     if(fields!=null&&fields.length>0){
	    	 for(Field everyField:fields){
	    		 everyField.setAccessible(true);
	    		 Object ob = everyField.get(obj);
//	    		 if(ob instanceof String){(用此种方式进行判断强转也是可取的)
	    		 /**表示如果对应的属性的字节码为String字节码,此时获取对应String的内容,将其中的a转换成b*****/
	    		 if(everyField.getType()==String.class){
	    			 String newStr = (String)ob;
	    			 String str1 = newStr.replaceAll("a", "b");
	    			 everyField.set(obj, str1);//前者指当前类的对象,后者指的是其被设置好的属性的值
	    		 }
//	    		 }
	    	 }
	     }
	}
}
//最后打印出的属性的值为:a:bbsketbbllb:behibndc:brbved:bll
</pre><pre name="code" class="java"></pre><pre name="code" class="java"><strong>(3)通过相应的反射去获取一个方法的反射,具体的实例如下</strong>
<strong>
</strong>
<pre name="code" class="java">package com.omg.demo;

import java.lang.reflect.Method;

/**
 * @author jianhao.lu
 * 将方法进行反射的实例
 */
public class MethodReflect {
      public static void main(String[] args) throws Exception {
		 /******非静态方法的常用的反射技巧*****/
    	 String test = "abc";
		 Method method = String.class.getMethod("charAt", Integer.TYPE);
		 char str = (char) method.invoke(test, 1);//前一个参数传入指定的对象,后一个参数表示的具体的位子参数
		 System.out.println(str);
		 
		 /****静态方法的常用的反射技巧************/
//		 String arg = args[0];(在eclipse中如果设置传入的参数为com.omg.demo.staticTest),此时效果等同于以下方式
		 String arg = "com.omg.demo.staticTest";
		 Method strMethod  = Class.forName(arg).getMethod("main", String[].class);
		 /****此处如果传入单纯的String[]字符串,jvm会将数组的参数当做分开的参数传入,此时就会产生参数多余的错误,传入的是数组,所以
		  * 此时应该将这个数组当做完整的一个对象进行传入*******/
		 strMethod.invoke(null, new Object[]{new String[]{"111","22"}});
	}
}

class staticTest{
	public static void main(String[] args) {
		if(args!=null&&args.length>0){
			for(String arg : args){
				System.out.println(arg);
			}
		}
	}
}


 

(4)在反射中关于数组的一些反射的应用

package com.omg.demo;

import java.lang.reflect.Array;

/**
 * @author jianhao.lu 数组的反射
 */
public class ArrayReflectDemo {
	public static void main(String[] args) {
         int[] a1 = new int[]{1,2,3};
         String [] a2 = new String[]{"a","b","c"};
         printArray(a2);
         printArray(a1);
         printArray("abx");
	}
	
	/**
	 * 将数组进行反射的应用
	 * @param obj
	 */
	public static void printArray(Object obj){
		Class cls = obj.getClass();
		/*****如果是数组的话,那么通过反射打印数组中的元素的值*****/
		if(cls.isArray()){
			int length = Array.getLength(obj);
			if(length>0){
				for(int i = 0;i<length;i++){
					System.out.println(Array.get(obj, i));
				}
			}
		}else{
			/****如果不是数组的话,那么此时打印出该类的类名******/
			System.out.println(obj.getClass().getName());
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值