国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

<java核心技術>讀書筆記2

jimhs / 3253人閱讀

摘要:如果需要收集參數化類型對象,只有使用警告這節討論,向參數可變的方法傳遞一個泛型類型的實例。異常不能拋出或捕獲泛型類的實例實際上,泛型類擴展也是不合法的。

Object:所有類的超類

java中每個類都是由它擴展而來,但是并不需要這樣寫:class Employee extends Object.如果沒有明確指出超類,Object類就被認為是這個的超類。
可以使用Object類型的變量引用任何類型的對象Object obj=new Employee().
在java中,只有基本類型(int,boolean,...)不是對象所有的數組類型,不管是對象數組還是基本類型的數組都擴展自Object類

Employee[] staff=new Employee[10];
Object obj=staff;//ok
obj=new int[10];//ok
對象包裝器與自動裝箱

有時需要將int這樣的基本類型轉換為對象,所有基本對象都有一個與之對應的類。如int->Integer.這些類稱為包裝類(wrapper).具體的,包括Integer,Long,Float,Double,Short,Byte,Character,Void,Boolean,前6個派生于它們公共的超類Number.
對象包裝類是不可變的,一旦創建,就不允許更改包裝在其中的值。
對象包裝類還是final,不能定義它們的子類。
java5之后,調用list.add(3)將自動變換成list.add(Integer.valueOf(3)),這種變換稱為自動裝箱。相反的,將一個Integer對象賦值給一個int值時,會自動拆箱

List list=new ArrayList();
list.add(3);
int n=list.get(0);//等同于list.get(0).intValue();

在算術表達式中,也可以自動裝箱,自動拆箱。

Integer n=3;
n++;//拆箱->自增->裝箱

==運算符用于比較包裝器對象,只不過檢測的是對象是否指向同一個存儲區域。因此,下面比較不會成立

        Integer a=1000;
        Integer b=1000;
        System.out.println(a==b);//false

但是如果包裝的值經常出現,==比較就有可能相等

        Integer a=100;
        Integer b=100;
        System.out.println(a==b);//true

這個和python類似

python并不是對創建的所有對象都會重新申請新的一塊內存空間。作為一種優化,python會緩存不變的對象(如數值較小的數字,字符串,元組等)并對其進行復用。

因此,java設定了自動裝箱規范

boolean

byte

char<=127

介于-128和127之間的short,int

被包裝到固定的對象中。
上面例子a,b是100,第二次賦值時,java不會重新申請新的一塊內存空間,存儲100這個值。

接口

接口特性

接口不是類,不能使用new運算符實例化一個接口

可以聲明接口變量,但必須引用實現了接口的類對象

可以使用instanceof檢查一個對象是否實現了某個特定的接口

接口可以繼承接口InterfaceA extends InterfaceB

接口中不能包含實例變量或靜態方法,卻可以包含常量

public interface Interface {
    String name="aaa";//a public static final constant
}

常量會自動被設為public static final

盡管每個類只允許擁有一個超類,卻可以實現多個接口class Concrete implements InterfaceA,InterfaceB

內部類

內部類方法可以訪問該類所在的作用域中的數據,包括私有數據

內部類可以對同一個包中的其他類隱藏起來

當想要定義一個回調函數且不想寫大量代碼時,使用匿名內部類比較方便

泛型 泛型類

泛型類:具有一個或多個類型變量的類。類型變量可以指定方法的返回類型以及類變量和局部變量的類型

public class Pair {
    T first;
    T second;
    Pair(){
        this.first=null;
        this.second=null;
    }
    Pair(T first,T second){
        this.first=first;
        this.second=second;
    }
    public T getFirst() {
        return first;
    }
    public void setFirst(T first) {
        this.first = first;
    }
    public T getSecond() {
        return second;
    }
    public void setSecond(T second) {
        this.second = second;
    }
}

Pair類引入一個類型變量T,用尖括號(<>)括起來,并放在類名的后面。
泛型可以有多個類型變量``

public class Pair {
    ...
}

實例化Pair pair=new Pair(),這時類型變量T就會被替換成String.這時,泛型類就可以看做普通類。

泛型方法

泛型方法可以定義在普通類中。

public  T getMethod(T... a){}

類型變量放在修飾符(這里是public)的后面,返回類型的前面
調用class.getMethod()
如果是上面情況,大多數時候,方法調用可以省略類型參數。編譯器有足夠的信息推斷出調用的方法。String[]與泛型類型T[]進行匹配,并推斷出T一定是String.
但是,如果是下面代碼

double result=class.getMethod(1.23,123,0);

編譯器會自動將參數打包為1個Double和2個Integer對象,然后尋找這些類的共同超類型,最終找到兩個這樣的超類NumberComparable,其本身也是泛型類型,這種情況下,只有將所有的參數寫成double值。
如果想知道一個泛型方法最終推斷出哪種類型,可以有目的的引入一個錯誤,看產生的錯誤信息,比如

class.getMethod("aaa",0,null);
//found:java.lang.Object&java.io.Serializable&java.util.Comparable...

