国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
1、==
2、equals()方法詳解
3、hashcode()淺談
2. int、char、long 各占多少字節(jié)數(shù)
3. int和Integer的區(qū)別
4. java多態(tài)的理解
1.多態(tài)概述
2.多態(tài)中成員的特點
3.instanceof關(guān)鍵字
4.多態(tài)的轉(zhuǎn)型
5.多態(tài)案例:
5. String、StringBuffer和StringBuilder區(qū)別
1、長度是否可變
2、執(zhí)行效率
2、應(yīng)用場景
1、是否線程安全
6. 什么是內(nèi)部類?內(nèi)部類的作用
內(nèi)部類的定義
內(nèi)部類的作用:
7. 抽象類和接口的區(qū)別
8. 抽象類的意義
9. 抽象類與接口的應(yīng)用場景
1.接口(interface)的應(yīng)用場合:
2.抽象類(abstract.class)的應(yīng)用場合:
10. ?抽象類是否可以沒有方法和屬性?
11. 接口的意義
12. Java泛型中的extends和super理解
13. 父類的靜態(tài)方法能否被子類重寫
14. 線程和進(jìn)程的區(qū)別
15. final,finally,finalize的區(qū)別
16. 序列化Serializable和Parcelable的區(qū)別
17. 靜態(tài)屬性和靜態(tài)方法是否可以被繼承?是否可以被重寫?以及原因?
18 .java中靜態(tài)內(nèi)部類的設(shè)計意圖
內(nèi)部類
靜態(tài)內(nèi)部類
首頁 Java Java面試題 2020全新java基礎(chǔ)面試題匯總

2020全新java基礎(chǔ)面試題匯總

Oct 21, 2020 pm 04:51 PM
java 面試題

2020全新java基礎(chǔ)面試題匯總

java中==和equals和hashCode的區(qū)別

(更多面試題推薦:java面試題及答案

1、==

java中的數(shù)據(jù)類型,可分為兩類:

  1. 基本數(shù)據(jù)類型,也稱原始數(shù)據(jù)類型 byte,short,char,int,long,float,double,boolean ?他們之間的比較,應(yīng)用雙等號(==),比較的是他們的值。

  2. 引用類型(類、接口、數(shù)組) 當(dāng)他們用(==)進(jìn)行比較的時候,比較的是他們在內(nèi)存中的存放地址,所以,除非是同一個new出來的對象,他們的比較后的結(jié)果為true,否則比較后結(jié)果為false。對象是放在堆中的,棧中存放的是對象的引用(地址)。先看下虛擬機內(nèi)存圖和代碼:

public?class?testDay?{
????public?static?void?main(String[]?args)?{
????????String?s1?=?new?String("11");
????????String?s2?=?new?String("11");
????????System.out.println(s1?==?s2);
????????System.out.println(s1.equals(s2));
????}
}

結(jié)果是:

false
true

blockchain

s1和s2都分別存儲的是相應(yīng)對象的地址。所以如果用 s1== s2時,比較的是兩個對象的地址值(即比較引用是否相同),為false。而調(diào)用equals方向的時候比較的是相應(yīng)地址里面的值,所以值為true。這里就需要詳細(xì)描述下equals()了。

2、equals()方法詳解

equals()方法是用來判斷其他的對象是否和該對象相等。其再Object里面就有定義,所以任何一個對象都有equals()方法。區(qū)別在于是否重寫了該方法。

先看下源碼:

public?boolean?equals(Object?obj)?{????return?(this?==?obj);
}

很明顯Object定義的是對兩個對象的地址值進(jìn)行的比較(即比較引用是否相同)。但是為什么String里面調(diào)用equals()卻是比較的不是地址而是堆內(nèi)存地址里面的值呢。這里就是個重點了,像String 、Math、Integer、Double等這些封裝類在使用equals()方法時,已經(jīng)覆蓋了object類的equals()方法??聪耂tring里面重寫的equals():

public?boolean?equals(Object?anObject)?{????if?(this?==?anObject)?{????????return?true;
????}????if?(anObject?instanceof?String)?{
????????String?anotherString?=?(String)anObject;
????????int?n?=?value.length;????????if?(n?==?anotherString.value.length)?{
????????????char?v1[]?=?value;
????????????char?v2[]?=?anotherString.value;
????????????int?i?=?0;????????????while?(n--?!=?0)?{????????????????if?(v1[i]?!=?v2[i])????????????????????return?false;
????????????????i++;
????????????}????????????return?true;
????????}
????}????return?false;
}

重寫了之后就是這是進(jìn)行的內(nèi)容比較,而已經(jīng)不再是之前地址的比較。依次類推Math、Integer、Double等這些類都是重寫了equals()方法的,從而進(jìn)行的是內(nèi)容的比較。當(dāng)然,基本類型是進(jìn)行值的比較。

需要注意的是當(dāng)equals()方法被override時,hashCode()也要被override。按照一般hashCode()方法的實現(xiàn)來說,相等的對象,它們的hashcode一定相等。為什么會這樣,這里又要簡單提一下hashcode了。

3、hashcode()淺談

明明是java中==和equals和hashCode的區(qū)別問題,怎么一下子又扯到hashcode()上面去了。你肯定很郁悶,好了,我打個簡單的例子你就知道為什么==或者equals的時候會涉及到hashCode。

舉例說明下:如果你想查找一個集合中是否包含某個對象,那么程序應(yīng)該怎么寫呢?不要用indexOf方法的話,就是從集合中去遍歷然后比較是否想到。萬一集合中有10000個元素呢,累屎了是吧。所以為了提高效率,哈希算法也就產(chǎn)生了。核心思想就是將集合分成若干個存儲區(qū)域(可以看成一個個桶),每個對象可以計算出一個哈希碼,可以根據(jù)哈希碼分組,每組分別對應(yīng)某個存儲區(qū)域,這樣一個對象根據(jù)它的哈希碼就可以分到不同的存儲區(qū)域(不同的區(qū)域)。

所以再比較元素的時候,實際上是先比較hashcode,如果相等了之后才去比較equal方法。

看下hashcode圖解:

2020全新java基礎(chǔ)面試題匯總

一個對象一般有key和value,可以根據(jù)key來計算它的hashCode值,再根據(jù)其hashCode值存儲在不同的存儲區(qū)域中,如上圖。不同區(qū)域能存儲多個值是因為會涉及到hash沖突的問題。簡單如果兩個不同對象的hashCode相同,這種現(xiàn)象稱為hash沖突。簡單來說就是hashCode相同但是equals不同的值。對于比較10000個元素就不需要遍歷整個集合了,只需要計算要查找對象的key的hashCode,然后找到該hashCode對應(yīng)的存儲區(qū)域查找就over了。

2020全新java基礎(chǔ)面試題匯總

大概可以知道,先通過hashcode來比較,如果hashcode相等,那么就用equals方法來比較兩個對象是否相等。再重寫了equals最好把hashCode也重寫。其實這是一條規(guī)范,如果不這樣做程序也可以執(zhí)行,只不過會隱藏bug。一般一個類的對象如果會存儲在HashTable,HashSet,HashMap等散列存儲結(jié)構(gòu)中,那么重寫equals后最好也重寫hashCode。

總結(jié):

  1. hashCode是為了提高在散列結(jié)構(gòu)存儲中查找的效率,在線性表中沒有作用。
  2. equals重寫的時候hashCode也跟著重寫
  3. 兩對象equals如果相等那么hashCode也一定相等,反之不一定。

2. int、char、long 各占多少字節(jié)數(shù)

byte 是 字節(jié)

bit 是 位

1 byte = 8 bit

char在java中是2個字節(jié),java采用unicode,2個字節(jié)來表示一個字符

short 2個字節(jié)

int 4個字節(jié)

long 8個字節(jié)

float 4個字節(jié)

double 8個字節(jié)

3. int和Integer的區(qū)別

  1. Integer是int的包裝類,int則是java的一種基本數(shù)據(jù)類型
  2. Integer變量必須實例化后才能使用,而int變量不需要
  3. Integer實際是對象的引用,當(dāng)new一個Integer時,實際上是生成一個指針指向此對象;而int則是直接存儲數(shù)據(jù)值
  4. Integer的默認(rèn)值是null,int的默認(rèn)值是0

延伸: 關(guān)于Integer和int的比較

  1. 由于Integer變量實際上是對一個Integer對象的引用,所以兩個通過new生成的Integer變量永遠(yuǎn)是不相等的(因為new生成的是兩個對象,其內(nèi)存地址不同)。
Integer?i?=?new?Integer(100);
Integer?j?=?new?Integer(100);
System.out.print(i?==?j);?//false
  1. Integer變量和int變量比較時,只要兩個變量的值是向等的,則結(jié)果為true(因為包裝類Integer和基本數(shù)據(jù)類型int比較時,java會自動拆包裝為int,然后進(jìn)行比較,實際上就變?yōu)閮蓚€int變量的比較)
