反射的定义:反射就是把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();
}
}
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());
}
}
}