㈠ 關於java中內部類引用外部類的問題代碼如下
因為你使用system.out.println這個方法輸出個對象的時候,因為只能輸出字元串,所以系統就會默認調用類中的toStringf方法,因為這個方法是源自object類的,所以幾乎所有的類都有這個方法。而你的代碼重寫了這個方法,所以輸出的時候就調用了這個方法,然後按你的規則進行了輸出。
比如
publicclassTest{
publicTest(){}
publicvoidtoString(){
System.out.println("----test------");
}
//假設:Testtest=newTest();
//System.out.println(test);
//輸出的結果就是"----test------"
}
㈡ java 中為什麼引用外部類的變數和方法都要是final內型 的
Thinking In Java裡面的說法(唯一正確的說法): 如果定義一個匿名內部類,並且希望它使用一個在其外部定的對象,那麼編譯器會要求其參數引用是final 的。以下是分析過程:
首先看代碼
publicclassTester{
publicstaticvoidmain(String[]args){
Aa=newA();
Cc=newC();
c.shoutc(a.shout(5));
}
}
////////////////////////////////////////////////////////
classA{
publicvoidshouta(){
System.out.println("HelloA");
}
publicAshout(finalintarg){
classBextendsA{
publicvoidshouta(){
System.out.println("HelloB"+arg);
}
}
returnnewB();
}
}
////////////////////////////////////////////////////////
classC{
voidshoutc(Aa){
a.shouta();
}
}
第5行c.shoutc(a.shout(5)),在a.shout(5)得到返回值後,a的shout()方法棧被清空了,即arg不存在了,而c.shoutc()卻又調用了a.shouta()去執行System.out.println("Hello B" + arg)。
再來看Java虛擬機是怎麼實現這個詭異的訪問的:有人認為這種訪問之所以能完成,是因為arg是final的,由於變數的生命周期,事實是這樣的嗎?方法棧都不存在了,變數即使存在,怎麼可能還被訪問到?試想下:一個方法能訪問另一個方法的定義的final局部變數嗎(不通過返回值)?
研究一下這個詭異的訪問執行的原理,用反射探測一下局部內部類 。編譯器會探測局部內部類中是否有直接使用外部定義變數的情況,如果有訪問就會定義一個同類型的變數,然後在構造方法中用外部變數給自己定義的變數賦值,而後局部內部類所使用的變數都是自己定義的變數,所以就可以訪問了。見下:
classA$1$B
{
A$1$B(A,int);
privatefinalintvar$arg;
privatefinalAthis$0;
}
A$1$B類型的對象會使用自定義的var$arg變數,而不是shout()方法中的final int arg變數,當然就可以訪問了。
那麼為什麼外部變數要是final的呢?即使外部變數不是final,編譯器也可以如此處理:自己定義一個同類型的變數,然後在構造方法中賦值就行了。原因就是為了讓我們能夠挺合邏輯的直接使用外部變數,而且看起來是在始終使用外部的arg變數(而不是賦值以後的自己的欄位)。
考慮出現這種情況:在局部內部類中使用外部變數arg,如果編譯器允許arg不是final的,那麼就可以對這個變數作變值操作(例如arg++),根據前面的分析,變值操作改變的是var$arg,而外部的變數arg並沒有變,仍然是5(var$arg才是6)。因此為了避免這樣如此不合邏輯的事情發生:你用了外部變數,又改變了變數的值,但那個變數卻沒有變化,自然的arg就被強行規定必須是final所修飾的,以確保讓兩個值永遠一樣,或所指向的對象永遠一樣(後者可能更重要)。
還有一點需要注意的是內部類與方法不是同時執行的,比如實現ActionListener,只有當事件發生的時候才會執行,而這時方法已經結束了。
㈢ Java 內部類如何被外部類調用
服了你了,能把程序寫成這樣。一個java文件里可以有多個類,但只能有一個public類,而且這個類必須是外部類,不能是內部類。而且你在Test里實例化inner的方法也不對,inner的類型始終是Outer.Inner,不會因為Outer實例化而變成outer.Inner,只不過編譯器還沒有報出那裡的錯誤而已。寫成這樣:
class Outer{
private int size=10;
class Inner{
public void doStuff(){
System.out.println(++size);
}
}
}
public class Test{
public static void main(String [] args){
Outer outer=new Outer();
Outer.Inner inner=outer.new Inner();
inner.doStuff();
}
}
㈣ android java的類中類怎麼調用外部類的方法
成員內部類可以無條件地訪問外部類的成員,而外部類想訪問成員內部類的成員卻不是這么隨心所欲了。在外部類中如果要訪問成員內部類的成員,必須先創建一個成員內部類的對象,再通過指向這個對象的引用來訪問:
classCircle{//外部類
privatedoubleradius=0;
publicCircle(doubleradius){
this.radius=radius;
getDrawInstance().drawSahpe();//必須先創建成員內部類的對象,再進行訪問
}
privateDrawgetDrawInstance(){//初始化內部類,以便可以訪問
returnnewDraw();
}
classDraw{//內部類
publicvoiddrawSahpe(){
System.out.println(radius);//外部類的private成員
}
}
}
㈤ java裡面的內部類和外部類是什麼_
外部類:
最普通的,我們平時見到的那種類,就是在一個後綴為.java的文件中,直接定義的類
內部類:
內部類,顧名思義,就是包含在外部類中的類,就叫做內部類。內部類有兩種,一種是靜態內部類,一種是非靜態內部類。
靜態內部類和非靜態內部類之間的區別主要如下:
1、內部原理的區別:
靜態內部類是屬於外部類的類成員,是一種靜態的成員,是屬於類的,就有點類似於private static Singleton instance = null;非靜態內部類,是屬於外部類的實例對象的一個實例成員,靜態類則是屬於所有外部共有的,也就是說,每個非靜態內部類,不是屬於外部類的,是屬於外部類的每一個實例的,創建非靜態內部類的實例以後,非靜態內部類實例,是必須跟一個外部類的實例進行關聯和有寄存關系的。
2、創建方式的區別:
創建靜態內部類的實例的時候,只要直接使用「外部類.內部類()」的方式,就可以,比如School.Teacher();創建非靜態內部類的實例的時候,必須要先創建一個外部類的實例,然後通過外部類的實例,再來創建內部類的實例,new School().Teacher()
通常來說,我們一般都會為了方便,會選擇使用靜態內部類。
㈥ java內部類如何被外部引用
將public去掉,則默認為friendly,即友元。
而在同一個包中的友元中的類是可以被引用的。
㈦ java 請問非靜態類為什麼持有外部類的引用
非靜態內部類依賴於外部類,沒有外部類就不能創建內部類,內部類可以直接訪問外部類的屬性,包括私有屬性
㈧ Java內部類怎麼直接調用外部類啊
publicclassOuter{
intx;
Strings="hello";
publicvoidtest(){
System.out.print("test");
}
publicclassInner{
ints=20;
publicvoidtestInner(){
//可以直接使用外部類的成員變數和成員方法
x=0;
test();
//如果外部類的成員變數和內部類變數重名,可以這樣調用外部類的變數
Outer.this.s="test";
//當然你可以new外部類對象這也是沒問題的
Outero=newOuter();
o.x=30;
o.test();
}
}
}
㈨ Java內部類怎麼直接調用外部類啊
在內部類中創建外部類對象 在調用
㈩ java類引用的問題
1.類之間不能調用各自的私有方法;
2.一個類只能直接調用另一個類的public static方法;
3.一個類只能在new出另一個類的時候才能調用它的public方法;
4.一個類要調用另一個類的方法時,2個類必須在同一個包中,不在同一個包的話需要import包;
5.只有子類可以調用父類的protect方法;
6.子類不可以調用抽象父類的抽象方法(需要重寫);
7.匿名內部類中的方法無法被其他類調用;
暫時想到這么多。