java反射,JavaBean

 
 
package cn.sxt.t01; import java.util.Arrays; public class Users { public Integer id; public String name; private String email; private String password; @Override public String toString() { return "Users [id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + "]"; } public Users(){ System.out.println("我是無參數構造器!!!!"); } public Users(String name){ System.out.println("我是有參數構造器 :"+name); } private Users(String name,Integer age){ System.out.println("我叫 :"+name+", 今年 :"+age); } public void say(){ System.out.println("你好,世界"); } public void hello1() { System.out.println("我是無參數無返回值方法"); } public String hello2(String name) { return "你好 :"+name; } private String hello3(String name,int age) { return "我是 :"+name+",今年 :"+age; } public static void staticMethod(String name) { System.out.println("我是靜態方法 :"+name); } public static void method1(int...intArr) { System.out.println(Arrays.toString(intArr)); } public static void method2(String[] strArr) { System.out.println(Arrays.toString(strArr)); } }
 
 

 





package
cn.sxt.t01; import static org.junit.Assert.*; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Date; import java.util.Iterator; import org.junit.Test; public class ClassTest01 { private static Date getObject; /*反射:(reflection):在運行時期,動態地去獲取類中的信息(類的信息,方法信息,構造器信息,字段等信息進行操做); 一個類中包含的信息有: 構造器,字段,方法 如何使用反射描述這些相關的信息 Class : 描述類 Method : 描述方法 Constructor :描述構造器 Field :描述字段 * */ @Test public void testName() throws Exception { //編譯類型 //運行類型(真實類型) Object obj = new java.util.Date(); //需求:根據對象obj調用Date類中的一個方法,toLocaleString,如何來作? //方案一: 強轉 Date d = (Date)obj; System.out.println(d.toLocaleString()); } //方案二: 使用反射 public Object getObject() { return new java.util.Date(); } @Test//獲取類的Class實例三種方式 public void testName1() throws Exception { /* * 在任何反射的操做以前,都必須先獲取某一個類的字節碼實例,任何一個類在jvm有且只有一份字節碼實例 * * 獲取字節碼實例有三種方式 * 1. 類名.class; * 2. 對象.getClass(); * 3. Class.forName("類的全限定名"); * 全限定名 = 包名+類名 * */ // 需求:獲取User類的字節碼實例 // 1. 類名.class; Class<Users> clz1=Users.class; System.out.println(clz1); // 2. 對象.getClass(); Users users=new Users(); Class<?> clz2= users.getClass(); System.out.println(clz2); // 3. Class.forName("類的全限定名"); // 全限定名 = 包名+類名 Class<?> clz3 = Class.forName("cn.sxt.t01.Users"); System.out.println(clz3); } @Test//獲取九大內置類的字節碼實例 public void testName2() throws Exception { /*對於對象來講,能夠直接使用對象.getClass()或者Class.forName(className); 類名.class均可以獲取Class實例. 可是咱們的基本數據類型,就沒有類的權限定名,也沒有getClass方法. 問題: 那麼如何使用Class類來表示基本數據類型的Class實例? 八大基本數據類型和 void關鍵字都是有 字節碼實例的 byte,short,int,long,char,float,double,boolean ,void關鍵字 答 : 數據類型/void.class 便可 每一個基本數據類型都是包裝類型 如 :int ----Integer包裝類型 注意: 基本數據類型和包裝數據類型底層的字節碼實例是不相同 */ //數據也是一種數據類型,也須要單獨獲取字節碼實例 Class clz = 數據類型[].class //獲取8大基本數據類型和void的字節碼實例(以int,integer爲列) // 1.獲取int類型的字節碼實例 Class<?> intClz=int.class; System.out.println(intClz); // 其餘七種基本數據類型 和 第一種類似.... // 獲取void的字節碼實例 Class <?> voidClz=void.class; System.out.println(voidClz); // 全部的基本數據類型都有包裝類型 // int---Integer // int 和Integer 的字節碼是絕對不相等的 Class<Integer> integeClz=Integer.class; System.out.println(integeClz); System.out.println(intClz == integeClz);//false // 直接經過數組類型獲取字節碼實例 Class<int[]> clz1=int[].class; System.out.println(clz1); // 定義一個數據 int[] arr1 = { 1, 2, 3, 5 }; Class<int[]> clz2=(Class<int[]>)arr1.getClass(); System.out.println(clz2); // 定義一個數據 int[] arr2 = { 10, 2, 3, 5 }; // 3.獲取arr1數組的字節碼實例 Class<int[]> clz3 = (Class<int[]>) arr2.getClass(); System.out.println(clz3); System.out.println(clz1 == clz2);//true System.out.println(clz3 == clz2);//true //因此不一樣數組的字節碼實例是相同的 } @Test public void testName3() throws Exception { /*類的構函數有 有參數構造函數,無參構造函數,公共構造函數,非公共構造函數,根據不一樣的構造函數 Class提供了幾種獲取不一樣構造函數的方法 * * * 獲取Users類的構造器 * * 1.獲取Users類的字節碼實例 * 2.獲取Users對應的構造器 */ //1.獲取Users類的字節碼實例 Class<Users> stu=Users.class; //2.獲取全部的公共構造器 Constructor<?>[] constructors = stu.getConstructors(); for(Constructor<?> constructor:constructors){ System.out.println(constructor); } //3.獲取全部的構造器(和訪問權限無關) Constructor<?>[] de = stu.getDeclaredConstructors(); for(Constructor<?> constructor : de){ System.out.println(constructor); } //4.獲取指定的構造器(公共的)getConstructor Constructor<Users> constructor1 = stu.getConstructor(String.class); System.out.println(constructor1); //5. getDeclaredConstructor 獲取和訪問權限無關構造器 Constructor<Users> constructor2 = stu.getDeclaredConstructor(String.class,Integer.class); System.out.println(constructor2); } @Test public void testName4() throws Exception { /*調用構造器,建立對象 Constructor<T>類:表示類中構造器的類型,Constructor的實例就是某一個類中的某一個構造器 經常使用方法: public T newInstance(Object... initargs):如調用帶參數的構造器,只能使用該方式. 參數:initargs:表示調用構造器的實際參數 返回:返回建立的實例,T表示Class所表示類的類型 若是:一個類中的構造器能夠直接訪問,同時沒有參數.,那麼能夠直接使用Class類中的newInstance方法建立對象. public Object newInstance():至關於new 類名(); 調用私有的構造器: * * */ //需求: 使用反射建立Student的java對象 //1.獲取字節碼實例 //Class<?> clz = Class.forName("cn.sxt.t01.Users"); Class<Users> clz = (Class<Users>)Class.forName("cn.sxt.t01.Users"); //2.獲取指定構造器 Constructor<Users> cons1 = clz.getConstructor(String.class); //2.1獲取私有構造函數 Constructor<Users> cons2 = clz.getDeclaredConstructor(String.class,Integer.class); //3.建立對象 //3.1. 若是當前類的字節碼有一個無參公共數構造器,能夠直接使用字節碼實例直接建立對象 Users n= clz.newInstance(); n.say(); //3.2.使用構造器建立對象; Users n1 = cons1.newInstance("dewjfe"); //3.3使用私有構造函數建立 //3.3.1設置忽略訪問修飾的權限 //若是是私有構造方法,反射默認是沒法直接執行的,找到父類中AccessibleObject的方法,設置爲true,便可忽略訪問權限 cons2.setAccessible(true); Users n3 = cons2.newInstance("fewfew",20); } @Test public void testName5() throws Exception { /*操做方法-Method 一個類建立對象之後,通常就要執行對象的方法等等,使用反射操做對象 首先要獲取方法,再去執行,使用Class 獲取對應的方法: getMethods() 獲取全部的公共方法,包括父類的公共方法 getDeclaredMethods() 獲取全部本類的方法,包括本類的私有方法 getDeclaredMethod(String name, Class<?>... parameterTypes) 獲取指定方法名稱的方法,和訪問權限無關 ame : 指定的方法名稱 parameterTypes : 方法參數的類型 Method執行方法:方法獲取之後就須要執行。Method對象中提供方法執行的功能 invoke(Object obj, Object... args) 執行方法 Obj :若是是對象方法,傳指定的對象,若是是類方法,傳 null Args: 方法的參數 若是方法有返回結果,能夠接收 獲取方法和方法的執行 一個類中的方法有不少,無參,有參,靜態,可變參數私有方法,等等,針對不一樣的方法處理,提供了不一樣的獲取方案 */ /* * 需求:獲取Users類的方法 */ //1.獲取Users的字節碼實例 Class<Users> clz=Users.class; //2.經過類的字節碼直接建立對象(必須保證類有一個無參數公共構造函數) Users newInstance = clz.newInstance(); //3.獲取方法 //3.1獲取全部的公共方法(包含父類的方法) Method[] methods = clz.getMethods(); for (Method method : methods) { System.out.println(method); } //3.2獲取當前類的全部的方法(不包含父類,和訪問權限無關,成員或者靜態方法都獲取) Method[] de = clz.getDeclaredMethods(); for (Method method :de) { System.out.println(method); } //3.3獲取指定名稱的方法 Method hello1 = clz.getMethod("hello1"); System.out.println(hello1); //3.4 獲取私有方法 Method hello3 = clz.getDeclaredMethod("hello3", String.class,int.class); System.out.println(hello3); //3.5獲取靜態方法 Method staticMethod = clz.getDeclaredMethod("staticMethod", String.class); System.out.println(staticMethod); //3.6獲取有數組參數的方法 Method method1 = clz.getDeclaredMethod("method1", int[].class); System.out.println(method1); System.out.println("------------------------------------------------------------"); } @Test public void testName6() throws Exception { //1.獲取Users的字節碼實例 Class<Users> clz=Users.class; //2.經過類的字節碼直接建立對象(必須保證類有一個無參數公共構造函數) Users n = clz.newInstance(); //3.獲取方法 //3.1獲取指定名稱的方法 Method hello1 = clz.getMethod("hello1"); System.out.println(hello1); //3.1.1執行無參數對象方法 hello1.invoke(n); //3.3 獲取私有方法 Method hello3 = clz.getDeclaredMethod("hello3", String.class,int.class); System.out.println(hello3); //3.3.1設置忽略訪問權限 hello3.setAccessible(true); //3.3.2 執行私有方法 Object invoke = hello3.invoke(n, "令狐沖",30 ); System.out.println( invoke); //3.4獲取靜態方法 Method staticMethod = clz.getDeclaredMethod("staticMethod", String.class); System.out.println(staticMethod); //3.4.1執行靜態方法 staticMethod.invoke(null, "金毛獅王"); //3.5獲取基本數據類型整數組參數的方法 Method method1 = clz.getDeclaredMethod("method1", int[].class); System.out.println(method1); //3.5.1執行 數組參數的方法 int[] intArr = {1,2,5,10}; method1.invoke(null, new Object[] {intArr}); //3.6獲取基本數據類型整數組參數的方法 Method method2 = clz.getDeclaredMethod("method2", String[].class); System.out.println(method2); //3.6.1執行字符串數組參數的方法 String[] stringArr = {"A","B","D"}; //若是方法中有可變參數(數組),若是反射傳遞的可變參數是引用類型,底層有一個拆箱的功能,會將數組的元素拆成一個個參數傳遞過來 //解決方案: 將數組外面在包裝一層數組,若是拆箱一次,獲得仍是一個數組` method2.invoke(null, new Object[] {stringArr}); } @Test public void testName7() throws Exception { /*操做字段(成員變量)-Field * 類中的字段有各類數據類型和各類訪問權限,針對這些狀況,反射操做有對應的方法來獲取和處理 * getFields() 獲取當前Class所表示類中全部的public的字段,包括繼承的字段. * getDeclaredFields() 獲取當前Class所表示類中全部的字段,不包括繼承的字段. * getField(String name) 獲取當前Class所表示類中該fieldName名字的字段,不包括繼承和私有的字段. * getDeclaredField(String name):獲取當前Class所表示類中該fieldName名字的字段,不包括繼承的字段. * */ /* * Field類經常使用方法: void setXX(Object obj, XX value) :爲基本類型字段設置值,XX表示基本數據類型 void set(Object obj, Object value) :表示爲引用類型字段設置值 參數: obj: 表示字段底層所屬對象,若該字段是static的,該值應該設爲null value: 表示將要設置的值 ------------------------------------------------------------------------------------- XX getXX(Object obj) :獲取基本類型字段的值,XX表示基本數據類型 Object get(Object obj) :表示獲取引用類型字段的值 參數: obj: 表示字段底層所屬對象,若該字段是static的,該值應該設爲null 返回:返回該字段的值. * * * *set(Object obj, Object value) 設置引用類型的值,非基本數據類型 Obj: 要設置值得對象 Value : 要設置的值/ /*Field操做設置值/獲取值 * 給某個類中的字段設置值和獲取值: 1,找到被操做字段所在類的字節碼 2,獲取到該被操做的字段對象 3,設置值/獲取值 * */ /* * 需求:操做Users類的字段 */ // 1.獲取Users字節碼實例 Class<Users> clz=Users.class; // 1.1 經過字節碼實例建立對象(必須保證有一個無參數public構造器) Users n = clz.newInstance(); // 2.獲取全部public字段 Field[] fields = clz.getFields(); for (Field field : fields) { System.out.println(field); } // 3.獲取全部的字段(與訪問權限無關) Field[] declaredFields = clz.getDeclaredFields(); for (Field field : declaredFields) { System.out.println(field); } // 4.獲取指定名稱的public字段 Field field = clz.getField("name"); // 4.1爲字段設置值 /* * nameField.set(obj, value); obj : 要設置值字段對應的對象 value :具體指 */ field.set(n, "fewwwfeg"); // 5.獲取指定名稱的和訪問權限無關的字段 Field emailField = clz.getDeclaredField("email"); // 5.1 設置忽略訪問權限 emailField.setAccessible(true); // 5.2 設置私有字段的值 emailField.set(n, "xln@qq.com"); System.out.println(n); }}

 

 
 
package cn.sxt.t01; public interface User { int tymp(); }
 
 

 

 
package cn.sxt.t01; import java.util.Arrays; public class Users implements User{ @Override public int tymp() { return 0; } }
 
 

 



package
cn.sxt.t01; import static org.junit.Assert.*; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; public class ClassTest01 { @Test public void testName9() throws Exception { //1.獲取Users實現類的字節碼實例 Class<Users> clz=Users.class; //獲取字節碼的接口 //獲取字節碼的接口 Class<?>[] interfaces = clz.getInterfaces(); for (Class<?> class1 : interfaces) { System.out.println(class1); } //獲取字節碼實例的權限的名 System.out.println(clz.getName()); //獲取簡單類名 System.out.println(clz.getSimpleName()); //獲取包 System.out.println(clz.getPackage()); } }

 

JavaBean

問題: 什麼是javaBean?java

答: JavaBean就是一個個Java類,在java中符合JavaBean特色類才叫作JavaBean數組

 

 JavaBean的三個特色

  1. JavaBean類的修飾符必須是public,也就是一個JavaBean必須是一個對應一個類文件
  2. JavaBean必須有無參數公共構造方法(以便於反射直接經過直接經過字節碼實例建立對象)
  3. JavaBean中的成員變量/字段必須有get/set方法提供對應的屬性

 

 

 JavaBean中的屬性

Java類有成員變量,成員變量絕對不是屬性JavaBean中的屬性是有get/set方法肯定的jvm

 

 Get方法肯定屬性

 public String getName() {

return name;ide

}函數

屬性肯定規則 get方法去掉 get前綴 ,剩餘部分 首字母小寫工具

屬性名稱 namethis

Set方法肯定屬性

 

public void setName(String name) {spa

 

this.name = name;code

 

}對象

 

屬性肯定規則 set方法去掉 set前綴 ,剩餘部分 首字母小寫

 

 

 

屬性名稱 name

若是一個成員變量get/set方法都有肯定的屬性就只有一個

 

問題 get/set方法肯定肯定的屬性通常不就和成員變量同樣啊,爲何要有屬性了

 

答: 通常狀況下,Eclipse工具備自動生成get/set方法的功能,肯定的JavaBean的屬性只是剛好和成員變量相同,可是成員變量不是屬性

以下特殊性狀況,屬性和成員變量名稱不一樣

 

//Filed

private String firstName;

//Filed

private String lastName;

 

//屬性 : fullName

public String getFullName() {

return this.firstName + this.lastName;

}

package cn.sxt.crm.pojo; public class Student { private Integer id; private String name; private Integer age; private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Student(Integer id, String name, Integer age, String password) { super(); this.id = id; this.name = name; this.age = age; this.password = password; } public Student() { super(); // TODO Auto-generated constructor stub
 } }
相關文章
相關標籤/搜索