成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

<java核心技術(shù)>讀書(shū)筆記2

jimhs / 3258人閱讀

摘要:如果需要收集參數(shù)化類(lèi)型對(duì)象,只有使用警告這節(jié)討論,向參數(shù)可變的方法傳遞一個(gè)泛型類(lèi)型的實(shí)例。異常不能拋出或捕獲泛型類(lèi)的實(shí)例實(shí)際上,泛型類(lèi)擴(kuò)展也是不合法的。

Object:所有類(lèi)的超類(lèi)

java中每個(gè)類(lèi)都是由它擴(kuò)展而來(lái),但是并不需要這樣寫(xiě):class Employee extends Object.如果沒(méi)有明確指出超類(lèi),Object類(lèi)就被認(rèn)為是這個(gè)的超類(lèi)。
可以使用Object類(lèi)型的變量引用任何類(lèi)型的對(duì)象Object obj=new Employee().
在java中,只有基本類(lèi)型(int,boolean,...)不是對(duì)象,所有的數(shù)組類(lèi)型,不管是對(duì)象數(shù)組還是基本類(lèi)型的數(shù)組都擴(kuò)展自O(shè)bject類(lèi)。

Employee[] staff=new Employee[10];
Object obj=staff;//ok
obj=new int[10];//ok
對(duì)象包裝器與自動(dòng)裝箱

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

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

在算術(shù)表達(dá)式中,也可以自動(dòng)裝箱,自動(dòng)拆箱。

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

==運(yùn)算符用于比較包裝器對(duì)象,只不過(guò)檢測(cè)的是對(duì)象是否指向同一個(gè)存儲(chǔ)區(qū)域。因此,下面比較不會(huì)成立

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

但是如果包裝的值經(jīng)常出現(xiàn),==比較就有可能相等

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

這個(gè)和python類(lèi)似

python并不是對(duì)創(chuàng)建的所有對(duì)象都會(huì)重新申請(qǐng)新的一塊內(nèi)存空間。作為一種優(yōu)化,python會(huì)緩存不變的對(duì)象(如數(shù)值較小的數(shù)字,字符串,元組等)并對(duì)其進(jìn)行復(fù)用。

因此,java設(shè)定了自動(dòng)裝箱規(guī)范

boolean

byte

char<=127

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

被包裝到固定的對(duì)象中。
上面例子a,b是100,第二次賦值時(shí),java不會(huì)重新申請(qǐng)新的一塊內(nèi)存空間,存儲(chǔ)100這個(gè)值。

接口

接口特性

接口不是類(lèi),不能使用new運(yùn)算符實(shí)例化一個(gè)接口

可以聲明接口變量,但必須引用實(shí)現(xiàn)了接口的類(lèi)對(duì)象

可以使用instanceof檢查一個(gè)對(duì)象是否實(shí)現(xiàn)了某個(gè)特定的接口

接口可以繼承接口InterfaceA extends InterfaceB

接口中不能包含實(shí)例變量或靜態(tài)方法,卻可以包含常量

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

常量會(huì)自動(dòng)被設(shè)為public static final

盡管每個(gè)類(lèi)只允許擁有一個(gè)超類(lèi),卻可以實(shí)現(xiàn)多個(gè)接口class Concrete implements InterfaceA,InterfaceB

內(nèi)部類(lèi)

內(nèi)部類(lèi)方法可以訪問(wèn)該類(lèi)所在的作用域中的數(shù)據(jù),包括私有數(shù)據(jù)

內(nèi)部類(lèi)可以對(duì)同一個(gè)包中的其他類(lèi)隱藏起來(lái)

當(dāng)想要定義一個(gè)回調(diào)函數(shù)且不想寫(xiě)大量代碼時(shí),使用匿名內(nèi)部類(lèi)比較方便

泛型 泛型類(lèi)

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

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類(lèi)引入一個(gè)類(lèi)型變量T,用尖括號(hào)(<>)括起來(lái),并放在類(lèi)名的后面。
泛型可以有多個(gè)類(lèi)型變量``

public class Pair {
    ...
}

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

泛型方法

泛型方法可以定義在普通類(lèi)中。

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

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

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

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

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

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

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

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

泛型的局限

大多數(shù)限制都是由類(lèi)型擦除引起的,類(lèi)型擦除可以參見(jiàn)Java泛型:類(lèi)型擦除

不能用基本類(lèi)型實(shí)例化類(lèi)型參數(shù)。
沒(méi)有Pair,只有Pair,因?yàn)轭?lèi)型擦除之后,類(lèi)型參數(shù)變?yōu)镻air,而Object不能存儲(chǔ)double值。

運(yùn)行時(shí)類(lèi)型查詢(xún)只試用于原始類(lèi)型。
虛擬機(jī)中的對(duì)象總有一個(gè)特定的非泛型類(lèi)型,因此所有的類(lèi)型查詢(xún)只產(chǎn)生原始類(lèi)型。

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

同樣的道理,getClass方法總是返回原始類(lèi)型。

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

上面代碼兩次調(diào)用getClass都將返回Pair.class.

不能創(chuàng)建參數(shù)化類(lèi)型的數(shù)組

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

上面代碼的問(wèn)題在于,類(lèi)型擦除后,paris的類(lèi)型是Pair[],可以轉(zhuǎn)換為Object[]

Object[] objarray=pairs;

數(shù)組會(huì)記住它的元素類(lèi)型,如果試圖存儲(chǔ)其他類(lèi)型的元素,就會(huì)拋出Array-StoreException.
只是不允許這樣創(chuàng)建數(shù)組,而聲明類(lèi)型為Pair[]的變量仍然是合法的。不過(guò)不能用new Pair[10]初始化這個(gè)變量。
可以聲明通配類(lèi)型的數(shù)組,然后類(lèi)型轉(zhuǎn)換

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

