Java之反射的應用,Java之反射應用
package com.zheges;import java.util.Date;public class Customer {//JavaBean 對象private String name;private int password;public String present = "God";private Date date;@Overridepublic String toString() {return "Customer [name=" + name + ", password=" + password+ ", present=" + present + ", date=" + date + "]";}public String getPresent() {return present;}public void setPresent(String present) {this.present = present;}public String getName() {return name;}public Date getDate() {return date;}public void setDate(Date date) {this.date = date;}public void setName(String name) {this.name = name;}public int getPassword() {return password;}public void setPassword(int password) {this.password = password;}public String getAB(){return "AB";}}
package com.zheges;import static org.junit.Assert.assertEquals;//靜態匯入Assert所有靜態方法import java.lang.reflect.Field;import org.junit.Before;import org.junit.Test;/*** 項目名稱:Reflection * 類名稱:FirDemo * 類描述:反射的基本應用* 建立人:ZHe * 建立時間:2015年8月29日 下午5:01:43 * 修改人:ZHe * 修改時間:2015年8月29日 下午5:01:43 */public class FirDemo {private Class<?> clazz;//類的位元組碼private Customer customer = new Customer();/** * 1.載入類,並且獲得類的位元組碼 * @throws ClassNotFoundException */@Beforepublic void getClassLoader() throws ClassNotFoundException {//1.使用Class的靜態方法載入clazz = Class.forName("com.zheges.Customer");//注意:這裡要使用類的全名//2.通過類對象獲得其位元組碼clazz = new Customer().getClass();//3.通過類的靜態屬性獲得clazz = Customer.class;assertEquals("com.zheges.Customer",clazz.getName());}/** * 2.獲得類的欄位(注意:不等同於屬性,屬性由getter來確定!) * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalAccessException * @throws IllegalArgumentException */@Testpublic void getClassProperties() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{//1.獲得私人欄位及其類型Field field = clazz.getDeclaredField("name");Class<?> type = field.getType();assertEquals(String.class, type);//2.獲得公有欄位及其類型Field field1 = clazz.getField("present");Class<?> type1 = field1.getType();assertEquals(String.class, type1);//3.true if this object is the same as the obj argument; false otherwise.assertEquals(true, field.equals(clazz.getDeclaredField("name")));//4.設定某個對象上該欄位的值field.setAccessible(true);//該欄位是私人的,需要設定setAccessiblefield.set(customer,"ZheGes");field1.set(customer, "Nor");assertEquals(customer.getName(), "ZheGes");assertEquals(customer.getPresent(), "Nor");//5.擷取某個對象上該欄位的值assertEquals(field.get(customer), "ZheGes");//前提是該私人變數設定了AccessibleassertEquals(field1.get(customer), "Nor");}}
package com.zheges;import java.beans.BeanInfo;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import static org.junit.Assert.*;import org.junit.Ignore;import org.junit.Test;/*** 項目名稱:Reflection * 類名稱:SecDemo * 類描述:反射進階應用程式:內省* 建立人:ZHe * 建立時間:2015年8月29日 下午5:03:02 * 修改人:ZHe * 修改時間:2015年8月29日 下午5:03:02 */public class SecDemo {//內省:通過反射的方式訪問javabean的技術//JavaBean:1.必須有無參的建構函式 2.屬性必須私人(屬性數目由get數目來定,並非由欄位來定!)3.提供標準的getter和setter//1.列印Customer的所有屬性(包含Object的屬性)/*result: AB-----Customer getterclass ----Object getter,getClass---->這個方法是繼承Object的datenamepasswordpresent*/@Ignorepublic void getProperties() throws IntrospectionException{BeanInfo beanInfo = Introspector.getBeanInfo(Customer.class);PropertyDescriptor [] propertyDescriptors = beanInfo.getPropertyDescriptors();for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {System.out.println(propertyDescriptor.getName());}}//2.列印Customer的所有屬性(不包含Object的屬性)@Ignorepublic void getOwnProperties() throws IntrospectionException{BeanInfo beanInfo = Introspector.getBeanInfo(Customer.class,Object.class);PropertyDescriptor [] propertyDescriptors = beanInfo.getPropertyDescriptors();for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {System.out.println(propertyDescriptor.getName());}}//3.操作JavaBean的指定屬性@Testpublic void actProperty() throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{Customer customer = new Customer();PropertyDescriptor propertyDescriptor = new PropertyDescriptor("name", Customer.class);Method method = propertyDescriptor.getWriteMethod();method.invoke(customer, "zheGes");Method method2 = propertyDescriptor.getReadMethod();System.out.println(method2.invoke(customer, null));}//4.獲得當前操作屬性的類型@Ignorepublic void getPropertyType() throws IntrospectionException{PropertyDescriptor propertyDescriptor = new PropertyDescriptor("name", Customer.class);assertEquals(String.class, propertyDescriptor.getPropertyType());}}
package com.zheges;import static org.junit.Assert.assertTrue;import java.lang.reflect.InvocationTargetException;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import org.apache.commons.beanutils.BeanUtils;import org.apache.commons.beanutils.ConversionException;import org.apache.commons.beanutils.ConvertUtils;import org.apache.commons.beanutils.Converter;import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;import org.junit.Ignore;import org.junit.Test;/*** 項目名稱:Reflection * 類名稱:ThrDemo * 類描述:反射的進階應用程式2:BeanUtils* 建立人:ZHe * 建立時間:2015年8月29日 下午5:50:20 * 修改人:ZHe * 修改時間:2015年8月29日 下午5:50:20 */public class ThrDemo {private Customer customer = new Customer();//1.BeanUtils操作屬性@Ignorepublic void actProperty() throws IllegalAccessException, InvocationTargetException, Exception{BeanUtils.setProperty(customer, "name", "ZHeGes");BeanUtils.setProperty(customer, "password", "404");//發生了String轉int,但這種轉換隻支援8種基礎類型!System.out.println(BeanUtils.getProperty(customer, "name")+" "+BeanUtils.getProperty(customer, "password"));}//2.對於非基礎類型的轉換,則要給BeanUtils註冊轉換器@Ignorepublic void registConver() throws Exception {//註冊一個日期轉換器,Converter介面,使用匿名內部類實現ConvertUtils.register(new Converter(){@Overridepublic Object convert(Class type, Object value) {if(null == value){return null;}if( !(value instanceof String)){throw new ConversionException("只支援String類型的轉換");}String str = (String)value;SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");try {return simpleDateFormat.parse(str);} catch (ParseException e) {throw new RuntimeException(e);//異常鏈不能斷!}}}, Date.class);BeanUtils.setProperty(customer, "date", "1992-3-18");//The property's value, converted to a StringSystem.out.println(BeanUtils.getProperty(customer, "date"));System.out.println(customer.getDate().toLocaleString());}//3.使用Apach公司提供的日期轉換器@Ignorepublic void registConver2() throws Exception{ConvertUtils.register(new DateLocaleConverter(), Date.class);BeanUtils.setProperty(customer, "date", "1992-3-18");System.out.println(customer.getDate().toLocaleString());}//4.使用BeanUtils將Map對象填充到JavaBean@Ignorepublic void usePopulate() throws Exception{Map map = new HashMap<>();map.put("name", "ZheGes");map.put("password", "123");map.put("date", "1992-2-1");//日期轉換器ConvertUtils.register(new DateLocaleConverter(), Date.class);BeanUtils.populate(customer, map);System.out.println(customer);}@Testpublic void test(){String str = "hell";String str1 = str;str = "wofl";System.out.println(str+" "+str1);}@Ignorepublic void test2(){Class<String> t1 = String.class;//Class<String> t2 = Date.class; false:加了類型約束,必須是類String的位元組碼,否則報錯!Class t3 = String.class;assertTrue(t1 == t3);}}