Integer?i?=?new?Integer(100);
int?j?=?100;
System.out.print(i?==?j);?//true
  1. 非new生成的Integer變量和new Integer()生成的變量比較時,結(jié)果為false。(因為非new生成的Integer變量指向的是java常量池中的對象,而new Integer()生成的變量指向堆中新建的對象,兩者在內(nèi)存中的地址不同)
Integer?i?=?new?Integer(100);
Integer?j?=?100;
System.out.print(i?==?j);?//false
  1. 對于兩個非new生成的Integer對象,進(jìn)行比較時,如果兩個變量的值在區(qū)間-128到127之間,則比較結(jié)果為true,如果兩個變量的值不在此區(qū)間,則比較結(jié)果為false
Integer?i?=?100;
Integer?j?=?100;
System.out.print(i?==?j);?//true
Integer?i?=?128;
Integer?j?=?128;
System.out.print(i?==?j);?//false

對于第4條的原因: java在編譯Integer i = 100 ;時,會翻譯成為Integer i = Integer.valueOf(100);,而java API中對Integer類型的valueOf的定義如下:

public?static?Integer?valueOf(int?i){
????assert?IntegerCache.high?>=?127;????if?(i?>=?IntegerCache.low?&&?i?<= IntegerCache.high){        return IntegerCache.cache[i + (-IntegerCache.low)];
    }    return new Integer(i);
}

java對于-128到127之間的數(shù),會進(jìn)行緩存,Integer i = 127時,會將127進(jìn)行緩存,下次再寫Integer j = 127時,就會直接從緩存中取,就不會new了

4. java多態(tài)的理解

