天天看點

j2se回想

執行Java程式.

Java程式有兩種方式一種是jar包。一種是class. 執行jar,Java -jar XXX.jar執行的時候,Java.exe調用GetMainClassName函數,該函數先獲得JNIEnv執行個體然後調用Java類Java.util.jar.JarFileJNIEnv中方法getManifest()并從傳回的Manifest對象中取getAttributes("Main-Class")的值即jar包中檔案:META-INF/MANIFEST.MF指定的Main-Class的主類名作為執行的主類。之後main函數會調用Java.c中LoadClass方法裝載該主類(使用JNIEnv執行個體的FindClass)。main函數直接調用Java.c中LoadClass方法裝載該類。假設是執行class方法。main函數直接調用Java.c中LoadClass方法裝載該類。

然後main函數調用JNIEnv執行個體的GetStaticMethodID方法查找裝載的class主類中

“public static void main(String[] args)”方法,并推斷該方法是否為public方法,然後調用JNIEnv執行個體的

CallStaticVoidMethod方法調用該Java類的main方法。 

----------------------------------------------------

堆和棧是分别管理 對象和位址值的。非靜态在擷取執行個體的時候須要一個引用,(是以須要new一個對象) 而靜态則不須要

native 是java用來和c/c++ 打交到的,早期java剛剛出生是c/c++橫行的時候,java為了适應當時的格局。是以在jvm中開辟了一塊空間特地來處理c/c++的程式。

這塊區域他叫做native。

而native是用來處理程式和硬體打交到的區域。

棧裡面是存放位址引用,堆裡面的存放的是實體對象。棧的速度快。堆比較慢。

JAVA_HOME

D:\Java\bin

PATH

%JAVA_HOME%;%System%.....

設定暫時的環境變量

set path="u盤上的jre檔案bin檔案的路徑",這樣path的路徑就變為了暫時的了。他的生命周期就在目前窗體。關閉就沒有了。

javac xxx.java

class 檔案不在目前目錄下

-->set classpath f:\xxx\xx\   這樣子過去,能夠為目前類檔案設定一個暫時的路徑。

& 過程中僅僅要有一邊為假,就為假

| 過程中僅僅要有一邊為真,就為真

&&左邊為false時不參與運算

||左邊為true時不參與運算

位運算。計算機專用,用于操作2進制的運算。

if(){}else if(){}else if(){} else  //這個盡管由多個代碼塊組成。可是僅僅有一個會運作。

if 和 switch  建議僅僅使用 switch  switch會把選擇答案載入進記憶體,選擇效率會高點。 int byte short char enum string

while(){}

do while(){}不管條件是否滿足,循環體都要運作一次。

(\r \n回車) (\t制表符) (\轉義字元)

辨別符:

wai:for(int i;i<10;i++){

 nei:for(int j;j<10;j++){

  break wai;  //跳出外循環

 }

}

重載:方法名同樣。參數個數不同,傳回值類型不同。

數組:同一類型,固定個數的容器。

選擇排序:1 第一個和後面的每個比較,小的放前面。内圈和外圈做比較。2 内圈的起始變量是外圈的第二個。3 來個暫時變量,為2個角标的引用做交換。

冒泡排序:1 相鄰的2個數做比較。大的放後面。

2 内圈變量是外圈長度減一。3 來個暫時變量。為2個角标的引用做交換。

Arrays.sort(arr);//開發專用 ,甯外希爾排序,效率非常高。

二分法查找:1 必須是有序的。

>>>右移動4位,<<<左移動4位 , 在10進制中一個數&15 相當于找到自身。

Integer.toBinatyString(-6); 十--->二進制

Integer.toOctalString(-6); 十--->八進制

Integer.toHexString(-6); 十--->十六進制

二維數組

引用資料類型,在堆裡面,預設初始化值是null。在沒有不論什麼指向之前他就是null。

int arr[][]={{1,2,3},{4,5,6},{7,8,9}};

int sum=0;

