search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

java學習筆記(一)

Java是一門好的語言,也是一門龐雜的系統,學習過程中要善於記錄和積累。

學習了四年java,但回頭看看好像什麼都沒學到,是因為學習沒有成系統,知識沒有成系統。

面向對象編程有很多重要的特性

比如:封裝,繼承,多態和抽象。下面的章節我們會逐個分析這些特性。

封裝

封裝給對象提供了隱藏內部特性和行為的能力。對象提供一些能被其他對象訪問的方法來改變它內部的數據。在Java當中,有3種修飾符:public,private和protected。每一種修飾符給其他的位於同一個包或者不同包下面對象賦予了不同的訪問許可權。

下面列出了使用封裝的一些好處:

  • 通過隱藏對象的屬性來保護對象內部的狀態。
  • 提高了代碼的可用性和可維護性,因為對象的行為可以被單獨的改變或者是擴展。
  • 禁止對象之間的不良交互提高模塊化。

繼承

繼承給對象提供了從基類獲取欄位和方法的能力。繼承提供了代碼的重用行,也可以在不修改類的情況下給現存的類添加新特性。Java不支持多繼承。每個類都只能繼承一個類,但是可以實現多個介面。

在java中:多態,是面向對象的程序設計語言最核心的特徵。多態,意味著一個對象有著多重特徵,可以在特定的情況下,表現不同的狀態,從而對應著不同的屬性和方法。從程序設計的角度而言,多態可以這樣來實現(以java語言為例)://當然還可以有其他的實現然後,我們就可以看到多態所展示的特性了:Parent pa = new Child_A;pa.simpleCall則顯然是調用Child_A的方法;Parent pa = new Child_B;pa.simpleCall則是在調用Child_B的方法。所以,我們對於抽象的父類或者介面給出了我們的具體實現后,pa 可以完全不用管實現的細節,只訪問我們定義的方法,就可以了。事實上,這就是多態所起的作用,可以實現控制反轉這在大量的J2EE輕量級框架中被用到,比如Spring的依賴注入機制。

抽象

抽象是把想法從具體的實例中分離出來的步驟,因此,要根據他們的功能而不是實現細節來創建類。Java支持創建只暴漏介面而不包含方法實現的抽象的類。這種抽象技術的主要目的是把類的行為和實現細節分離開。

抽象和封裝的不同點

抽象和封裝是互補的概念。一方面,抽象關注對象的行為。另一方面,封裝關注對象行為的細節。一般是通過隱藏對象內部狀態信息做到封裝,因此,封裝可以看成是用來提供抽象的一種策略。

java虛擬機:jvm可以執行java位元組碼(java源文件被編譯成位元組碼文件),可以使java運行在任意平台,不需要程序員為每一個平台重寫代碼重新編譯。

jdk和jre:java開發工具包(包含jre編譯器和其他工具),java運行環境。

java中的static的作用;(可以在沒有實例化的情況下被訪問)