但這樣類(lèi)型是不安全的。
如果需要收集參數(shù)化類(lèi)型對(duì)象,只有使用ArrayList>.

Varargs警告
這節(jié)討論,向參數(shù)可變的方法傳遞一個(gè)泛型類(lèi)型的實(shí)例。

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

為了調(diào)用addAll方法,java虛擬機(jī)必須建立一個(gè)Pair數(shù)組,這就違反了上一個(gè)泛型局限。
不過(guò),對(duì)于這種情況,規(guī)則有所放松,只會(huì)得到一個(gè)警告,而不是錯(cuò)誤。
有兩種方法抑制這個(gè)警告

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

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

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

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

泛型類(lèi)中靜態(tài)類(lèi)型變量無(wú)效
不能在靜態(tài)域或方法中引用類(lèi)型變量

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

類(lèi)型擦除后,Singleton類(lèi)只包含一個(gè)instance域變量。

異常不能拋出或捕獲泛型類(lèi)的實(shí)例
實(shí)際上,泛型類(lèi)擴(kuò)展Throwable也是不合法的。

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

catch子句中不能使用類(lèi)型變量。

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

不過(guò)在其中使用類(lèi)型變量是允許的。

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

注意擦除后的沖突
類(lèi)型擦除后,無(wú)法創(chuàng)建引發(fā)沖突的條件。

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

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

泛型類(lèi)型的繼承規(guī)則

考慮一個(gè)類(lèi)和一個(gè)子類(lèi),如Employee和Manager.顯然Pair不是Pair的子類(lèi)。
注意泛型和數(shù)組間的重要區(qū)別,可以將一個(gè)Manager[]數(shù)組賦值給一個(gè)類(lèi)型為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
    }
}

另外,可以參數(shù)化類(lèi)型轉(zhuǎn)換為原始類(lèi)型,如Pair是原始類(lèi)型Pair的一個(gè)子類(lèi)型。

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(""));//類(lèi)型警告,但是可運(yùn)行
        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
    }
}

最后,泛型類(lèi)可以擴(kuò)展或?qū)崿F(xiàn)其他泛型類(lèi),這和普通類(lèi)沒(méi)什么區(qū)別。如ArrayList類(lèi)實(shí)現(xiàn)List接口,這意味著ArrayList可以轉(zhuǎn)換為L(zhǎng)ist.
但是如前面所見(jiàn),ArrayList不是一個(gè)ArrayList或List。

通配符類(lèi)型

Pair表示類(lèi)型參數(shù)是Employee類(lèi)的子類(lèi).
看下面代碼

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

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

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

不過(guò)將getFirst方法的返回值賦值給一個(gè)Employee引用就不存在問(wèn)題。

通配符的超類(lèi)型限定

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

無(wú)限定通配符

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64680.html

相關(guān)文章

  • &lt;java核心技術(shù)&gt;讀書(shū)筆記1

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

    William_Sang 評(píng)論0 收藏0
  • &lt;jdk7學(xué)習(xí)筆記&gt;讀書(shū)筆記-并行api

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

    bovenson 評(píng)論0 收藏0
  • &lt;&lt;深入PHP面向?qū)ο蟆⒛J脚c實(shí)踐&gt;&gt;讀書(shū)筆記:面向?qū)ο笤O(shè)計(jì)和過(guò)程式編程

    摘要:注本文內(nèi)容來(lái)深入面向?qū)ο竽J脚c實(shí)踐中節(jié)。面向?qū)ο笤O(shè)計(jì)與過(guò)程式編程面向?qū)ο笤O(shè)計(jì)和過(guò)程式編程有什么不同呢可能有些人認(rèn)為最大的不同在于面向?qū)ο缶幊讨邪瑢?duì)象。面向?qū)ο缶幊毯瓦^(guò)程式編程的一個(gè)核心區(qū)別是如何分配職責(zé)。 注:本文內(nèi)容來(lái)中6.2節(jié)。 6.2 面向?qū)ο笤O(shè)計(jì)與過(guò)程式編程 ??面向?qū)ο笤O(shè)計(jì)和過(guò)程式編程有什么不同呢?可能有些人認(rèn)為最大的不同在于面向?qū)ο缶幊讨邪瑢?duì)象。事實(shí)上,這種說(shuō)法不準(zhǔn)確。...

    xiao7cn 評(píng)論0 收藏0
  • 《HTML與CSS 第一章 認(rèn)識(shí)HTML》讀書(shū)筆記

    摘要:一讓廣播明星黯然失色要建立頁(yè)面,需要?jiǎng)?chuàng)建用超文本標(biāo)記語(yǔ)言,編寫(xiě)的文件,把它們放在一個(gè)服務(wù)器上二服務(wù)器能做什么服務(wù)器在互聯(lián)網(wǎng)上有一份全天候的工作。一、Web讓廣播明星黯然失色    要建立Web頁(yè)面,需要?jiǎng)?chuàng)建用超文本標(biāo)記語(yǔ)言(HyperText Markup Language,HTML)編寫(xiě)的文件,把它們放在一個(gè)Web服務(wù)器上二、Web服務(wù)器能做什么?  Web服務(wù)器在互聯(lián)網(wǎng)上有一份全天候的工...

    番茄西紅柿 評(píng)論0 收藏0
  • &lt;javascript高級(jí)程序設(shè)計(jì)&gt;第十二章讀書(shū)筆記----偏移量

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

    dayday_up 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

jimhs

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<