Java反射的簡單入門
阿新 • • 發佈:2018-11-24
ceo 對象 exceptio 是不是 入門 port .com ssi get
1.Class的簡單介紹
Class類的類表示正在運行的Java應用程序中的類和接口。 枚舉是一種類,一個註解是一種接口, 每個數組也屬於一個反映為類對象的類,該對象由具有相同元素類型和維數的所有數組共享。 原始Java類型( boolean
, byte
, char
, short
, int
, long
, float
和double
),和關鍵字void
也表示為類對象。
摘自jdk1.8中文版,剛開始看可能不懂,現在逐句來解釋一下。
第一句話:一個類被加載以後,JVM就會在內存中給創建一個對應類的Class對象。
第二句話:類型相同的對象,維數相同的數組(不管長度)共享的是同一個內存中的Class對象。
第三句話:上面這些原始的類型,也會在內存中有一個與之對象的Class對象。
package com.dingyu; import org.junit.Test; /** * Class的簡單使用方法 * * @author 70241 * */ public class ClassDemo { @Test public void classTest1() { try { Class class1 = Class.forName("com.dingyu.User");// 第一種獲取Class對象的方法 User user = newUser(); Class class2 = user.getClass();// 第二種獲取Class對象的方法 Class class3=User.class;//第三種獲取Class對象的方法 System.out.println("接下來判斷到底同一類的不同對象的Class對象是不是同一個:" + (class1.hashCode() == class2.hashCode()&&class1.hashCode() == class3.hashCode())); }catch (ClassNotFoundException e) { e.printStackTrace(); } } @Test public void classTest2() { String[] s1 = new String[10]; String[] s2 = new String[30]; String[][] s3 = new String[3][30]; System.out.println(s1.getClass().hashCode()==s2.getClass().hashCode()); System.out.println(s1.getClass().hashCode()==s3.getClass().hashCode()); } }
2.Class獲取類的屬性,構造器,方法和註解的簡單使用
package com.dingyu; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; /** * Class的簡單用法 * * @author dingyu * */ public class ClassDemo02 { @Test public void usingClass() throws Exception { Class userClass = Class.forName("com.dingyu.User"); // 獲得類名 System.out.println(userClass.getName());// 獲得全類名 System.out.println(userClass.getSimpleName());// 獲得類名 // 獲得屬性 Field[] fields = userClass.getDeclaredFields();// 獲得所有的屬性 for (Field field : fields) { System.out.println(field.getName()); } System.out.println(userClass.getDeclaredField("id").getName());// 獲得指定的屬性 // 獲得方法 Method[] methods = userClass.getDeclaredMethods();// 獲得所有的方法 for (Method method : methods) { System.out.println(method.getName()); } Method method = userClass.getDeclaredMethod("setId", int.class);// 獲得指定的方法,前面方法名,後面方法的參數 System.out.println(method.getName()); // 獲得構造器 Constructor[] constructors = userClass.getDeclaredConstructors(); System.out.println(constructors.length); Constructor constructor = userClass.getDeclaredConstructor(int.class, String.class, int.class);// 獲得指定的構造器,需要指定構造的參數 System.out.println(constructor.getName()); // 獲得註解 Annotation[] annotations = userClass.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } // 指定註解名 MyAnnotation annotation = (MyAnnotation)userClass.getDeclaredAnnotation(MyAnnotation.class); System.out.println(annotation); } }
3.Class動態的調用構造器,方法,修改屬性
package com.dingyu; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; /** * 使用反射動態的調用構造器,方法,修改屬性 * @author 70241 * */ public class ClassDemo03 { @Test @SuppressWarnings("all") public void usingClass() throws Exception { Class class1 = Class.forName("com.dingyu.User"); //使用反射去調用構造器 User user1 = (User) class1.newInstance();//調用的是無參的 Constructor constructor = class1.getDeclaredConstructor(int.class,String.class,int.class);//獲得有參的構造器 User user2 = (User) constructor.newInstance(04,"dingyu",20);//動態生成對象 //使用反射去調用方法 Method methodSetId = class1.getDeclaredMethod("setId",int.class); methodSetId.invoke(user1, 02);//執行user1中的setId,後面是給的參數 System.out.println(user1.getId()); //使用反射去修改屬性的值 Field field = class1.getDeclaredField("age"); field.setAccessible(true);//因為age是私有的,加上這句就表示這個屬性不需要做安全檢查 field.set(user1, 20); System.out.println(field.get(user1)); System.out.println(user1.getAge()); } }
4.反射獲得帶泛型的參數或返回值裏泛型的的類型
package com.dingyu; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Map; /** * 反射獲得帶泛型的參數或返回值裏泛型的的類型 * @author dingyu * */ public class ClassDemo04 { public void test01(Map<Integer, String> map, String s) { } public Map<Integer, String> test02() { return null; } public static void main(String[] args) throws Exception { //參數中帶泛型的 Method method = ClassDemo04.class.getDeclaredMethod("test01", Map.class, String.class); Type[] types = method.getGenericParameterTypes();// 返回一個 Type對象的數組, Type以聲明順序表示由該對象表示的可執行文件的形式參數類型 // 打印這些參數的類型 for (Type type : types) { System.out.println(type.getTypeName()); if (type instanceof ParameterizedType) {// 如果是泛型的參數 Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();// 獲得泛型的的類型 for (Type type2 : actualTypeArguments) { System.out.println(type2.getTypeName()); } } } //返回值中帶泛型的 Method method02 = ClassDemo04.class.getDeclaredMethod("test02"); Type type = method02.getGenericReturnType();// 返回的類型 // 打印這些返回的類型 System.out.println(type.getTypeName()); if (type instanceof ParameterizedType) {// 如果是泛型的參數 Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();// 獲得泛型的的類型 for (Type type2 : actualTypeArguments) { System.out.println(type2.getTypeName()); } } } }
Java反射的簡單入門