是靜態修飾符,什麼叫靜態修飾符呢?大家都知道,在程序中任何變數或者代碼都是在編譯時由系統自動分配內存來存儲的,而所謂靜態就是指在編譯后所分配的內存會一直存在,直到程序退出內存才會釋放這個空間,也就是只要程序在運行,那麼這塊內存就會一直存在。這樣做有什麼意義呢? 在Java程序裡面,所有的東西都是對象,而對象的抽象就是類,對於一個類而言,如果要使用他的成員,那麼普通情況下必須先實例化對象后,通過對象的引用才能夠訪問這些成員,但是有種情況例外,就是該成員是用static聲明的(在這裡所講排除了類的訪問控制),例如: 未聲明為static class ClassA{ int b; public void ex1{ … } } class ClassB{ void ex2{ int i; ClassA a = new ClassA; i = a.b; //這裡通過對象引用訪問成員變數b a.ex1; //這裡通過對象引用訪問成員函數ex1 } } 聲明為static class ClassA{ static int b; static void ex1{ … } } class ClassB{ void ex2{ int i; i = ClassA.b; //這裡通過類名訪問成員變數b ClassA.ex1; //這裡通過類名訪問成員函數ex1 } } 通過以上兩種比較,就可以知道static用來修飾類成員的主要作用了,在java類庫當中有很多類成員都聲明為static,可以讓用戶不需要實例化對象就可以引用成員,最基本的有Integer.parseInt,Float.parseFloat等等用來把對象轉換為所需要的基本數據類型。這樣的變數和方法我們又叫做類變數和類方法。 接下來講一下被static修飾后的變數的值的問題,剛才在前面講過,被static修飾后的成員,在編譯時由內存分配一塊內存空間,直到程序停止運行才會釋放,那麼就是說該類的所有對象都會共享這塊內存空間,看一下下面這個例子: class TStatic{ static int i; public TStatic{ i = 4; } public TStatic(int j){ i = j; } public static void main(String args){ TStatic t = new TStatic(5); //聲明對象引用,並實例化 TStatic tt = new TStatic; //同上 System.out.println(t.i); System.out.println(tt.i); System.out.println(t.i); } } 這段代碼裡面Tstatic類有一個static的int變數I,有兩個構造函數,第一個用於初始化I為4,第二個用於初始化i為傳進函數的值,在main中所傳的值是5,程序首先聲明對象的引用t,然後調用帶參數的構造函數實例化對象,此時對象t的成員變數I的值為5,接著聲明對象tt,調用無參數的構造函數,那麼就把對象tt的成員變數i的值初始化為4了,注意了,在這裡i是static,那就是說該類的所有對象都共享該內存,那也就是說在實例化對象tt的時候改變了i的值,那麼實際上對象t的i值也變了,因為實際上他們引用的是同一個成員變數。最後列印的結果是三個4。Java中static方法不能被覆蓋,因為方法覆蓋是基於運行時動態綁定的,而static方法是編譯時靜態綁定的。static方法跟類的任何實例都不相關,所以概念上不適用。java中的自動裝箱和拆箱:(基本數據類型和對象包裝類型)

  • byte
  • short
  • int
  • long
  • float
  • double
  • boolean
  • char

自動裝箱是Java編譯器在基本數據類型和對應的對象包裝類型之間做的一個轉化。比如:把int轉化成Integer,double轉化成double,等等。反之就是自動拆箱。

java的方法重載、方法覆蓋和構造函數:Java中的方法重載發生在同一個類裡面兩個或者是多個方法的方法名相同但是參數不同的情況。(體現了多態性)與此相對,方法覆蓋是說子類重新定義了父類的方法。方法覆蓋必須有相同的方法名,參數列表和返回類型。覆蓋者可能不會限制它所覆蓋的方法的訪問。

當新對象被創建的時候,構造函數會被調用。每一個類都有構造函數。在程序員沒有給類提供構造函數的情況下,Java編譯器會為這個類創建一個默認的構造函數。

Java中構造函數重載和方法重載很相似。可以為一個類創建多個構造函數。每一個構造函數必須有它自己唯一的參數列表。

抽象類和介面:介面和抽象類的定義類似、區別是:一個類實現介面、必須實現介面里的所有方法、而且一個類可以實現多個介面(相當於多繼承)介面使用interface關鍵字、而抽象類使用的是abstract 關鍵字、一個類只能繼承一次。繼承抽象類的話、是可以不全部實現他的所有方法的。但是你可以重寫他的方法

介面和抽象類的概念不一樣。介面是對動作的抽象,抽象類是對根源的抽象。

抽象類表示的是,這個對象是什麼。介面表示的是,這個對象能做什麼。比如,男人,女人,這兩個類(如果是類的話……),他們的抽象類是人。說明,他們都是人。

人可以吃東西,狗也可以吃東西,你可以把「吃東西」定義成一個介面,然後讓這些類去實現它.

所以,在高級語言上,一個類只能繼承一個類(抽象類)(正如人不可能同時是生物和非生物),但是可以實現多個介面(吃飯介面、走路介面)。

第一點. 介面是抽象類的變體,介面中所有的方法都是抽象的。而抽象類是聲明方法的存在而不去實現它的類。 第二點. 介面可以多繼承,抽象類不行 第三點. 介面定義方法,不能實現,而抽象類可以實現部分方法。 第四點. 介面中基本數據類型為static 而抽類象不是的。

當你關注一個事物的本質的時候,用抽象類;當你關注一個操作的時候,用介面。

抽象類的功能要遠超過介面,但是,定義抽象類的代價高。因為高級語言來說(從實際設計上來說也是)每個類只能繼承一個類。在這個類中,你必須繼承或編寫出其所有子類的

所有共性。雖然介面在功能上會弱化許多,但是它只是針對一個動作的描述。而且你可以在一個類中同時實現多個介面。在設計階段會降低難度的。

進程和線程:線程是系統中執行的最小單元,同一進程中有許多線程,線程共享進程的資源。創建線程的方法:1.實現Thread類2.實現Runnable介面

  • 3.應用程序可以使用Executor框架來創建線程池

線程執行過程中的幾種狀態:

  • 就緒(Runnable):線程準備運行,不一定立馬就能開始執行。
  • 運行中(Running):進程正在執行線程的代碼。
  • 等待中(Waiting):線程處於阻塞的狀態,等待外部的處理結束。
  • 睡眠中(Sleeping):線程被強制睡眠。
  • I/O阻塞(Blocked on I/O):等待I/O操作完成。
  • 同步阻塞(Blocked on Synchronization):等待獲取鎖。
  • 死亡(Dead):線程完成了執行。

java中的集合類:

Java集合類提供了一套設計良好的支持對一組對象進行操作的介面和類。Java集合類裡面最基本的介面有:

  • Collection:代表一組對象,每一個對象都是它的子元素。
  • Set:不包含重複元素的Collection。
  • List:有順序的collection,並且可以包含重複元素。
  • Map:可以把鍵(key)映射到值(value)的對象,鍵不能重複。

.數組(Array)和列表(ArrayList)有什麼區別?什麼時候應該使用Array而不是ArrayList?

下面列出了Array和ArrayList的不同點:

  • Array可以包含基本類型和對象類型,ArrayList只能包含對象類型。
  • Array大小是固定的,ArrayList的大小是動態變化的。
  • ArrayList提供了更多的方法和特性,比如:addAll,removeAll,iterator等等。
  • 對於基本類型數據,集合使用自動裝箱來減少編碼工作量。但是,當處理固定大小的基本數據類型的時候,這種方式相對比較慢。

ArrayList和LinkedList有什麼區別?

ArrayList和LinkedList都實現了List介面,他們有以下的不同點:

  • ArrayList是基於索引的數據介面,它的底層是數組。它可以以O(1)時間複雜度對元素進行隨機訪問。與此對應,LinkedList是以元素列表的形式存儲它的數據,每一個元素都和它的前一個和后一個元素鏈接在一起,在這種情況下,查找某個元素的時間複雜度是O(n)。

  • 相對於ArrayList,LinkedList的插入,添加,刪除操作速度更快,因為當元素被添加到集合任意位置的時候,不需要像數組那樣重新計算大小或者是更新索引。

  • LinkedList比ArrayList更占內存,因為LinkedList為每一個節點存儲了兩個引用,一個指向前一個元素,一個指向下一個元素。

  • HashSet和TreeSet有什麼區別?

  • HashSet是由一個hash表來實現的,因此,它的元素是無序的。add,remove,contains方法的時間複雜度是O(1)。

    另一方面,TreeSet是由一個樹形的結構來實現的,它裡面的元素是有序的。因此,add,remove,contains方法的時間複雜度是O(logn)。

Comparable和Comparator介面是幹什麼的?列出它們的區別。

Java提供了只包含一個compareTo方法的Comparable介面。這個方法可以個給兩個對象排序。具體來說,它返回負數,0,正數來表明輸入對象小於,等於,大於已經存在的對象。

Java提供了包含compare和equals兩個方法的Comparator介面。compare方法用來給兩個輸入參數排序,返回負數,0,正數表明第一個參數是小於,等於,大於第二個參數。equals方法需要一個對象作為參數,它用來決定輸入參數是否和comparator相等。只有當輸入參數也是一個comparator並且輸入參數和當前comparator的排序結果是相同的時候,這個方法才返回true。

java中的垃圾回收機制:

http://blog.csdn.NET/zsuguangh/article/details/6429592

意義:除了釋放沒用的對象,垃圾回收也可以清除內存記錄碎片

Java的垃圾回收機制是JVM提供的能力,用於在空閑時間以不定時的方式動態回收無任何引用的對象佔據的內存空間。 需要注意的是:垃圾回收回收的是無任何引用的對象佔據的內存空間而不是對象本身System.gc Runtime.getRuntime.gc 上面的方法調用時用於顯式通知JVM可以進行一次垃圾回收,但真正垃圾回收機制具體在什麼時間點開始發生動作這同樣是不可預料的,這和搶佔式的線程在發生作用時的原理一樣。

finalize方法什麼時候被調用?析構函數(finalization)的目的是什麼?

在釋放對象佔用的內存之前,垃圾收集器會調用對象的finalize方法。一般建議在該方法中釋放對象持有的資源



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