管理Java类文件
在java中,每一個定義好的類,在編譯的時候,都會對應地產生一個.class文件。如果程序的規模越來越大,那么類文件也會越來越多,管理起來也會越來越麻煩,很容易發生命名的沖突。因此,java中引入了"包"(package)的概念。
一、內部類
在類中還可以再定義類,這種類叫做內部類(Inner Class)。使用內部類主要有三個好處:一是可以任意地訪問對應的外部類的私有(private)成員;二是如果一個內部類只服務于對應的外部類,那么外界就不必知道有這個內部類的存在;三是對于外部類來說,內部類可以將一系列數據類型“打包”,就像C++的類中再定義結構體一樣。當然類的功能要比結構體強大多了。
1、訪問外部類的prvate成員
import static java.lang.System.out;class Outer {private int x = 0;//內部類Innerclass Inner{public int accessOuter() //訪問外部類的private成員{return x;}}public Inner getInner() //返回內部類對象{return new Inner();}public static void main(String[] args){Outer objOut = new Outer();out.println(objOut.getInner().accessOuter());} }可以看到,程序打印出了外部類的private成員x的值。
2、將數據類型打包
public class InnerDemo {//內部類Point,表示一個點private class Point{private int x,y;Point(int x,int y){this.x = x;this.y = y;}public String toString(){return "(x = " + x + ",y = " + y + ")";}}//創建3個部類Point對象Point[] pt = new Point[]{new Point(1,1),new Point(2,2),new Point(3,3)};//輸出點集public void getAllPoints(){for(Point point : pt){System.out.println(point);}}public static void main(String[] args){InnerDemo inner = new InnerDemo();inner.getAllPoints();} }InnerDemo類表示一個點集,而點集中的每一個點元素就可以用內部類來定義表示。程序運行結果:
對于一個包含內部類的類,程序編譯后會產生一個名為 "外部類名$內部類名.class" 的類文件。如上例,編譯后會生成InnerDemo$Point.class文件。由于Point類僅僅服務于其對應的外部InnerDemo類,因而在實際使用InnerDemo類的時候,我們不必關心Point類的存在。
二、匿名內部類
匿名內部類可以不用聲明類名稱,直接使用new關鍵字來產生一個對象:
new Object(){public void doSomethig(){//... ...} }這樣的好處是,對于一些接口或者方法的參數類型是一個類的引用的時候,我們不必單獨定義一個新的類去產生一個對象再把對象傳進去,直接使用匿名內部類可以省略類的定義。如getInner方法需要一個Point類的對象,那么我們可以這樣寫: getInner(new Point()public void method(){//do something} );值得注意的是,如果在一個匿名的內部類中想要訪問外部的局部變量,那么就必須將這個要被訪問的變量聲明為final.否則在編譯的時候就會報錯,如: public void method(){int x = 100; //沒有聲明為finalObject obj = new Object(){public String toString(){System.out.println(x); //訪問外部的x變量return "New Object!";} };}那么,為什么編譯器要強制我們把x聲明為final?這是因為,在匿名內部類中訪問x時,內部類中訪問的只是變量x的一份拷貝,如果在匿名內部類中修改了變量x,那么這種修改是不會影響到外部的變量x的。所以把x聲明為final后,就起到一個提醒的作用,表示程序員不可以在內部類中修改x的值。這樣就降低了出錯的可能性。
三、包(package),導入(import)
1、包
Java 提供包來管理類。包就對應著我們文件系統的文件目錄。我們可以使用關鍵字 package來定義包,如:
package test; public class Point { }編譯時加入-d參數,并在后面指定要把生成的類放在哪一個文件之下,如:javac -d . Point.java
這將會在當前目錄下生成一個 test目錄,Point.class文件就在這個test目錄里。
注意,一旦設置了包后,這個包的名字就變成了類名的一部分。如上例,類Point的類名應為test.Point而不是Point了。
2、import
有時候我們的類的包名非常長,那么在使用的時候就會非常麻煩,因為要寫上一長串包名。這時候就可以用import語句來導入一個包中的類,然后再使用此包中的類的時候,就不必加上長長的包名了。如:
不導入時:
test.Point pt = new test.Point();使用import后: import test.Point;//導入test包中的Point類 Point pt = new Point();編譯器在編譯這個源文件時,首先會在當前目錄下尋找Point類文件,如果沒有找到,就會試著組合import上的設置來尋找Point類。這樣在使用類的時候就不需要加包名了。
但在使用import時,如果你把源文件跟生成的類文件都放在同一個目錄,那么在編譯時極可能會發生“找不到類”的錯誤。下面就是一個這樣的例子:
我們在test目錄下有這樣兩個文件:
假定在Point.class的上層目錄里有這樣一個程序:
import test.*;class ImportError {Point pt = new Point(); }它使用通配符*導入了test目錄下的所有類,但在編譯時就會報錯:
為什么會發生這個錯誤呢?
因為,當使用通配符*時,編譯器就會導入test目錄下的所有文件。當我們用到Point 類時,由于Point.java文件和Point.class文件都在test目錄下,編譯器會首先找到Point.java文件而不是Point.class類。所以會報錯。
為了避免此類錯誤的發生,我們要把源文件跟類文件分開,專門建立一個src目錄存放.java 文件,建立classes目錄存放.class文件。
3、import靜態成員
在J2SE 5.0后增加了import static 語法,允許我們導入一個類或接口中的靜態成員。這樣就可以讓程序員寫得更少了。如:
System.out.println("");可以寫成: import static java.lang.System.out;... out.println(""); ...
嗯嗯,就先到這吧。。
轉載于:https://www.cnblogs.com/whongfei/archive/2013/03/20/5246995.html
總結
- 上一篇: 详解.NET异步
- 下一篇: tftp 在线更新 cisco swit