1.多態(tài)概述

  1. 多態(tài)是繼封裝、繼承之后,面向?qū)ο蟮牡谌筇匦浴?/p>

  2. 多態(tài)現(xiàn)實意義理解:

  • 現(xiàn)實事物經(jīng)常會體現(xiàn)出多種形態(tài),如學(xué)生,學(xué)生是人的一種,則一個具體的同學(xué)張三既是學(xué)生也是人,即出現(xiàn)兩種形態(tài)。

  • Java作為面向?qū)ο蟮恼Z言,同樣可以描述一個事物的多種形態(tài)。如Student類繼承了Person類,一個Student的對象便既是Student,又是Person。

  1. 多態(tài)體現(xiàn)為父類引用變量可以指向子類對象。

  2. 前提條件:必須有子父類關(guān)系。

注意:在使用多態(tài)后的父類引用變量調(diào)用方法時,會調(diào)用子類重寫后的方法。

  1. 多態(tài)的定義與使用格式

定義格式:父類類型 變量名=new 子類類型();

2.多態(tài)中成員的特點

  1. 多態(tài)成員變量:編譯運行看左邊

Fu f=new Zi();

System.out.println(f.num);//f是Fu中的值,只能取到父中的值

  1. 多態(tài)成員方法:編譯看左邊,運行看右邊

Fu f1=new Zi();

System.out.println(f1.show());//f1的門面類型是Fu,但實際類型是Zi,所以調(diào)用的是重寫后的方法。

3.instanceof關(guān)鍵字

作用:用來判斷某個對象是否屬于某種數(shù)據(jù)類型。

* 注意: 返回類型為布爾類型

使用案例:

Fu f1=new Zi();
Fu f2=new Son();if(f1 instanceof Zi){
    System.out.println("f1是Zi的類型");
}else{
    System.out.println("f1是Son的類型");
}

4.多態(tài)的轉(zhuǎn)型

多態(tài)的轉(zhuǎn)型分為向上轉(zhuǎn)型和向下轉(zhuǎn)型兩種

  • 向上轉(zhuǎn)型:多態(tài)本身就是向上轉(zhuǎn)型過的過程

    • 使用格式:父類類型 變量名=new 子類類型();

    • 適用場景:當(dāng)不需要面對子類類型時,通過提高擴展性,或者使用父類的功能就能完成相應(yīng)的操作。

  • 向下轉(zhuǎn)型:一個已經(jīng)向上轉(zhuǎn)型的子類對象可以使用強制類型轉(zhuǎn)換的格式,將父類引用類型轉(zhuǎn)為子類引用各類型

    • 使用格式:子類類型 變量名=(子類類型)父類類型的變量;

    • 適用場景:當(dāng)要使用子類特有功能時。

5.多態(tài)案例:

例1:

package day0524;
 
public class demo04 {
    public static void main(String[] args) {
        People p=new Stu();
        p.eat();
        //調(diào)用特有的方法
        Stu s=(Stu)p;
        s.study();
        //((Stu) p).study();
    }
}
class People{
    public void eat(){
        System.out.println("吃飯");
    }
}
class Stu extends People{
    @Override
    public void eat(){
        System.out.println("吃水煮肉片");
    }
    public void study(){
        System.out.println("好好學(xué)習(xí)");
    }
}
class Teachers extends People{
    @Override
    public void eat(){
        System.out.println("吃櫻桃");
    }
    public void teach(){
        System.out.println("認(rèn)真授課");
    }
}

答案:吃水煮肉片 好好學(xué)習(xí)

例2:

請問題目運行結(jié)果是什么?

package day0524;
public class demo1 {
    public static void main(String[] args) {
        A a=new A();
        a.show();
        B b=new B();
        b.show();
    }
}
class A{
    public void show(){
        show2();
    }
    public void show2(){
        System.out.println("A");
    }
}
class B extends A{
    public void show2(){
        System.out.println("B");
    }
}
class C extends B{
    public void show(){
        super.show();
    }
    public void show2(){
        System.out.println("C");
    }
}

答案:A B

5. String、StringBuffer和StringBuilder區(qū)別

1、長度是否可變

  • String 是被 final 修飾的,他的長度是不可變的,就算調(diào)用 String 的concat 方法,那也是把字符串拼接起來并重新創(chuàng)建一個對象,把拼接后的 String 的值賦給新創(chuàng)建的對象
  • StringBuffer 和 StringBuilder 類的對象能夠被多次的修改,并且不產(chǎn)生新的未使用對象,StringBuffer 與 StringBuilder 中的方法和功能完全是等價的。調(diào)用StringBuffer 的 append 方法,來改變 StringBuffer 的長度,并且,相比較于 StringBuffer,String 一旦發(fā)生長度變化,是非常耗費內(nèi)存的!