for(int i;i<arr.length;i++){

 for(int j;j<arr[i].length;j++){

  sum+=arr[i][j];

面向對象:

1 面向對象思想是一種符合現實社會中人們對問題思考習慣的思想。

2 把現實社會中複雜的事情簡單化(eg:買電腦)

3 把運作者,變為指揮者(eg:買電腦)

--------------------

3 種引用類型的變量。

 1 數組。

 2 類。

 3 接口。

局部變量和成員變量的差别

1 在類中定義的位置不同

2 在記憶體中的生命周期不同(堆和棧)

3 生命周期不同

4 初始化值不一樣。

匿名對象的使用場景:當對象方法或屬性僅僅有一次調用的時候就用匿名對象。

五片記憶體區域:

1 寄存器。

2 本地方法區[和jni一起用]。

3 棧記憶體。

4 堆記憶體。

5 方法區[資料共享區]。

---------------------------------------------------------

1 封裝:隐藏對象的屬性和實作細節,僅對提供公共的訪問和操作方式。

 構造函數:将對象初始化。每個類都有一個預設的構造函數。

 this:表示目前對象,位元組碼。

誰調用這個類。this就代表誰。

 {} 構造代碼塊。每次建立一個對象都會運作一次。而構造函數僅僅運作一次。

  --------------------

  static: 和方法一樣。存在方法區中,而方法是在被調用的時候才進棧,被static修飾的就是一直存在方法區中。

  ---1 被static修飾的,優先于對象存在。

  ---2 随着類的載入而載入,消失而消失。

  ---3 被全部成員共享。

  ---4 靜态僅僅能調用靜态。非靜态能夠調用靜态。

  static(類變量(在方法區中))object(執行個體變量(在堆中))

  方法預設存儲在方法區中,而當執行的時候才在棧中。

  ---------------

  static 代碼塊(那他和jni有什麼差别呢)

  1 随着類的載入而載入,并且僅僅運作一次。

  2 優先于主函數運作。

  3 給類初始化。

  單例模式:為了保證一個project僅僅有一個對象。

  eg: 對象也能夠用來封裝資料。

  1 懶漢式。

  2 餓漢式。

  由于static 是随着類的載入而載入的,浪費記憶體。

是以為了避免一定的空間浪費,開發中推薦懶漢式,特别是android

  單例中出現的方法。是為了[可控]

--------------------------------------------------------

2 繼承:(單繼承[調用的不确定性],多實作)

 1 讓類與類之間産生了關系。

 2 對共性進行了抽取(屬性和方法)。

 3 子類能夠調用父類的屬性和方法。前提是僅僅能訪問父類中public的。

并且子類中使用的時候不會自己主動提示,可是我們手動寫。

 4 在子類的全部構造函數的第一行,預設有一句 super(),他會去調用父類的構造方法。

 5 【凡是】子類繼承父類。父類和子類的屬性,都在子類的堆記憶體區其中。是以父類有的,子類就能夠不用寫了。寫了就是記憶體浪費。

    特殊情況[android 自己定義控件]例如以下:

 6 當子類重寫父類了的方法之後。就會将父類的方法進行屏蔽。以後調用這種方法,都是去運作子類的邏輯,在android自己定義控件中用的比較多。

 7 結論:父類的構造函數,既能夠給本類對象初始化,也能夠給子類對象初始化。

------------------

 繼承就是不斷的向上抽取。僅僅有在其子類才有特有的功能,什麼時候繼承得看情況。

 this能夠代表目前對象。super 代表父類空間。

 被private 修飾的不能被子類繼承訪問。

可是子類的堆記憶體中有。

 當子父類中出現一摸一樣的方法時。子類會覆寫(重寫)父類的方法。

而且子類的權限要>=父類。

 重載是函數名同樣,參數不同。和覆寫不一樣。

 static僅僅能覆寫static

 在一個類中:當有參構造的出現,預設的無參構造會消失。

 繼承會把父類中的所有public的功能所有拿過來。

final

被final 修飾的屬性不能改動、類不能繼承、方法不能重寫。

在開發中常量就能夠用final 來修飾,可是名稱得大寫。

并且在繼承中,假設子類中有,預設是調用子類的,子類沒有才調用父類的。

構造代碼塊:在super()和自己的代碼之間,會調用構造代碼塊。

一個對象在記憶體中産生的過程:

1 将該對象所需的類檔案載入進記憶體。

2 在記憶體中進行空間的方法區的空間配置設定。

3 通過new 在堆中開辟空間。

4 對象中的屬性進行預設初始化。

5 調用與之對象的構造函數進行初始化。

6 通過構造函數的super調用父類中的構造函數初始化。

7 對象中的屬性進行顯示初始化。

8 構造代碼塊初始化。

9 該構造函數内部自己定義内容進行初始化。

 抽象:is a  [是](多個子類繼承同一個父類)

 當你描寫叙述一個事物的時候,沒有足夠的資訊對該事物進行描寫叙述,那麼這個事物相應的類就是一個抽象類。

 抽象類不能執行個體化。

 抽象類中的方法必須所有重寫。

 抽象類中能有自己的特有方法。(接口不能)

 抽象類必需要被繼承。

 子類能繼承一切非 private 的方法。

 繼承的本意在于抽象,而非代碼的重用。

 -----------------

 接口:like a  [像](多個接口能被同一個類實作)

 接口裡面的方法都是抽象方法。

 接口裡面的常量都是靜态不可被改動的。

 接口僅僅能實作不能被new。

 接口能多實作。

(攻克了java的單實作的問題)

 接口能繼承接口。并且接口能夠【多繼承】。

 接口的出現是為了定義額外的功能。

接口回調:

1 在Fragment類 中定義一個Test接口。

2 在Fragment類 中定義一個接口對象常量。

3 在Fragment類 中定義一個方法。為接口的引用指派,參數是實作類的子類。

4 在MainActivity類 中實作Test接口。重寫接口裡面的方法。在方法裡面寫上自己的邏輯。

5 在TestCallBack類 中new Fragment這個對象。

調用執行個體化接口的那個方法。參數是new MainActivity();(假設執行null,就傳this吧)

-----------------

3 多态:

父類或接口的引用指向子類的執行個體對象。

優點:提高了代碼的拓展性。

壞處:不能使用子類的特有内容。

假設想使用子類的特有功能,就得向下轉型。

instanceof:向下轉型的keyword,僅僅能用于引用類型的推斷。

多态-成員變量:編譯執行都看左邊。

多态-成員函數:編譯看左邊,執行看右邊。

-----------------------------------------------

多線程:

程序:正在運作的任務程式。

線程:程式運作的程式。

自己定義線程執行的任務都執行在run方法中。

當調用。start()方法後,線程内部。會自己主動運作run() 方法;

有2種方式建立線程。

1 實作Runnable接口。(這個比較好可以起拓展用的)

2 繼承 Thread 類。

(這個比較寫死)

同步鎖:

僅僅要保證鎖是同一個鎖就不會出現線程安全的問題。

JDK 1.5 之後。Lock替代了同步,Condition替代了Object中的螢幕方法。

private final Lock lock=new ReentrantLock();//建立鎖對象

private Condition xiaofei=lock.newCondition();//子鎖1

private Condition shencan=lock.newCondition();//子鎖2

lock.lock();//加鎖

xiaofei.await(); //等待

shencan.signal(); //喚醒

lock.unlock();//解鎖

----------------------------------------------

eclipse 模闆

方法中去掉無用的凝視 java->code style ->code templates

自己定義快捷鍵 java->Editor-> Templates

StringBuffer(線程安全,在多線程的時候使用) StringBuilder(線程不安全,沒有線程的時候。開發中建議使用這個)

字元串比較。實作 Comparable 接口,調用 Comparto()方法,會依照字典大小排序。他的傳回值是0或1。

基本資料類型,字元串轉為對象 Character

toLowerCase(char ch);【指定字元串:變小寫】

toUpperCase(cher ch);【指定字元串:變大寫】

------------

toBinatyString 二進制

toHexString 十六進制

toOctalString 八進制

==================================================集合  記住 Collection 下的集合都能被疊代 Iterator

集合長度可變。數組長度不可變。

集合能夠存儲多種類型對象,數組僅僅能存儲單一類型的對象。

Iterator是Collection全部子集合共性抽取的疊代接口;

    Collection[接口]   (集合都有:增,删。改,查。的方法)                                 

     List: 連結清單結構:能夠模仿堆棧。

   注意問題:在疊代集合的時候,/*假設須要對集合進行并發操作,會出現并發改動異常*/,我們得把Iterator 換為ListIterator。

   他的功能比 Iterator很多其它。(詳情檢視api)

    非線程安全:

    ArrayList 查詢快。增删慢。

    LinkedList 增删快。查詢慢。 【能夠用來模仿堆棧 addLast(),removeFlast()】

    /*線程安全*/。在多線程的時候使用:

    Vector 底層是數組結構。他疊代的時候能夠用枚舉接口, Enumeration 來疊代。由于枚舉在的時候還沒有集合架構。

  Set:  集合結構:能夠用來去重。

   HashSet 無序的。

存儲時速度巨快,由于底層是依據雜湊演算法來實作的。

可是不關心順序,而且唯一。

須要查詢hashCode() 和equers()

    自己定義對象(往哈希表中存儲資料的時候)要重寫 equals(),HashCode()  方法。

才幹做比較。

    自己定義對象(假設想讓對象具備比較大小的功能,依照自然順序排序,必需要實作 Comparable接口 )

    eg:/*牛逼的equers()方法

     public boolean equers(Object obj){

      if(this==obj){//比較位址

       return true;

      }

      if(!(obj instanceof Student)){

       throws new ClassCastException("類型不比對,無法比較");

      Student stu=(Student) obj;

      return this.name.equals(stu.name) && this.age==stu.age;

     }

     */

   TreeSet:

    排序方式1:

     使用元素的自然順序進行排序。他保證資料的唯一性,是在自己定義對象中實作 Comparable接口 重寫compareTo()看傳回值是否為0,為0就是反複的元素。

    排序方式2:

     定義一個比較器,讓對象一初始化就具備比較功能。實作 Comparator 接口。

重寫 compare()方法,相等傳回0;

     假設須要先依照字典排序又要依照長度排序,那麼就得在compare()裡面繼續調用 compareTo() 方法了。

     實作原理是二叉樹比較法。就像二分查找法一樣。

     person p=(person)o;

     int temp =this.age-p.age;

     return temp==0?this.name.compareTo(p.name):temp;

   LinkedHashSet:

    有序且去反複的清單:

  範型:

   上邊界: ?

extends person (傳遞進來的參數僅僅能為 person的本身或者子類型)

   下邊界: person super ? ()

  泛型類:

  省去了以前的強轉和類型轉換異常的麻煩。(将泛型定義在類上。使用者僅僅須要在使用這個類的時候傳入泛型就能夠了)

  詳細什麼類型由使用者确定。

  eg: public Util<T>{   //使用方僅僅須要   這樣使用    Util<Person> u=new Util<Person>

    private T t;//        u.setT(new Person());

    public void setT(T t){//     u.getT();

     this.t=t;

    }

    public T getT(){

     return t;

   }

  泛型方法:在不确定方法的參數的時候,須要什麼類型自己傳遞 (基本資料類型。或者對象類型,都能夠)

  eg: public <W> void show(W w){

    System.out.println("w:"+w);

  泛型接口:也是傳入的參數不确定的時候使用的。

  eg:public interfrace inner<V>{

    public abstract void show(V v);

   class innerImpl<C> implements inner<C>{

    public void show(C c){

     System.out.println("c:"+c);

   main(String[] args){

    new innerImpl<Integer>().show(new Integer(3));

    new innerImpl<String>().show(new String("ok"));

  fore() 循環。不操作角标,能操作數組和 Connection集合;

 Map(Key,Value):

  key不能反複;

  取值有2種方式:

   1 map.keySet 得到全部key的集合

   2 map.entrySet 得到全部key和value的集合  (entry 實體對象)

  1.0 Hashtable 線程安全,key value不同意為空(和Vector一個時代的)

  1.2 HashMap   線程不安全,key value同意為空【假設是自己定義對象,在疊代的時候要去除反複的key,能夠參閱 250行牛逼的equers()方法】

   TreeMap   底層是二叉樹實作的,假設想讓自己定義對象也具有比較性,必須實作 Comparable接口,查詢 compareTo();

   LinkedHashMap 有序結構的連結清單集合(内部模拟了堆棧的實作)

   //Properties 他也是鍵值對的屬性集。重要的是他能持久化這個集合,用于IO流讀取。他的父類是HashTable

 專門操作集合的工具類:

 Collections   eg:詳情檢視api;  工具類中有,synchronizedCollection(),List,Map能夠将非同步的集合轉為同步的集合。

 Arrays    eg:詳情檢視api; asList(int[] i)數組轉集合。

可是有些方法是不能用的。

由于集合是固定的。不能做增删操作。

          toArray()集合轉數組。

定義類型必須一緻。

  可變參數: ... 能夠替代非常多個數的數組,前提是必須放在參數清單的最後面。

其它api:

 System: 有一個非常有意思的api。 System.getProperties()他能傳回這個整個環境和工具的資訊的集合。

 還能夠通過集合裡面特定的key值,能夠在不同平台下都能使用的特殊功能符号。

 Runtime:這是一個底層由單例模式完畢的執行時類。 通過Runtime.getRuntime()能夠得到他的對象。詳情檢視 api

 eg:啟動qq  Runtime.getRuntime().extc("qq.exe");{這裡面,寫的的是Dos指令}

 Math: abs()絕對值 , ceil 天花闆 floor地闆 round四舍五入 Max最大 Min最小 pow幂運算,... 正旋餘弦 很多其它檢視api

IO流:用來處理裝置間的傳輸資料。分輸出流和輸入流。

{僅僅要對象一建立就有檔案。

假設已經存在會被覆寫}

 使用完之後一定要記得關閉流對象。并且得放在finally中,并且這個流對象還得做非空推斷,防止對象沒有建立成功,報null異常。

因為作業系統不同。有的時候\r\n 不好使,是以我們使用 System.getProperty("line.separator");

位元組流:

 InputStream OutputStream: (看頂層,用底層)

 FileInputStream

 FileOutputStream

 位元組流能夠直接将内容寫到目的地,不須要暫時存儲就能操作檔案,比字元流少了走緩沖區這一步。

他是直接操作位元組的。

 裝飾模式:

 BufferedInputStream 對已有的對象提供了額外的功能,還不用對源對象進行改動,避免了繼承的臃腫。

 BufferedOutputStream

 轉換流:(事實上我想說:他也是代理模式麼?)

 InputStreamReader(new InputStream()):位元組轉字元,将記憶體看不懂的位元組轉為能夠看懂的文字。

 OutputStreamWriter(new OutputStream()):字元轉位元組。将看的懂的文字轉為記憶體為看不懂的位元組。

字元流:(位元組流+編碼表)

 Reader Writer:

 FileWriter FileReader

 檔案操作流。

 對檔案進行續寫 new FileWriter("demo.txt",true);

 在記憶體中定義高效的緩沖區:(一般擷取記憶體中的速度遠比直接擷取目的地的資料快高效)

 BufferedReader(new FileReader());  BufferedWriter(new FileWriter());

 [事實上BufferedReader 這樣的方式是典型的裝飾模式的應用:對已有的對象提供了額外的功能,還不用對源對象進行改動,避免是繼承的臃腫]

 BufferedReader(new FileReader());

 LineNumberReader(new FileReader());

IO流4步曲

 1 明白源和目的 I  O

 2 是否純文字 FileReader

 3 明白裝置

 4 是否須要高效 BufferReader

 轉行流:

 InputStreamReader(),指定編碼表 InputStreamReader(is,"UTF-8");

 OutputStreamWriter(),指定編碼表 OutputStreamWriter(os,"UTF-8");

File 類:

 File.separator 名稱分隔符,在不論什麼環境下都能使用。linux和windows下都能識别。他會自己主動轉換

 File.getTotalSpace() 總大小

 File.getFreeSpace() 剩餘空間

 File.deleteOnExit();退出系統的時候會自己主動删除檔案(是以在我們建立檔案之後能夠立刻寫這句話)

 File.isFile() 是否為檔案

 File.isDirectory() 是否為目錄

 file.list(new filter());檔案過濾器

 file.listFilse(new filter());目錄過濾器

SequenceInputStream 合并流:

public static void main(String[] args) throws IOException {

  将多個流進行邏輯串聯(進行合并,變成一個流,操作起來非常友善,由于多個源變成了一個源)

  FileInputStream fis1 = new FileInputStream("tempfile\\seq_1.txt");

  FileInputStream fis2 = new FileInputStream("tempfile\\seq_2.txt");

  FileInputStream fis3 = new FileInputStream("tempfile\\seq_3.txt");

  ArrayList<FileInputStream> v = new ArrayList<FileInputStream>();

  v.add(fis1);

  v.add(fis2);

  v.add(fis3);

  Enumeration<FileInputStream> en = Collections.enumeration(v);

  SequenceInputStream sis = new SequenceInputStream(en);

  //建立目的。

  FileOutputStream fos = new FileOutputStream("tempfile\\seq_4.txt");

  byte[] buf = new byte[1024];

  int len = 0;

  while((len=sis.read(buf))!=-1){

   fos.write(buf,0,len);

  }

  fos.close();

  sis.close();

 RandomAccessFile:多線程下載下傳專用流。

 seek(8); 能随機操作指針的方法,能夠開啟多個線程同一時候操作這個對象。達到多線程下載下傳。

 從看不懂到看得懂解碼,從看的懂到看不懂,編碼。

檔案加密:

 public static void main(String[] args) throws IOException {

  BufferedInputStream bis = new BufferedInputStream(new FileInputStream("copy4.mp3")); // 建立流對象,并給流對象加上緩沖區

  BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy5.mp3"));

//  byte[] buf=new byte[1024]; 操作位元組的時候,自己定義的緩存數組就不要了,會導緻垃圾産生

  int b=0;

  while ((b = bis.read(/*buf*/)) != -1) {

   bos.write(b ^ 111);//這個11 就是密鑰

  bis.close();

  bos.close();

網絡程式設計:

UDP:

不須要建立連接配接速度快。資料限制大小在64k之内,無連接配接,不可靠協定。

TCP:

須要建立連接配接。經過3次握手。能夠進行大傳輸資料,是可靠協定,但效率會稍低。

TCP協定,多線程上傳檔案,源代碼

public class UploadPicClient {

 public static void main(String[] args) throws UnknownHostException, IOException {

  if(args.length!=1){

   System.out.println("請指定檔案");

   return;

  File file = new File(args[0]);

  if(!(file.exists() && file.isFile())){

   System.out.println("該檔案不存在,或不是正确的檔案,又一次指定");

  if(!(file.getName().endsWith(".jpg") || file.getName().endsWith(".gif"))){

   System.out.println("檔案擴充名必須是jpg。或者而是 gif。");

  if(file.length()>=1024*1024*2){

   System.out.println("檔案過大,又一次選擇,");

  Socket s = new Socket("192.168.1.100",10006);

  FileInputStream fis = new FileInputStream(file);

  OutputStream out = s.getOutputStream();

  while((len=fis.read(buf))!=-1){

   out.write(buf,0,len);

  //告訴server端,發送資料完成,發送一個結束标記。

  s.shutdownOutput();

  InputStream in = s.getInputStream();

  byte[] bufIn = new byte[1024];

  int lenIn = in.read(bufIn);

  String info = new String(bufIn,0,lenIn);

  System.out.println(info);

  fis.close();

  s.close();

public class UploadPicServer {

  //服務端,接收client發送過來的圖檔資料。 進行存儲後,回饋一個 上傳成功字樣。 多使用者的并發訪問。

  ServerSocket  ss = new ServerSocket(10006);

  while(true){    

   Socket s  = ss.accept();

   new Thread(new UploadThread(s)).start();

//  ss.close(); 

public class UploadThread implements Runnable {

 private Socket s;

 public UploadThread(Socket s) {

  super();

  this.s = s;

 @Override

 public void run() {

  String ip = s.getInetAddress().getHostAddress();

  System.out.println(ip+"......connected");

  try{

  //讀取資料。網絡。

  File dir = new File("c:\\mypic");

  if(!dir.exists())

   dir.mkdir();

  int count = 1;

  File file = new File(dir,ip+".jpg");

  while(file.exists()){

   file = new File(dir,ip+"("+(count++)+").jpg");

  //目的:檔案

  FileOutputStream fos = new FileOutputStream(file);

  while((len=in.read(buf))!=-1){

  out.write("上傳成功".getBytes());

  catch(IOException e){