意思是可以將結果賦給Object,Serializable或Comparable.

類型變量的限定
 T min(T[] a);

上面代碼將T限制為實現了Comparable接口的類,這樣min方法只能被實現了實現了Comparable接口的類(如String,Date類)的數組調用。
注意這里用的是extends關鍵字
extends BoundingType表示T應該是綁定類型的子類型(subtype),T和綁定類型可以是類,也可以是接口.選擇extends關鍵字的原因是跟接近子類型的概念。
一個類型變量或通配符可以有多個限定,如T extends Serializable&Comparable.&隔開限定類型,,隔開類型變量。
由于對類是單繼承,對接口多重繼承,如果限定類型中有類又有接口,必須將類作為限定列表中的第一個

泛型的局限

大多數限制都是由類型擦除引起的,類型擦除可以參見Java泛型:類型擦除

不能用基本類型實例化類型參數。
沒有Pair,只有Pair,因為類型擦除之后,類型參數變為Pair,而Object不能存儲double值。

運行時類型查詢只試用于原始類型。
虛擬機中的對象總有一個特定的非泛型類型,因此所有的類型查詢只產生原始類型。

if(a instanceof Pair)...//error
if(a instanceof Pair)...//error
Pair p=(Pair) a;//warning,can only test that a is a Pair

同樣的道理,getClass方法總是返回原始類型。

Pair stringPair=...;
Pair employeePair=...;
if(stringPair.getClass()==employeePair.getClass())...//they are equal

上面代碼兩次調用getClass都將返回Pair.class.

不能創建參數化類型的數組

Pair[] paris=new Pair[10];
//error,The type of the expression must be an array type but it resolved to Pair

上面代碼的問題在于,類型擦除后,paris的類型是Pair[],可以轉換為Object[]

Object[] objarray=pairs;

數組會記住它的元素類型,如果試圖存儲其他類型的元素,就會拋出Array-StoreException.
只是不允許這樣創建數組,而聲明類型為Pair[]的變量仍然是合法的。不過不能用new Pair[10]初始化這個變量。
可以聲明通配類型的數組,然后類型轉換

Pair[] pairs=(Pair[]) new Pair[10];

但這樣類型是不安全的。
如果需要收集參數化類型對象,只有使用ArrayList>.

Varargs警告
這節討論,向參數可變的方法傳遞一個泛型類型的實例。

static  void addAll(Collection coll,T... ts){
    for(T t:ts)
        coll.add(t);
}
Collection> coll=...;
Pair pair1=...;
Pair pair2=...;
addAll(coll,pair1,pair2);

為了調用addAll方法,java虛擬機必須建立一個Pair數組,這就違反了上一個泛型局限。
不過,對于這種情況,規則有所放松,只會得到一個警告,而不是錯誤。
有兩種方法抑制這個警告

為包含addAll調用的方法添加標注@SuppressWarnings("unchecked").

如果是java7或其后面版本,用@SafeVarargs直接標注addAll方法。

@SafeVarargs
static  void addAll(Collection coll,T... ts)

不能實例化類型變量
不能使用像new T(),new T[],T.class這樣的表達式中的類型變量。

泛型類中靜態類型變量無效
不能在靜態域或方法中引用類型變量

public class singleton{
    static T instance;//error
    static T getInstance(){//error
        ...
    }
}

類型擦除后,Singleton類只包含一個instance域變量。

異常不能拋出或捕獲泛型類的實例
實際上,泛型類擴展Throwable也是不合法的。

Class Problem extends Exception{...}//error,can"t extend Throwable

catch子句中不能使用類型變量。

     void dowork(T t) throws T{
        try{
            ...
        }catch(T t){//error
            ...
        }
    }

不過在其中使用類型變量是允許的。

     void dowork(T t) throws T{
        try{
            ...
        }catch(Throwable realCause){//error
            t.initCause(realCause);
            throw t;
        }
    }

注意擦除后的沖突
類型擦除后,無法創建引發沖突的條件。

public class Pair {
    ...
    boolean equals(T value){
        return this.first.equals(value)&&this.second.equals(value);
    }
}

上面代碼類型擦除后boolean equals(T)變成boolean equals(Object),與Object類本身的equals方法發生沖突。所以編譯器會發出警告,equals(T)方法沒有override Object類中的equals(Object).

泛型類型的繼承規則

考慮一個類和一個子類,如Employee和Manager.顯然Pair不是Pair的子類。
注意泛型和數組間的重要區別,可以將一個Manager[]數組賦值給一個類型為Employee[]的變量。

public class Manager extends Employee{
    public static void main(String[] args){
        Manager ceo=new Manager();
        Manager cto=new Manager();
        Manager[] managers=new Manager[]{ceo,cto};
        Employee[] employs=managers;
        System.out.println(employs.length);//2
    }
}

另外,可以參數化類型轉換為原始類型,如Pair是原始類型Pair的一個子類型。