2、執(zhí)行效率

  • 三者在執(zhí)行速度方面的比較:StringBuilder > StringBuffer > String

    3、應(yīng)用場景

    • 如果要操作少量的數(shù)據(jù)用 = String
    • 單線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuilder
    • 多線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuffer

    StringBuffer和StringBuilder區(qū)別

    1、是否線程安全

    • StringBuilder 類在 Java 5 中被提出,它和 StringBuffer 之間的最大不同在于 StringBuilder 的方法不是線程安全的(不能同步訪問),StringBuffer是線程安全的。只是StringBuffer 中的方法大都采用了 synchronized 關(guān)鍵字進(jìn)行修飾,因此是線程安全的,而 StringBuilder 沒有這個修飾,可以被認(rèn)為是線程不安全的。

    2、應(yīng)用場景

    • 由于 StringBuilder 相較于 StringBuffer 有速度優(yōu)勢,所以多數(shù)情況下建議使用 StringBuilder 類。
    • 然而在應(yīng)用程序要求線程安全的情況下,則必須使用 StringBuffer 類。 append方法與直接使用+串聯(lián)相比,減少常量池的浪費。

    6. 什么是內(nèi)部類?內(nèi)部類的作用

    內(nèi)部類的定義

    將一個類定義在另一個類里面或者一個方法里面,這樣的類稱為內(nèi)部類。

    內(nèi)部類的作用:

    1. 成員內(nèi)部類 成員內(nèi)部類可以無條件訪問外部類的所有成員屬性和成員方法(包括private成員和靜態(tài)成員)。 當(dāng)成員內(nèi)部類擁有和外部類同名的成員變量或者方法時,會發(fā)生隱藏現(xiàn)象,即默認(rèn)情況下訪問的是成員內(nèi)部類的成員。

    2. 局部內(nèi)部類 局部內(nèi)部類是定義在一個方法或者一個作用域里面的類,它和成員內(nèi)部類的區(qū)別在于局部內(nèi)部類的訪問僅限于方法內(nèi)或者該作用域內(nèi)。

    3. 匿名內(nèi)部類 匿名內(nèi)部類就是沒有名字的內(nèi)部類

    4. 靜態(tài)內(nèi)部類 指被聲明為static的內(nèi)部類,他可以不依賴內(nèi)部類而實例,而通常的內(nèi)部類需要實例化外部類,從而實例化。靜態(tài)內(nèi)部類不可以有與外部類有相同的類名。不能訪問外部類的普通成員變量,但是可以訪問靜態(tài)成員變量和靜態(tài)方法(包括私有類型) 一個 靜態(tài)內(nèi)部類去掉static 就是成員內(nèi)部類,他可以自由的引用外部類的屬性和方法,無論是靜態(tài)還是非靜態(tài)。但是不可以有靜態(tài)屬性和方法

    (學(xué)習(xí)視頻推薦:java課程

    7. 抽象類和接口的區(qū)別

    1. 抽象類要被子類繼承,接口要被類實現(xiàn)。
      2020全新java基礎(chǔ)面試題匯總
    2. 接口只能做方法聲明,抽象類中可以作方法聲明,也可以做方法實現(xiàn)。
      2020全新java基礎(chǔ)面試題匯總
    3. 接口里定義的變量只能是公共的靜態(tài)的常量,抽象類中的變量是普通變量。
      2020全新java基礎(chǔ)面試題匯總
    4. 接口是設(shè)計的結(jié)果,抽象類是重構(gòu)的結(jié)果。
      2020全新java基礎(chǔ)面試題匯總
    5. 抽象類和接口都是用來抽象具體對象的,但是接口的抽象級別最高。
      2020全新java基礎(chǔ)面試題匯總
    6. 抽象類可以有具體的方法和屬性,接口只能有抽象方法和不可變常量。
      2020全新java基礎(chǔ)面試題匯總
    7. 抽象類主要用來抽象類別,接口主要用來抽象功能。
      2020全新java基礎(chǔ)面試題匯總

    8. 抽象類的意義

    抽象類: 一個類中如果包含抽象方法,這個類應(yīng)該用abstract關(guān)鍵字聲明為抽象類。

    意義:

    1. 為子類提供一個公共的類型;
    2. 封裝子類中重復(fù)內(nèi)容(成員變量和方法);
    3. 定義有抽象方法,子類雖然有不同的實現(xiàn),但該方法的定義是一致的。

    9. 抽象類與接口的應(yīng)用場景

    1.接口(interface)的應(yīng)用場合:

    1. 類與類之間需要特定的接口進(jìn)行協(xié)調(diào),而不在乎其如何實現(xiàn)。
    2. 作為能夠?qū)崿F(xiàn)特定功能的標(biāo)識存在,也可以是什么接口方法都沒有的純粹標(biāo)識。
    3. 需要將一組類視為單一的類,而調(diào)用者只通過接口來與這組類發(fā)生聯(lián)系。
    4. 需要實現(xiàn)特定的多項功能,而這些功能之間可能完全沒有任何聯(lián)系。

    2.抽象類(abstract.class)的應(yīng)用場合:

    一句話,在既需要統(tǒng)一的接口,又需要實例變量或缺省的方法的情況下,就可以使用它。最常見的有:

    1. 定義了一組接口,但又不想強迫每個實現(xiàn)類都必須實現(xiàn)所有的接口??梢杂胊bstract.class定義一組方法體,甚至可以是空方法體,然后由子類選擇自己所感興趣的方法來覆蓋。
    2. 某些場合下,只靠純粹的接口不能滿足類與類之間的協(xié)調(diào),還必需類中表示狀態(tài)的變量來區(qū)別不同的關(guān)系。abstract的中介作用可以很好地滿足這一點。
    3. 規(guī)范了一組相互協(xié)調(diào)的方法,其中一些方法是共同的,與狀態(tài)無關(guān)的,可以共享的,無需子類分別實現(xiàn);而另一些方法卻需要各個子類根據(jù)自己特定的狀態(tài)來實現(xiàn)特定的功能

    10. ?抽象類是否可以沒有方法和屬性?

    答案是:可以

    抽象類中可以沒有抽象方法,但有抽象方法的一定是抽象類。所以,java中 抽象類里面可以沒有抽象方法。注意即使是沒有抽象方法和屬性的抽象類,也不能被實例化。

    11. 接口的意義

    1. 定義接口的重要性:在Java編程,abstract class 和interface是支持抽象類定義的兩種機制。正是由于這兩種機制的存在,才使得Java成為面向?qū)ο蟮木幊陶Z言。
    2. 定義接口有利于代碼的規(guī)范:對于一個大型項目而言,架構(gòu)師往往會對一些主要的接口來進(jìn)行定義,或者清理一些沒有必要的接口。這樣做的目的一方面是為了給開發(fā)人員一個清晰的指示,告訴他們哪些業(yè)務(wù)需要實現(xiàn);同時也能防止由于開發(fā)人員隨意命名而導(dǎo)致的命名不清晰和代碼混亂,影響開發(fā)效率。
    3. 有利于對代碼進(jìn)行維護(hù):比如你要做一個畫板程序,其中里面有一個面板類,主要負(fù)責(zé)繪畫功能,然后你就這樣定義了這個類??墒窃诓痪脤恚阃蝗话l(fā)現(xiàn)現(xiàn)有的類已經(jīng)不能夠滿足需要,然后你又要重新設(shè)計這個類,更糟糕是你可能要放棄這個類,那么其他地方可能有引用他,這樣修改起來很麻煩。如果你一開始定義一個接口,把繪制功能放在接口里,然后定義類時實現(xiàn)這個接口,然后你只要用這個接口去引用實現(xiàn)它的類就行了,以后要換的話只不過是引用另一個類而已,這樣就達(dá)到維護(hù)、拓展的方便性。
    4. 保證代碼的安全和嚴(yán)密:一個好的程序一定符合高內(nèi)聚低耦合的特征,那么實現(xiàn)低耦合,定義接口是一個很好的方法,能夠讓系統(tǒng)的功能較好地實現(xiàn),而不涉及任何具體的實現(xiàn)細(xì)節(jié)。這樣就比較安全、嚴(yán)密一些,這一思想一般在軟件開發(fā)中較為常見。

    12. Java泛型中的extends和super理解

    在平時看源碼的時候我們經(jīng)??吹椒盒?,且經(jīng)常會看到extends和super的使用,看過其他的文章里也有講到上界通配符和下屆通配符,總感覺講的不夠明白。這里備注一下,以免忘記。

    1. extends也成為上界通配符,就是指定上邊界。即泛型中的類必須為當(dāng)前類的子類或當(dāng)前類。
    2. super也稱為下屆通配符,就是指定下邊界。即泛型中的類必須為當(dāng)前類或者其父類。

    這兩點不難理解,extends修飾的只能取,不能放,這是為什么呢? 先看一個列子:

    public?class?Food?{}
    public?class?Fruit?extends?Food?{}
    public?class?Apple?extends?Fruit?{}
    public?class?Banana?extends?Fruit{}
    
    public?class?GenericTest?{
    
    ????public?void?testExtends(List<? extends Fruit>?list){
    
    ????????//報錯,extends為上界通配符,只能取值,不能放.
    ????????//因為Fruit的子類不只有Apple還有Banana,這里不能確定具體的泛型到底是Apple還是Banana,所以放入任何一種類型都會報錯
    ????????//list.add(new?Apple());
    
    ????????//可以正常獲取
    ????????Fruit?fruit?=?list.get(1);
    ????}
    
    ????public?void?testSuper(List<? super Fruit>?list){
    
    ????????//super為下界通配符,可以存放元素,但是也只能存放當(dāng)前類或者子類的實例,以當(dāng)前的例子來講,
    ????????//無法確定Fruit的父類是否只有Food一個(Object是超級父類)
    ????????//因此放入Food的實例編譯不通過
    ????????list.add(new?Apple());
    //????????list.add(new?Food());
    
    ????????Object?object?=?list.get(1);
    ????}
    }

    在testExtends方法中,因為泛型中用的是extends,在向list中存放元素的時候,我們并不能確定List中的元素的具體類型,即可能是Apple也可能是Banana。因此調(diào)用add方法時,不論傳入new Apple()還是new Banana(),都會出現(xiàn)編譯錯誤。

    理解了extends之后,再看super就很容易理解了,即我們不能確定testSuper方法的參數(shù)中的泛型是Fruit的哪個父類,因此在調(diào)用get方法時只能返回Object類型。結(jié)合extends可見,在獲取泛型元素時,使用extends獲取到的是泛型中的上邊界的類型(本例子中為Fruit),范圍更小。

    總結(jié):在使用泛型時,存取元素時用super,獲取元素時,用extends。

    13. 父類的靜態(tài)方法能否被子類重寫

    不能,父類的靜態(tài)方法能夠被子類繼承,但是不能夠被子類重寫,即使子類中的靜態(tài)方法與父類中的靜態(tài)方法完全一樣,也是兩個完全不同的方法。

    class?Fruit{
    
    ????static?String?color?=?"五顏六色";
    ????static?public?void?call()?{
    ????????System.out.println("這是一個水果");
    ????}
    }
    
    public?class?Banana?extends?Fruit{
    
    ????static?String?color?=?"黃色";
    ????static?public?void?call()?{
    ????????System.out.println("這是一個香蕉");
    ????}
    
    ????public?static?void?main(String[]?args)?{
    
    ????????Fruit?fruit?=?new?Banana();
    ????????System.out.println(fruit.color);????//五顏六色
    ????????fruit.call();?????????//這是一個水果
    ????}
    }

    如代碼所示,如果能夠被重寫,則輸出的應(yīng)該是這是一個香蕉。與此類似的是,靜態(tài)變量也不能夠被重寫。如果想要調(diào)用父類的靜態(tài)方法,應(yīng)該使用類來調(diào)用。 那為什么會出現(xiàn)這種情況呢? 我們要從重寫的定義來說:

    重寫指的是根據(jù)運行時對象的類型來決定調(diào)用哪個方法,而不是根據(jù)編譯時的類型。

    對于靜態(tài)方法和靜態(tài)變量來說,雖然在上述代碼中使用對象來進(jìn)行調(diào)用,但是底層上還是使用父類來調(diào)用的,靜態(tài)變量和靜態(tài)方法在編譯的時候就將其與類綁定在一起。既然它們在編譯的時候就決定了調(diào)用的方法、變量,那就和重寫沒有關(guān)系了。

    靜態(tài)屬性和靜態(tài)方法是否可以被繼承

    可以被繼承,如果子類中有相同的靜態(tài)方法和靜態(tài)變量,那么父類的方法以及變量就會被覆蓋。要想調(diào)用就就必須使用父類來調(diào)用。

    class?Fruit{
    
    ????static?String?color?=?"五顏六色";
    ????static?String?xingzhuang?=?"奇形怪狀";
    ????static?public?void?call()?{
    ????????System.out.println("這是一個水果");
    ????}
    ????static?public?void?test()?{
    ????????System.out.println("這是沒有被子類覆蓋的方法");
    ????}
    }
    
    public?class?Banana?extends?Fruit{
    
    ????static?String?color?=?"黃色";
    ????static?public?void?call()?{
    ????????System.out.println("這是一個香蕉");
    ????}
    
    ????public?static?void?main(String[]?args)?{
    
    ????????Banana?banana?=?new?Banana();????
    ????????banana.test();?????//這是沒有被子類覆蓋的方法
    ????????banana.call();?????//調(diào)用Banana類中的call方法????這是一個香蕉
    ????????Fruit.call();?????????//調(diào)用Fruit類中的方法?這是一個水果
    
    ????????System.out.println(banana.xingzhuang?+?"?"?+?banana.color);???//奇形怪狀?黃色
    ????}
    }

    從上述代碼可以看出,子類中覆蓋了父類的靜態(tài)方法的話,調(diào)用的是子類的方法,這個時候要是還想調(diào)用父類的靜態(tài)方法,應(yīng)該是用父類直接調(diào)用。如果子類沒有覆蓋,則調(diào)用的是父類的方法。靜態(tài)變量與此相似。

    14. 線程和進(jìn)程的區(qū)別

    • 定義方面:進(jìn)程是程序在某個數(shù)據(jù)集合上的一次運行活動;線程是進(jìn)程中的一個執(zhí)行路徑。(進(jìn)程可以創(chuàng)建多個線程)
    • 角色方面:在支持線程機制的系統(tǒng)中,進(jìn)程是系統(tǒng)資源分配的單位,線程是CPU調(diào)度的單位。
    • 資源共享方面:進(jìn)程之間不能共享資源,而線程共享所在進(jìn)程的地址空間和其它資源。同時線程還有自己的棧和棧指針,程序計數(shù)器等寄存器。
    • 獨立性方面:進(jìn)程有自己獨立的地址空間,而線程沒有,線程必須依賴于進(jìn)程而存在。
    • 開銷方面。進(jìn)程切換的開銷較大。線程相對較小。(前面也提到過,引入線程也出于了開銷的考慮。)

    可看下這篇文章:juejin.im/post/684490…

    15. final,finally,finalize的區(qū)別

    • final 用于聲明屬性,方法和類, 分別表示屬性不可變, 方法不可覆蓋, 類不可繼承.
    • finally 是異常處理語句結(jié)構(gòu)的一部分,表示總是執(zhí)行.
    • finalize 是Object類的一個方法,在垃圾收集器執(zhí)行的時候會調(diào)用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關(guān)閉文件等.

    16. 序列化Serializable和Parcelable的區(qū)別

    Android中Intent如果要傳遞類對象,可以通過兩種方式實現(xiàn)。

    方式一:Serializable,要傳遞的類實現(xiàn)Serializable接口傳遞對象, 方式二:Parcelable,要傳遞的類實現(xiàn)Parcelable接口傳遞對象。

    Serializable(Java自帶):Serializable是序列化的意思,表示將一個對象轉(zhuǎn)換成可存儲或可傳輸?shù)臓顟B(tài)。序列化后的對象可以在網(wǎng)絡(luò)上進(jìn)行傳輸,也可以存儲到本地。Serializable是一種標(biāo)記接口,這意味著無需實現(xiàn)方法,Java便會對這個對象進(jìn)行高效的序列化操作。

    Parcelable(Android 專用):Android的Parcelable的設(shè)計初衷是因為Serializable效率過慢(使用反射),為了在程序內(nèi)不同組件間以及不同Android程序間(AIDL)高效的傳輸數(shù)據(jù)而設(shè)計,這些數(shù)據(jù)僅在內(nèi)存中存在。Parcelable方式的實現(xiàn)原理是將一個完整的對象進(jìn)行分解,而分解后的每一部分都是Intent所支持的數(shù)據(jù)類型,這樣也就實現(xiàn)傳遞對象的功能了。

    效率及選擇:

    Parcelable的性能比Serializable好,因為后者在反射過程頻繁GC,所以在內(nèi)存間數(shù)據(jù)傳輸時推薦使用Parcelable,如activity間傳輸數(shù)據(jù)。而Serializable可將數(shù)據(jù)持久化方便保存,所以在需要保存或網(wǎng)絡(luò)傳輸數(shù)據(jù)時選擇Serializable,因為android不同版本Parcelable可能不同,所以不推薦使用Parcelable進(jìn)行數(shù)據(jù)持久化。 Parcelable不能使用在要將數(shù)據(jù)存儲在磁盤上的情況,因為Parcelable不能很好的保證數(shù)據(jù)的持續(xù)性在外界有變化的情況下。盡管Serializable效率低點,但此時還是建議使用Serializable 。

    通過intent傳遞復(fù)雜數(shù)據(jù)類型時必須先實現(xiàn)兩個接口之一,對應(yīng)方法分別是getSerializableExtra(),getParcelableExtra()。

    17. 靜態(tài)屬性和靜態(tài)方法是否可以被繼承?是否可以被重寫?以及原因?

    父類的靜態(tài)屬性和方法可以被子類繼承

    不可以被子類重寫:當(dāng)父類的引用指向子類時,使用對象調(diào)用靜態(tài)方法或者靜態(tài)變量,是調(diào)用的父類中的方法或者變量。并沒有被子類改寫。

    原因:

    因為靜態(tài)方法從程序開始運行后就已經(jīng)分配了內(nèi)存,也就是說已經(jīng)寫死了。所有引用到該方法的對象(父類的對象也好子類的對象也好)所指向的都是同一塊內(nèi)存中的數(shù)據(jù),也就是該靜態(tài)方法。

    子類中如果定義了相同名稱的靜態(tài)方法,并不會重寫,而應(yīng)該是在內(nèi)存中又分配了一塊給子類的靜態(tài)方法,沒有重寫這一說。

    18 .java中靜態(tài)內(nèi)部類的設(shè)計意圖

    內(nèi)部類

    內(nèi)部類,即定義在一個類的內(nèi)部的類。為什么有內(nèi)部類呢?

    我們知道,在java中類是單繼承的,一個類只能繼承另一個具體類或抽象類(可以實現(xiàn)多個接口)。這種設(shè)計的目的是因為在多繼承中,當(dāng)多個父類中有重復(fù)的屬性或者方法時,子類的調(diào)用結(jié)果會含糊不清,因此用了單繼承。

    而使用內(nèi)部類的原因是:每個內(nèi)部類都能獨立地繼承一個(接口的)實現(xiàn),所以無論外圍類是否已經(jīng)繼承了某個(接口的)實現(xiàn),對于內(nèi)部類都沒有影響。

    在我們程序設(shè)計中有時候會存在一些使用接口很難解決的問題,這個時候我們可以利用內(nèi)部類提供的、可以繼承多個具體的或者抽象的類的能力來解決這些程序設(shè)計問題。可以這樣說,接口只是解決了部分問題,而內(nèi)部類使得多重繼承的解決方案變得更加完整。

    靜態(tài)內(nèi)部類

    說靜態(tài)內(nèi)部類之前,先了解下成員內(nèi)部類(非靜態(tài)的內(nèi)部類)。

    成員內(nèi)部類

    成員內(nèi)部類也是最普通的內(nèi)部類,它是外圍類的一個成員,所以它可以無限制的訪問外圍類的所有成員屬性和方法,盡管是private的,但是外圍類要訪問內(nèi)部類的成員屬性和方法則需要通過內(nèi)部類實例來訪問。

    在成員內(nèi)部類中要注意兩點:

    • 成員內(nèi)部類中不能存在任何static的變量和方法;

    • 成員內(nèi)部類是依附于外圍類的,所以只有先創(chuàng)建了外圍類才能夠創(chuàng)建內(nèi)部類。

    靜態(tài)內(nèi)部類

    靜態(tài)內(nèi)部類與非靜態(tài)內(nèi)部類之間存在一個最大的區(qū)別:非靜態(tài)內(nèi)部類在編譯完成之后會隱含地保存著一個引用,該引用是指向創(chuàng)建它的外圍內(nèi),但是靜態(tài)內(nèi)部類卻沒有。

    沒有這個引用就意味著:

    • 它的創(chuàng)建是不需要依賴于外圍類的。

    • 它不能使用任何外圍類的非static成員變量和方法。

    其它兩種內(nèi)部類:局部內(nèi)部類和匿名內(nèi)部類

    局部內(nèi)部類

    局部內(nèi)部類是嵌套在方法和作用域內(nèi)的,對于這個類的使用主要是應(yīng)用與解決比較復(fù)雜的問題,想創(chuàng)建一個類來輔助我們的解決方案,到那時又不希望這個類是公共可用的,所以就產(chǎn)生了局部內(nèi)部類,局部內(nèi)部類和成員內(nèi)部類一樣被編譯,只是它的作用域發(fā)生了改變,它只能在該方法和屬性中被使用,出了該方法和屬性就會失效。

    匿名內(nèi)部類

    1. 匿名內(nèi)部類是沒有訪問修飾符的。

    2. new 匿名內(nèi)部類,這個類首先是要存在的。

    3. 當(dāng)所在方法的形參需要被匿名內(nèi)部類使用,那么這個形參就必須為final。

    4. 匿名內(nèi)部類沒有明面上的構(gòu)造方法,編譯器會自動生成一個引用外部類的構(gòu)造方法。

    相關(guān)推薦:java入門

    以上是2020全新java基礎(chǔ)面試題匯總的詳細(xì)內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1601
