java 內部類操作

來源:互聯網
上載者:User

今天在寫一個小demo的時候,溫習了下內部類,居然發現在用反射的時候出異常import java.lang.reflect.InvocationTargetException;</p><p>public class JustMyTestMain {</p><p>public static void main(String[] args) throws InstantiationException,<br />IllegalAccessException, IllegalArgumentException,<br />SecurityException, InvocationTargetException {<br />JustMyTestMain t = new JustMyTestMain();<br />Animal a = t.new Animal();<br />Dog d = t.new Dog();<br />Cat c = t.new Cat();<br />a = d;<br />// 實際上a應用的是dog對象,並不能把dog對象轉換成cat對象<br />// c=(Cat) a;//編譯可以通過,但運行出錯<br />a.call();<br />// a=(Animal)<br />Animal a1= (Animal) d.getClass().getSuperclass().newInstance();<br />a1.call();<br />}</p><p>class Animal {<br />public void call() {<br />System.out.println("ooooo");<br />}<br />}</p><p>class Dog extends Animal {<br />public void call() {<br />System.out.println("Dog");<br />}<br />}</p><p>class Cat extends Animal {<br />public void call() {<br />System.out.println("Cat");<br />}<br />}</p><p>}

在d.getClass().getSuperclass().newInstance();的時候報的異常,後來查了網上的說要使用 Inner.class.getConstructors()[0].newInstance(new Outer()),才行,因此改造了原來的方法

Animal a1 = (Animal) d.getClass().getSuperclass().getConstructors()[0]
    .newInstance(t);但是結果還是出錯,不過這次報的是數組小標越界的問題,用debug跟進去看,發現d.getClass().getSuperclass().getConstructors()返回的是空,杯具啊。再次找了google大神,原來這樣調用的話內部類要為public。原因是只有公開非靜態內部類的預設建構函式需要一個外圍類的執行個體。當然不是public也行的,這個時候只需要將getConstructors方法換成getDeclaredConstructors就可以了。還有如果內部類是私人的,在初始化的時候要將建構函式的訪問設定成true

public class Outer{<br /> private class Inner{<br /> }<br /> public static void main(String[] args){<br /> System.out.println(Inner.class);<br /> //查看class是否有建構函式<br /> System.out.println(Inner.class.getDeclaredConstructors().length);<br /> //擷取第一個建構函式<br /> Constructor c = Inner.class.getDeclaredConstructors()[0];<br /> //將c設定成可訪問<br /> c.setAccessible(true);<br /> //用建構函式初始化內部類<br /> System.out.println(c.newInstance(new Outer());<br /> }<br />}<br />

 

最後總結各種內部類的情況,來一個內部類反射的大匯總

import java.lang.reflect.Constructor;<br />import java.lang.reflect.InvocationTargetException;</p><p>public class JustMyTestMain {</p><p>public static void main(String[] args) throws InstantiationException,<br />IllegalAccessException, IllegalArgumentException,<br />SecurityException, InvocationTargetException,<br />ClassNotFoundException {<br />JustMyTestMain t = new JustMyTestMain();<br />Animal a = t.new Animal();<br />Dog d = t.new Dog();<br />Cat c = t.new Cat();<br />a = d;<br />// 實際上a應用的是dog對象,並不能把dog對象轉換成cat對象<br />// c=(Cat) a;//編譯可以通過,但運行出錯<br />a.call();</p><p>//對於公開非靜態內部類的預設建構函式需要一個外圍類的執行個體<br />//getConstructors()返回一個包含某些 Constructor 對象的數組,<br />//這些對象反映此 Class 對象所表示的類的所有公用構造方法。<br />Animal a1 = (Animal) d.getClass().getSuperclass().getConstructors()[0]<br />.newInstance(t);<br />a1.call();</p><p>// 對於非公開內部類需要調用getDeclaredConstructors<br />//該方法返回 Constructor 對象的一個數組,這些對象反映此 Class 對象表示的類聲明的所有構造方法。<br />//不只是公用的構造方法<br />Class cla = Class.forName("net.zj.hz.yk.JustMyTestMain$Dog");<br />Dog d1 = (Dog) cla.getDeclaredConstructors()[0].newInstance(t);<br />d1.call();</p><p>cla = Class.forName("net.zj.hz.yk.JustMyTestMain$Cat");<br />Constructor con = cla.getDeclaredConstructors()[0];<br />// 對於私人內部類,需要將建構函式設定成可訪問,如果這行注釋去掉,將會異常<br />con.setAccessible(true);<br />Cat c1 = (Cat) con.newInstance(t);<br />c1.call();</p><p>//如果是 static內部類,則預設建構函式是一個無參的建構函式<br />cla = Class.forName("net.zj.hz.yk.JustMyTestMain$Inner");<br />Inner in = (Inner) cla.getConstructors()[0].newInstance();<br />in.call();</p><p>cla = Class.forName("net.zj.hz.yk.JustMyTestMain$Inner2");<br />Inner2 in2 = (Inner2) cla.getDeclaredConstructors()[0].newInstance();<br />in2.call();<br />}</p><p>public class Animal {<br />public void call() {<br />System.out.println("Animal");<br />}<br />}</p><p>class Dog extends Animal {<br />public void call() {<br />System.out.println("Dog");<br />}<br />}</p><p>private class Cat extends Animal {<br />public void call() {<br />System.out.println("Cat");<br />}<br />}</p><p>public static class Inner {<br />public void call() {<br />System.out.println("Inner");<br />}<br />}</p><p>static class Inner2 {<br />public void call() {<br />System.out.println("Inner2");<br />}<br />}<br />}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.