public class Pair {
    T first;
    T second;
    Pair(T first,T second){
        this.first=first;
        this.second=second;
    }
    public T getFirst() {
        return first;
    }
    public void setFirst(T first) {
        this.first = first;
    }
}
public class Manager{
    public static void main(String[] args){
        Manager ceo=new Manager();
        Manager cto=new Manager();
        Pair pair=new Pair<>(ceo,cto);
        Pair pair1=pair;//ok
        pair1.setFirst(new File(""));//類型警告,但是可運行
        Manager manager=(Manager)pair1.getFirst();
        //ClassCastException,java.io.File cannot be cast to com.Manager
        Manager manager1=pair.getFirst();
        //ClassCastException,java.io.File cannot be cast to com.Manager
    }
}

最后,泛型類可以擴展或實現其他泛型類,這和普通類沒什么區別。如ArrayList類實現List接口,這意味著ArrayList可以轉換為List.
但是如前面所見,ArrayList不是一個ArrayList或List

通配符類型

Pair表示類型參數是Employee類的子類.
看下面代碼

    void print(Pair p){
        Employee first=p.getFirst();
        Employee second=p.getSecond();
        ...
    }

正如前面所說,這里不能將Pair傳給方法。解決方法:
void print(Pair p)
類型Pair是Pair的子類型
下面考慮

        Pair manager=new Pair<>();
        Pair pair=manager;//ok
        pair.setFirst(manager);
        //編譯錯誤,The method setFirst(capture#1-of ? extends Employee) in the type 
        //Pair is not applicable for the arguments (Pair)

不過將getFirst方法的返回值賦值給一個Employee引用就不存在問題。

通配符的超類型限定

? super Manager,這個通配符限制類型變量為Manager的所有超類型。
上面代碼如果換成,將會表現為可以為方法通過參數(set),但不能使用返回值(get).
帶有超類型限定的通配符()可以向泛型對象寫入,帶有子類型限定的()可以從泛型對象讀取

無限定通配符

如Pair有方法
? getFirst()
void setFirst(?)
getFirst的返回值只能賦值給一個Object,而setFirst方法不能被調用,甚至用Object做參數也不能。
可以調用setFirst(null)

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64680.html

相關文章

  • &lt;java核心技術&gt;讀書筆記1

    摘要:關鍵字作用調用超類方法調用超類構造器關鍵字作用引用隱式參數如調用該類的其他構造器在覆蓋一個方法時,子類方法可見性不能低于超類方法阻止繼承類和方法目的確保它們不會在子類中改變語義。但是如果將一個類聲明為后面可以改變類變量的值了。 數據類型 整型 int 存儲要求:4byte 取值范圍:-2147483648 -- 2147483647(超過20億) short 存儲要求:2byte 取...

    William_Sang 評論0 收藏0
  • &lt;jdk7學習筆記&gt;讀書筆記-并行api

    摘要:然而,這兩個方法都只是讀取對象狀態,如果只是讀取操作,就可以允許線程并行,這樣讀取效率將會提高。分配線程執行子任務執行子任務獲得子任務進行完成的結果 Lock Lock接口主要操作類是ReentrantLock,可以起到synchronized的作用,另外也提供額外的功能。用Lock重寫上一篇中的死鎖例子 import java.util.concurrent.locks.Lock; ...

    bovenson 評論0 收藏0
  • &lt;&lt;深入PHP面向對象、模式與實踐&gt;&gt;讀書筆記:面向對象設計和過程式編程

    摘要:注本文內容來深入面向對象模式與實踐中節。面向對象設計與過程式編程面向對象設計和過程式編程有什么不同呢可能有些人認為最大的不同在于面向對象編程中包含對象。面向對象編程和過程式編程的一個核心區別是如何分配職責。 注:本文內容來中6.2節。 6.2 面向對象設計與過程式編程 ??面向對象設計和過程式編程有什么不同呢?可能有些人認為最大的不同在于面向對象編程中包含對象。事實上,這種說法不準確。...

    xiao7cn 評論0 收藏0
  • 《HTML與CSS 第一章 認識HTML》讀書筆記

    摘要:一讓廣播明星黯然失色要建立頁面,需要創建用超文本標記語言,編寫的文件,把它們放在一個服務器上二服務器能做什么服務器在互聯網上有一份全天候的工作。一、Web讓廣播明星黯然失色    要建立Web頁面,需要創建用超文本標記語言(HyperText Markup Language,HTML)編寫的文件,把它們放在一個Web服務器上二、Web服務器能做什么?  Web服務器在互聯網上有一份全天候的工...

    番茄西紅柿 評論0 收藏0
  • &lt;javascript高級程序設計&gt;第十二章讀書筆記----偏移量

    摘要:包括元素的高度上下內邊距上下邊框值,如果元素的的值為那么該值為。該值為元素的包含元素。最后,所有這些偏移量都是只讀的,而且每次訪問他們都需要重新計算。為了避免重復計算,可以將計算的值保存起來,以提高性能。 offsetHeight 包括元素的高度、上下內邊距、上下邊框值,如果元素的style.display的值為none,那么該值為0。offsetWidth 包括元素的寬度、左...

    dayday_up 評論0 收藏0

發表評論

0條評論

jimhs

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<