29
PHP教程
1502
276
如何使用JDBC處理Java的交易? 如何使用JDBC處理Java的交易? Aug 02, 2025 pm 12:29 PM

要正確處理JDBC事務(wù),必須先關(guān)閉自動提交模式,再執(zhí)行多個操作,最后根據(jù)結(jié)果提交或回滾;1.調(diào)用conn.setAutoCommit(false)以開始事務(wù);2.執(zhí)行多個SQL操作,如INSERT和UPDATE;3.若所有操作成功則調(diào)用conn.commit(),若發(fā)生異常則調(diào)用conn.rollback()確保數(shù)據(jù)一致性;同時應(yīng)使用try-with-resources管理資源,妥善處理異常并關(guān)閉連接,避免連接泄漏;此外建議使用連接池、設(shè)置保存點實現(xiàn)部分回滾,并保持事務(wù)盡可能短以提升性能。

如何使用Java的日歷? 如何使用Java的日歷? Aug 02, 2025 am 02:38 AM

使用java.time包中的類替代舊的Date和Calendar類;2.通過LocalDate、LocalDateTime和LocalTime獲取當(dāng)前日期時間;3.使用of()方法創(chuàng)建特定日期時間;4.利用plus/minus方法不可變地增減時間;5.使用ZonedDateTime和ZoneId處理時區(qū);6.通過DateTimeFormatter格式化和解析日期字符串;7.必要時通過Instant與舊日期類型兼容;現(xiàn)代Java中日期處理應(yīng)優(yōu)先使用java.timeAPI,它提供了清晰、不可變且線

