Java 異常與反射 總結

來源:互聯網
上載者:User

標籤:clone()   對象傳輸   unicode   函數   性問題   運行時異常   事件   關係   contains   

      1.異常  

        異常,簡單來說,就是一個程式執行過程中發生的不正常情況的事件。它發生在程式的運行期間,幹擾了正常的指令流程。如果沒有處理異常,那麼出現異常之後,程式會停止運行。異常分為運行異常和非運行異常。非運行異常也叫編譯異常。對於編譯異常編譯器要求必須處理。否則無法運行。運行時異常編譯器不要求強制處理。運行時異常一般是由程式邏輯錯誤引起的,程式應該從邏輯角度儘可能避免這類異常的發生。它們都繼承於Exception類。運行異常和非運行異常也下分各類異常。異常發生的原因是程式錯誤或偶然的外在因素導致的一般性問題。

繼承關係

如果一個方法內拋出異常,該異常會被拋到調用方法中。如果異常沒有在調用方法中處理,它繼續被拋給這個方法的調用者。這個過程將一直繼續下去,直到異常被處理。這一過程稱為捕獲異常。

2.反射

在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;

對於任意一個對象,都能夠調用它的任意一個方法和屬性;

這種動態擷取的資訊以及動態調用對象的方法的功能稱為java語言的反射機制。

反射的思維導圖如下

 

 

      當使用反射時候,首先需要擷取到Class類的對象,得到了這個類之後,就可以得到class檔案裡面的所有內容。

以下是具體的反射應用方式

1.類型轉換:將Map轉成Person的示範

Person類是一個普通的實體類,裡麵包含三個私人的成員屬性及它們的Set和Get函數。Map是集合架構裡使用的Map類型架構,裡面可以加入泛型。具體轉碼如下

 1 //param1:要轉化的資料類型Person.class        String.class 2 public static Object toBean(Class<?> type,Map<String,? extends Object> map) throws Exception{ 3      4     //Introspector專門處理Bean的工具類。比如擷取Class的屬性或者方法或構造 5     BeanInfo beanInfo = Introspector.getBeanInfo(type);//參數傳遞的就是類的類型 6     //調用newInstance方法建立這個類 7     Object o = type.newInstance(); 8     //擷取o的方法 9     PropertyDescriptor[] ps = beanInfo.getPropertyDescriptors();10     for (int i = 0; i < ps.length; i++) {11 12         PropertyDescriptor p = ps[i];13         //擷取方法描述的名稱(屬性名稱)如果是Person --->name(name,age,sex)14         String name = p.getName();15         //name是否就是map中的key?16         if(map.containsKey(name)){17             //通過key擷取map的值18             Object value = map.get(name);19             //通過反射,value賦給o20             //p.getWriteMethod();//set方法21             //p.getReadMethod();//get方法22             p.getWriteMethod().invoke(o, value);23         }24     }25     //擷取map中的key的值,以及value的值26     return o;27 }28 public static void main(String[] args) throws Exception {    29     Map pMap = new HashMap();30     pMap.put("name", "張三");31     pMap.put("age", 1);32     pMap.put("sex", 2);33     //Map--->Object34     Person p = new Person("張三");35     p.setAge(1);36     p.setSex(2);37     Person o = (Person)toBean(Person.class,pMap);38     System.out.println(" "+o.toString());39 }

        以上代碼的思想就是,建立一個相對於想要的類的BeanInfo,然後通過這個BeanInfo對象得到所有的屬性名稱(對應到Map裡就是所有索引值對的鍵),然後判斷Map裡是否有與擷取的鍵名稱同名的鍵,如果有的話就通過Map擷取那個鍵的值,然後通過PropertyDescriptor對象擷取需要的對象的set方法,將值賦值給相應的屬性,最後返回相應的類型的對象。

2.Java中五種建立新對象的方法

 1>直接用new調用該類的建構函式

new Person("張三");

2>使用class類中的newInstance方法建立對象,調用建構函式

