轉載自https://www.cnblogs.com/sargeles/p/6605945.html
java通常是先有類再有對象,有對象我就可以調用方法或者屬性。
-
package Reflect; /** * 通過一個對象獲得完整的包名和類名 * */ class Demo{ //other codes... } class hello{ public static void main(String[] args) { Demo demo=new Demo(); System.out.println(demo.getClass().getName()); } }
-
package Reflect; class Demo{ //other codes... } class hello{ public static void main(String[] args) { Class<?> demo1=null; Class<?> demo2=null; Class<?> demo3=null; try{ //一般儘量採用這種形式 demo1=Class.forName("Reflect.Demo"); }catch(Exception e){ e.printStackTrace(); } demo2=new Demo().getClass(); demo3=Demo.class; System.out.println("類名稱 "+demo1.getName()); System.out.println("類名稱 "+demo2.getName()); System.out.println("類名稱 "+demo3.getName()); } }
-
package reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.omg.CORBA.PUBLIC_MEMBER; /** * 五個函數:(public static void) * ClassUtil.printClassMessage(Object obj); * ClassUtil.printFieldMessage(Object obj); * ClassUtil.printConstructorMessage(Object obj); * ClassUtil.printInterfacesMessage(Object obj); * ClassUtil.printSuperclassMessage(Object obj); * * @author sargeles */ public class ClassUtil { /** * 打印類的信息,包括五個函數。 * * @param obj * */ public static void printClassMessage(Object obj) { // 要獲取類的信息,首先要獲取類的類類型 Class c = obj.getClass();// 傳遞的是哪個子類的對象,c就是該子類的類類型 // 獲取類的名稱 System.out.println("類的名稱是:" + c.getName()); System.out.println("類的成員方法有:"); /* * Method類,方法對象 一個成員方法就是一個Method對象 * getMethods()方法獲取的是所有的public的方法,包括從父類繼承而來的 * getDeclareMethods()獲取的是所有該類自己聲明的方法,不問訪問權限 */ Method[] ms = c.getMethods(); for (Method m : ms) { // public int getModifiers()方法是公有的,可以獲取修飾符信息,將其包裝成一個int。 int mo = m.getModifiers(); // Modifier封裝瞭解讀帶有修飾符信息的int的方法。這些方法都是靜態的。可以直接用。 System.out.print(Modifier.toString(mo) + " "); // 得到方法返回值類型的類類型 Class returnType = m.getReturnType(); System.out.print(returnType.getName() + " "); // 得到方法的名稱 System.out.print(m.getName() + "("); // 獲取參數類型--->得到的是參數列表的類型的類類型 Class[] paramTypes = m.getParameterTypes(); for (int i = 0; i < paramTypes.length; i++) { if (i > 0) System.out.print(","); System.out.print(paramTypes[i].getName()); } System.out.println(")"); } } /** * 獲取成員變量的信息(自己聲明的) * * @param obj */ public static void printFieldMessage(Object obj) { // 要獲取類的信息,首先要獲取類的類類型 Class c = obj.getClass();// 傳遞的是哪個子類的對象,c就是該子類的類類型 System.out.println("類的名稱是:" + c.getName()); System.out.println("類的成員變量有:"); /* * 成員變量也是對象 java.lang.reflect.Field Field類封裝了關於成員變量的操作 * getFields()方法獲取的是所有public的成員變量的信息 * getDeclaredFields()獲取的是該類自己聲明的成員變量的信息 */ Field[] fs = c.getDeclaredFields(); for (Field field : fs) { // 獲得成員變量的類型的類類型 Class fieldType = field.getType(); String typeName = fieldType.getName(); // 得到成員變量的名字 String fieldName = field.getName(); System.out.println(typeName + " " + fieldName); } } /** * 獲取類的構造函數信息 * * @param obj */ public static void printConstructorMessage(Object obj) { Class c = obj.getClass(); System.out.println("類的名稱是:" + c.getName()); System.out.println("類的構造函數有:"); /* * 構造函數也是對象 java.lang.Constructor中封裝了構造函數的信息 * getConstructors獲取所有的public的構造函數 getDeclaredConstructors得到所有的構造函數 */ Constructor[] cs = c.getDeclaredConstructors(); for (Constructor constructor : cs) { // java.lang.Class.getModifiers()方法是公有本地的,可以獲取修飾符信息,將其包裝成一個int。 int mo = constructor.getModifiers(); // Modifier封裝瞭解讀帶有修飾符信息的int的方法。這些方法都是靜態的。可以直接用。 System.out.print(Modifier.toString(mo) + " "); System.out.print(constructor.getName() + "("); // 獲取構造函數的參數列表--->得到的是參數列表的類類型 Class[] paramTypes = constructor.getParameterTypes(); for (int i = 0; i < paramTypes.length; i++) { if (i > 0) System.out.print(","); System.out.print(paramTypes[i].getName()); } System.out.println(")"); } } /** * 類的接口信息 * * @param obj */ public static void printInterfacesMessage(Object obj) { Class c = obj.getClass(); System.out.println("類的名稱是:" + c.getName()); System.out.println("類實現的接口有:"); /* * 接口類也是對象,因爲接口也是類類型的一種,所以是Class的泛型。 */ Class[] intes = c.getInterfaces(); for (Class classes : intes) { // 獲取每個接口的名字,然後輸出。 System.out.println(classes.getName()); } } /** * 類的父類信息 * * @param obj */ public static void printSuperclassMessage(Object obj) { Class c = obj.getClass(); System.out.println("類的名稱是:" + c.getName()); System.out.print("類的父類是:"); /* * 父類只可能有一個,所以不用遍歷,單根繼承。 */ Class superclass = c.getSuperclass(); System.out.println(superclass.getName()); } }
-
public class InvokeDemo { private String st="invoke"; int[] i={1,5,6,9,8,2}; public void add1(int a, int b) { System.out.println(a + b); } public static void add2(int a, int b) { System.out.println(a + b); } } public class InvokeTest { public static void main(String[] args) { try { //獲取測試樣例的類類型和測試實例 Class<?> c = Class.forName("reflect.InvokeDemo"); Object obj = c.newInstance(); //反射調用 Method m = c.getMethod("add1",int.class,int.class); int[] i={1,2}; m.invoke(obj,i[1],i[0]); //沒有必要通過反射調用的static方法 InvokeDemo.add2(1, 3); //反射修改屬性 Field field = c.getDeclaredField("st") //使得這個屬性可以被修改,無論它是否是私有,甚至final。 field.setAccessible(true); field.set(obj, "男"); System.out.println(field.get(obj)); } catch (Exception e) { e.printStackTrace(); } } }
3
4
男
-
java.lang.IllegalAccessException: Class com.test.accessible.Main can not access a member of class com.test.accessible.AccessibleTest with modifiers "private"
-
public class InvokeTest2 { public static void main(String[] args) { String str = "I'm not changed!"; change(str); System.out.println(str); } static void change(String str){ try { Class<?> clazz = str.getClass(); Field field = clazz.getDeclaredField("value"); field.setAccessible(true); Object obj = field.get(str); char[] charValue = (char [] )obj; charValue = new char [str.length()]; String st = "I'm changed!"; charValue = st.toCharArray(); field.set(str, charValue); } catch (Exception e) { e.printStackTrace(); } } }