比較Java框架:Spring Boot vs Quarkus vs Micronaut 比較Java框架:Spring Boot vs Quarkus vs Micronaut Aug 04, 2025 pm 12:48 PM

前形式攝取,quarkusandmicronautleaddueTocile timeProcessingandGraalvSupport,withquarkusoftenpernperforminglightbetterine nosserless notelless centarios.2。

了解網(wǎng)絡(luò)端口和防火墻 了解網(wǎng)絡(luò)端口和防火墻 Aug 01, 2025 am 06:40 AM

NetworkPortSandFireWallsworkTogetHertoEnableCommunication whereSeringSecurity.1.NetWorkPortSareVirtualendPointSnumbered0-655 35,with-Well-with-Newonportslike80(HTTP),443(https),22(SSH)和25(smtp)sindiessingspefificservices.2.portsoperateervertcp(可靠,c

垃圾收集如何在Java工作? 垃圾收集如何在Java工作? Aug 02, 2025 pm 01:55 PM

Java的垃圾回收(GC)是自動管理內(nèi)存的機制,通過回收不可達(dá)對象釋放堆內(nèi)存,減少內(nèi)存泄漏風(fēng)險。1.GC從根對象(如棧變量、活動線程、靜態(tài)字段等)出發(fā)判斷對象可達(dá)性,無法到達(dá)的對象被標(biāo)記為垃圾。2.基于標(biāo)記-清除算法,標(biāo)記所有可達(dá)對象,清除未標(biāo)記對象。3.采用分代收集策略:新生代(Eden、S0、S1)頻繁執(zhí)行MinorGC;老年代執(zhí)行較少但耗時較長的MajorGC;Metaspace存儲類元數(shù)據(jù)。4.JVM提供多種GC器:SerialGC適用于小型應(yīng)用;ParallelGC提升吞吐量;CMS降

使用HTML'輸入類型”作為用戶數(shù)據(jù) 使用HTML'輸入類型”作為用戶數(shù)據(jù) Aug 03, 2025 am 11:07 AM

選擇合適的HTMLinput類型能提升數(shù)據(jù)準(zhǔn)確性、增強用戶體驗并提高可用性。1.根據(jù)數(shù)據(jù)類型選用對應(yīng)input類型,如text、email、tel、number和date,可實現(xiàn)自動校驗和適配鍵盤;2.利用HTML5新增類型如url、color、range和search,可提供更直觀的交互方式;3.配合使用placeholder和required屬性,可提升表單填寫效率和正確率,但需注意placeholder不能替代label。

比較Java構(gòu)建工具:Maven vs. Gradle 比較Java構(gòu)建工具:Maven vs. Gradle Aug 03, 2025 pm 01:36 PM

Gradleisthebetterchoiceformostnewprojectsduetoitssuperiorflexibility,performance,andmoderntoolingsupport.1.Gradle’sGroovy/KotlinDSLismoreconciseandexpressivethanMaven’sverboseXML.2.GradleoutperformsMaveninbuildspeedwithincrementalcompilation,buildcac

以身作則,解釋說明 以身作則,解釋說明 Aug 02, 2025 am 06:26 AM

defer用于在函數(shù)返回前執(zhí)行指定操作,如清理資源;參數(shù)在defer時立即求值,函數(shù)按后進(jìn)先出(LIFO)順序執(zhí)行;1.多個defer按聲明逆序執(zhí)行;2.常用于文件關(guān)閉等安全清理;3.可修改命名返回值;4.即使發(fā)生panic也會執(zhí)行,適合用于recover;5.避免在循環(huán)中濫用defer,防止資源泄漏;正確使用可提升代碼安全性和可讀性。

See all articles