1 public static void test1() throws ClassNotFoundException, InstantiationException, IllegalAccessException{2         //1、擷取Class類的對象    3         Class c = Class.forName("com.Person");4         //2、通過Class類中的newInstance方法建立Person對象5         Person p = (Person)c.newInstance();6         //3、檢測一下7         p.setName("張三");8         System.out.println(p.getName());9     }

3>使用class類型中的建構函式中的newInstance方法

public static void test2() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{        //1、擷取Person類型        Constructor c = Person.class.getConstructor();        //2、建立方法        Person p = (Person)c.newInstance();        //3、檢測        p.setName("張三");        System.out.println(p.getName());    }

4>通過clone方法建立。前提是需要在實體類裡重寫clone()方法

/***實體類**/public class Person implements Cloneable{    private String name;    private int  age;    private int  sex;@Override    protected Person clone() throws CloneNotSupportedException {        Person person = null;        person = (Person)super.clone();        return person;    }}/***功能類中clone功能函數**/public static void test3(){        //需要重寫clone方法,重寫cloneable介面。非常特殊        //在Person類裡實現cloneable介面        Person p1 =new Person("王五");        //調用clone方法建立一個新的對象p2        Person p2 = null;        try {             p2 = p1.clone();        } catch (CloneNotSupportedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        System.out.println(p1==p2);            }

5>序列化和還原序列化的方法,通過這種方法可以將對象轉換為位元組序列的方式,把對象傳輸到另一台機器上。

3.通過反射擷取方法和操作屬性

1>通過反射擷取方法

通過反射擷取方法的方式是先申明一個Class對象,然後通過該對象的getDeclaredMethod方法建立Method對象,通過Method對象的invoke方法調用擷取到的方法實現功能。具體範例程式碼如下

 1 public static void test5() { 2         try {  3             Class c = Class.forName("com.hpe.ref.Person"); 4             //擷取方法        Person setName  getName 5             //param1:方法名的String類型 6             //param2:方法的參數類型 7             Method m = c.getDeclaredMethod("setName", String.class); 8             //建立Object對象 9             Object obj = c.newInstance();10             //invoke調用方法(反射的方式調用方法)11             //param1:反射的類,param2:m方法的值12             m.invoke(obj, "張三");13             //驗證14             Method gM =c.getDeclaredMethod("getName");15             System.out.println(gM.invoke(obj));16         } catch (Exception e) {17             // TODO Auto-generated catch block18             e.printStackTrace();19         }20     }

2>通過反射擷取屬性

        通過反射擷取屬性的方法是通過Class擷取該對象的Class對象形式,之後通過Field以字串的形式擷取類中的屬性,然後通過Field對象來操作該屬性。具體代碼如下。

public static void test4(){        //通過反射,在運行階段建立這個person對象        try {            Class c = Class.forName("com.hpe.ref.Person");                        Field field = c.getDeclaredField("name");            //通過字串的形式擷取類中的屬性。            Field[] fs = c.getDeclaredFields();            //設定對屬性,如果是私人的,可以有許可權訪問            field.setAccessible(true);            Object o  =c.newInstance();            //set方法----操作屬性的方式            field.set(o, "張三");            System.out.println(field.get(o));        } catch (ClassNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (NoSuchFieldException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (SecurityException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (InstantiationException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IllegalAccessException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }
3.小註:分析下列代碼功能

這段代碼的功能分析

public int indexOf(int ch)

返回指定字元第一次出現的字串內的索引。 如果與值的字元ch在此表示的字元序列發生String第一事件發生之對象,則索引(在Unicode代碼單元)被返回。

public StringBuffer insert(int offset, char c)

在此序列中插入char參數的字串表示形式。

總體效果就好像第二個參數通過方法String.valueOf(char)轉換為一個字串,並且該字串中的字元然後是inserted到指定的位移量的這個字元序列。

offset參數必須大於或等於0 ,小於或等於該序列的length 。

所以它的功能是,以小數點為界,每往前數三位,就在str字串裡插入一個逗號。以達到計算數位位元效果。

 

Java 異常與反射 總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.