反射機制:Class,Field,Method,Construts,Array
import java.lang.reflect.Method;
public class DumpMethods
{
public static void main(String[] args) throws Exception
{
Class<?> classType = Class.forName(args[0]);//"java.lang.String"//得到一個class對象
Method[] methods = classType.getDeclaredMethods();//得到所有聲明方法
for(Method method : methods)
{
System.out.println(method);
}
}
}
//反射類的對象,並調用方法
public class InvokeTester
{
public int add(int param1, int param2)
{
return param1 + param2;
}
public String echo(String message)
{
return "hello: " + message;
}
public static void main(String[] args) throws Exception
{
// InvokeTester test = new InvokeTester();
// System.out.println(test.add(1, 2));
// System.out.println(test.echo("tom"));
Class<?> classType = InvokeTester.class;//還有兩種方式forName()、object.getClass():
Object invokeTester = classType.newInstance();
// System.out.println(invokeTester instanceof InvokeTester);
Method addMethod = classType.getMethod("add", new Class[] { int.class,
int.class });
Object result = addMethod.invoke(invokeTester, new Object[]{1, 2});
System.out.println((Integer)result);
System.out.println("---------------------");
Method echoMethod = classType.getMethod("echo", new Class[]{String.class});
Object result2 = echoMethod.invoke(invokeTester, new Object[]{"tom"});
System.out.println((String)result2);
}
}
//反射機制的使用
public class ReflectTester
{
// 該方法實現對Customer對象的拷貝操作
public Object copy(Object object) throws Exception
{
Class<?> classType = object.getClass();//這是第三種方式反射類
Object objectCopy = classType.getConstructor(new Class[] {})
.newInstance(new Object[] {});//其實裏面的參數new Object[]{},如果是不帶參數的構造方法,則可以用null來代替。
// 獲得對象的所有成員變量
Field[] fields = classType.getDeclaredFields();
for (Field field : fields)
{
String name = field.getName();
String firstLetter = name.substring(0, 1).toUpperCase();// 將屬性的首字母轉換爲大寫
String getMethodName = "get" + firstLetter + name.substring(1);//這個字符串截取相當於name.substring(1,name.length);
String setMethodName = "set" + firstLetter + name.substring(1);
Method getMethod = classType.getMethod(getMethodName,
new Class[] {});
Method setMethod = classType.getMethod(setMethodName,
new Class[] { field.getType() });//這個field.getType()類似int.class
Object value = getMethod.invoke(object, new Object[] {});//object對象已經的參數已經被賦值 new Object[]{}是null
setMethod.invoke(objectCopy, new Object[] { value });objectCopy對象本來是null的,但被賦值後,就是object
}
// 以上兩行代碼等價於下面一行
// Object obj2 = classType.newInstance();
// System.out.println(obj);
return objectCopy;
Array動態反射數組介紹
public class ArrayTester1
{
public static void main(String[] args) throws Exception
{
Class<?> classType = Class.forName("java.lang.String");
Object array = Array.newInstance(classType, 10);//表示String字符串的長度是10
Array.set(array, 5, "hello");//設置index是5的值
String str = (String)Array.get(array, 5);得到對應的值
System.out.println(str);
}
}
Array的實例化多維數組
public class ArrayTester2
{
public static void main(String[] args)
{
int[] dims = new int[] { 5, 10, 15 };
Object array = Array.newInstance(Integer.TYPE, dims);
System.out.println(array instanceof int[][][]);
Object arrayObj = Array.get(array, 3);
arrayObj = Array.get(arrayObj, 5);
Array.setInt(arrayObj, 10, 37);
int[][][] arrayCast = (int[][][]) array;
System.out.println(arrayCast[3][5][10]);
// System.out.println(Integer.TYPE);//int,它返回的是原生數據類型,相當於int.class
// System.out.println(Integer.class);//class java.lang.Integer
}
}
輸出結果:true
37
//得到反射類的層次結構
public class ClassTest
{
public static void main(String[] args)
{
Class<?> classType = Child.class;
System.out.println(classType);//Child
classType = classType.getSuperclass();
System.out.println(classType);//Parent
classType = classType.getSuperclass();
System.out.println(classType);//Object
classType = classType.getSuperclass();
System.out.println(classType);//null
}
}
class Parent
{
}
class Child extends Parent
{
}
//用反射機制獲取類中private的方法
public class Private
{
private String sayHello(String name)
{
return "hello: " + name;
}
}
public class TestPrivate
{
public static void main(String[] args) throws Exception
{
Private p = new Private();
Class<?> classType = p.getClass();
Method method = classType.getDeclaredMethod("sayHello",
new Class[] { String.class });//這裏必須用DeclaredMethod方法,因爲它可以訪問private,而getMethod僅僅能訪問公共的修飾符,不能訪問私有。
method.setAccessible(true);//壓制Java的訪問控制檢查,設置爲true表示可以訪問private
String str = (String)method.invoke(p, new Object[]{"zhangsan"});
System.out.println(str);
}
}
//用反射機制訪問私有屬性
public class Private2
{
private String name = "zhangsan";
public String getName()
{
return name;
}
}
public class TestPrivate2
{
public static void main(String[] args) throws Exception
{
Private2 p = new Private2();
Class<?> classType = p.getClass();
Field field = classType.getDeclaredField("name");
field.setAccessible(true);//壓制Java對訪問修飾符的檢查
field.set(p, "lisi");
System.out.println(p.getName());
}
}