Java基礎面試題總結


 

1、 面向對象和面向過程的區別

  • 面向過程 :面向過程性能比面向對象高。 因為類調用時需要實例化,開銷比較大,比較消耗資源,所以當性能是最重要的考量因素的時候,比如單片機、嵌入式開發、Linux/Unix等一般采用面向過程開發。但是,面向過程沒有面向對象易維護、易復用、易擴展。
  • 面向對象 :面向對象易維護、易復用、易擴展。 因為面向對象有封裝、繼承、多態性的特性,所以可以設計出低耦合的系統,使系統更加靈活、更加易於維護。但是,面向對象性能比面向過程低。

2、Java 語言有哪些特點?

  1. 簡單易學;
  2. 面向對象(封裝,繼承,多態);
  3. 平台無關性( Java 虛擬機實現平台無關性);
  4. 可靠性;
  5. 安全性;
  6. 支持多線程( C++ 語言沒有內置的多線程機制,因此必須調用操作系統的多線程功能來進行多線程程序設計,而 Java 語言卻提供了多線程支持);
  7. 支持網絡編程並且很方便( Java 語言誕生本身就是為簡化網絡編程設計的,因此 Java 語言不僅支持網絡編程而且很方便);
  8. 編譯與解釋並存;

3、JVM、JDK 、JRE

JVM:Java虛擬機(JVM)是運行 Java 字節碼的虛擬機。JVM有針對不同系統的特定實現(Windows,Linux,macOS),目的是使用相同的字節碼,它們都會給出相同的結果。

什么是字節碼?采用字節碼的好處是什么?

  在 Java 中,JVM可以理解的代碼就叫做字節碼(即擴展名為 .class 的文件),它不面向任何特定的處理器,只面向虛擬機。Java 語言通過字節碼的方式,在一定程度上解決了傳統解釋型語言執行效率低的問題,同時又保留了解釋型語言可移植的特點。所以 Java 程序運行時比較高效,而且,由於字節碼並不針對一種特定的機器,因此,Java程序無須重新編譯便可在多種不同操作系統的計算機上運行。

Java 程序從源代碼到運行一般有下面3步:

  

  我們需要格外注意的是 .class->機器碼 這一步。在這一步 JVM 類加載器首先加載字節碼文件,然后通過解釋器逐行解釋執行,這種方式的執行速度會相對比較慢。而且,有些方法和代碼塊是經常需要被調用的(也就是所謂的熱點代碼),所以后面引進了 JIT 編譯器,而JIT 屬於運行時編譯當 JIT 編譯器完成第一次編譯后,其會將字節碼對應的機器碼保存下來,下次可以直接使用。而我們知道,機器碼的運行效率肯定是高於 Java 解釋器的。這也解釋了我們為什么經常會說 Java 是編譯與解釋共存的語言。

 JDK:(Java Development Kit)Java開發工具包,它擁有JRE所擁有的一切,還有編譯器(javac)和工具(如javadoc和jdb)。它能夠創建和編譯程序。

JRE:(Java Runtime Environment)Java運行時環境,它是運行已編譯 Java 程序所需的所有內容的集合,包括 Java虛擬機(JVM),Java類庫,java命令和其他的一些基礎構件。但是,它不能用於創建新程序。

4、Java和C++的區別?

  • 都是面向對象的語言,都支持封裝、繼承和多態。
  • Java 不提供指針來直接訪問內存,程序內存更加安全。
  • Java 的類是單繼承的,C++ 支持多重繼承;雖然 Java 的類不可以多繼承,但是接口可以多繼承。
  • Java 有自動內存管理機制,不需要程序員手動釋放無用內存。

5、字符型常量和字符串常量的區別?

  1. 形式上:字符常量是單引號引起的一個字符;字符串常量是雙引號引起的若干個字符。
  2. 含義上:字符常量相當於一個整型值( ASCII 值),可以參加表達式運算; 字符串常量代表一個地址值(該字符串在內存中存放位置)。
  3. 占內存大小 :字符常量只占2個字節;字符串常量占若干個字節(至少一個字符結束標志)。 (注意: char在Java中占兩個字節)

 一個字節(Byte)占8位(8bit)

5、8大基本數據類型及其字節數?

byte:1字節    short:2字節

int:4字節    long:8字節

float:4字節精確到7位有效數字    double:8字節

char:2字節    boolean:1位

引用類型:4字節 ,1個字節表示8位

 6、構造器 Constructor 是否可被 override?

   父類的私有屬性和構造方法並不能被繼承,所以 Constructor 也就不能被 override(重寫),但是可以 overload(重載),所以你可以看到一個類中有多個構造函數的情況。

 7、重載和重寫的區別?

  • 重載 發生在同一個類中方法名必須相同,實質表現就是多個具有不同的參數個數或者類型同名函數返回值類型可隨意,不能以返回類型作為重載函數的區分標准),返回值類型、訪問修飾符可以不同,發生在編譯時。   
  • 重寫: 發生在父子類中方法名、參數列表必須相同是父類與子類之間的多態性,實質是對父類的函數進行重新定義返回值范圍小於等於父類,拋出的異常范圍小於等於父類,訪問修飾符范圍大於等於父類如果父類方法訪問修飾符為 private 則子類就不能重寫該方法

 問:Java 構造方法能否被重寫和重載?

  重寫是子類方法重寫父類的方法,重寫的方法名不變,而類的構造方法名必須與類名一致,假設父類的構造方法如果能夠被子類重寫則子類類名必須與父類類名一致才行,所以 Java 的構造方法是不能被重寫的。而重載是針對同一個的,所以構造方法可以被重載

 8、Java 面向對象編程三大特性?

  封裝 繼承 多態

 封裝

  封裝就是把抽象的數據和對數據進行的操作封裝在一起,數據被保存在內部,程序的其他部分只有通過被授權的操作(成員方法)才能對數據進行操作。

  java提供了四種控制修飾符控制方法和變量訪問的權限:

  • public:對外公開
  • protected:對子類和同一包中的類公開
  • 沒有修飾符號:向同一個包的類公開
  • private:只有類本身可以訪問,不對外公開

 繼承:(extends )

  繼承是使用已存在的類的定義作為基礎建立新類的技術。繼承可以解決代碼復用問題,當多個類存在相同的屬性(變量)和方法時,可以從這些類中抽象出父類,在父類中定義這些相同的屬性和方法,所有的子類不需要重新定義這些屬性和方法,只需要通過extend語句來聲明繼承父類。

關於繼承如下 3 點請記住:

  • 子類擁有父類對象所有的屬性和方法(包括私有屬性和私有方法),但是父類中的私有屬性和方法子類是無法訪問,只是擁有。
  • 子類可以擁有自己屬性和方法,即子類可以對父類進行擴展。
  • 子類可以用自己的方式實現父類的方法。

多態

所謂多態,就是指一個引用(類型)在不同情況下的多種狀態,你也可以這樣理解:父類型的引用指向子類型的對象

多態有兩個好處:

1. 應用程序不必為每一個派生類編寫功能調用,只需要對抽象基類進行處理即可。大大提高程序的可復用性。//繼承 
2. 派生類的功能可以被基類的方法或引用變量所調用,這叫向后兼容,可以提高可擴充性和可維護性。 //多態的真正作用,

9、String、StringBuffer 和 StringBuilder 的區別是什么? String 為什么是不可變的?(重要)

一、區別

1、String是字符串常量,而StringBuffer和StringBuilder是字符串變量。由String創建的字符內容是不可改變的,而由StringBuffer和StringBuidler創建的字符內容是可以改變的。

2、StringBuffer是線程安全的,而StringBuilder是非線程安全的。StringBuilder是從JDK 5開始,為StringBuffer類補充的一個單線程的等價類。我們在使用時應優先考慮使用StringBuilder,因為它支持StringBuffer的所有操作,但是因為它不執行同步,不會有線程安全帶來額外的系統消耗,所以速度更快。

二、String為什么是不可變的?

String 類中使用 final 關鍵字修飾字符數組來保存字符串private final char value[],所以 String 對象是不可變的。而StringBuilder 與 StringBuffer 都繼承自 AbstractStringBuilder 類,在 AbstractStringBuilder 中也是使用字符數組保存字符串char[]value 但是沒有用 final 關鍵字修飾,所以這兩種對象都是可變的。

  String是被聲明為final class,除了hash這個屬性其它屬性都聲明為final。因為它的不可變性,所以例如拼接字符串時候會產生很多無用的中間對象,如果頻繁的進行這樣的操作對性能有所影響。

  StringBuffer就是為了解決大量拼接字符串時產生很多中間對象問題而提供的一個類,提供append和add方法,可以將字符串添加到已有序列的末尾或指定位置,它的本質是一個線程安全的可修改的字符序列,把所有修改數據的方法都加上了synchronized。但是保證了線程安全是需要性能的代價的。

  在很多情況下我們的字符串拼接操作不需要線程安全,這時候StringBuilder登場了,StringBuilder是JDK1.5發布的,它和StringBuffer本質上沒什么區別,就是去掉了保證線程安全的那部分,減少了開銷。

  StringBuffer 和 StringBuilder 二者都繼承了 AbstractStringBuilder ,底層都是利用可修改的char數組(JDK 9 以后是 byte數組)。

再說說字符串常量池:

  Java為了避免在一個系統中產生大量的String對象,引入了字符串常量池。

  創建一個字符串時,首先會檢查池中是否有值相同的字符串對象,如果有就直接返回引用,不會創建字符串對象;如果沒有則新建字符串對象,返回對象引用,並且將新創建的對象放入池中但是,通過new方法創建的String對象是不檢查字符串常量池的,而是直接在堆中創建新對象,也不會把對象放入池中。上述原則只適用於直接給String對象引用賦值的情況。

  String str1 = new String("a");  //不檢查字符串常量池的
  String str2 = "bb";   //檢查字符串常量池的

  String還提供了intern()方法。調用該方法時,如果字符串常量池中包括了一個等於此String對象的字符串(由equals方法確定),則返回池中的字符串的引用。否則,將此String對象添加到池中,並且返回此池中對象的引用。

  在JDK6中,不推薦大量使用intern方法,因為這個版本字符串緩存在永久代中,這個空間是有限了,除了FullGC之外不會被清楚,所以大量的緩存在這容易OutOfMemoryError。

  之后的版本把字符串放入了堆中,避免了永久代被擠滿。

參考:https://baijiahao.baidu.com/s?id=1629804867201303563&wfr=spider&for=pc

對於三者使用的總結

  1. 操作少量的數據: 適用String
  2. 單線程操作字符串緩沖區下操作大量數據: 適用StringBuilder
  3. 多線程操作字符串緩沖區下操作大量數據: 適用StringBuffer

10、自動裝箱與拆箱

  • 裝箱:將基本類型用它們對應的引用類型包裝起來;
  • 拆箱:將包裝類型轉換為基本數據類型;
//自動裝箱
Integer total = 99; //系統自動執行了Integer total = Integer.valueOf(99);
 
//自定拆箱
int totalprim = total;  //系統自動執行了int totalprim = total.intValue();

問題一:int和Integer的區別?

1. int是基本數據類型,Integer是int的包裝類就是將int類型包裝成Object對象;

2. Integer變量必須實例化后才能使用;int變量不需要;

3. Integer實際是對象的引用,指向此new的Integer對象;int是直接存儲數據值 ;

4. Integer的默認值是null;int的默認值是0。

深入:

  • 兩個通過new生成的Integer變量永遠是不相等的。因為new生成的是兩個對象,其內存地址不同。
  • Integer與new Integer不會相等。因為非new生成的Integer變量指向的是java常量池中的對象,而new Integer()生成的變量指向堆中新建的對象,兩者在內存中的地址不同。
  •  兩個都是非new出來的Integer,如果數在-128到127之間,則是true,否則為false。
    •  java在編譯Integer i = 127的時候,被翻譯成 Integer i = Integer.valueOf(127);  java API中對Integer類型的valueOf的定義如下,對於-128到127之間的數,會進行緩存,Integer i = 127時,會將127這個Integer對象進行緩存,下次再寫Integer j = 127時,就會直接從緩存中取,就不會new了。
  • Integer變量和int變量比較時,只要兩個變量的值是向等的,則結果為true。(因為包裝類Integer和基本數據類型int比較時,java會自動拆箱為int,然后進行比較,實際上就變為兩個int變量的比較)

Integer.valueOf函數源碼:

public static Integer valueOf(int i) {
    return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
}

它會首先判斷i的大小:如果i小於-128或者大於等於128,就創建一個Integer對象,否則執行SMALL_VALUES[i + 128]。

SMALL_VALUES[i + 128]是什么東西:

private static final Integer[] SMALL_VALUES = new Integer[256];

SMALL_VALUES本來已經被創建好,也就是說在i >= 128 || i < -128是會創建不同的對象,在i < 128 && i >= -128會根據i的值返回已經創建好的指定的對象。

問題二:為什么有了int還要有設計Integer?

  對象封裝有很多好處,可以把屬性也就是數據跟處理這些數據的方法結合在一起,比如Integer就有parseInt()等方法來專門處理int型相關的數據。

  另一個非常重要的原因就是在Java中絕大部分方法或類都是用來處理類類型對象的,如ArrayList集合類就只能以類作為他的存儲對象,而這時如果想把一個int型的數據存入list是不可能的,必須把它包裝成類,也就是Integer才能被List所接受。所以Integer的存在是很必要的。

11、為什么不能從靜態的方法里調用非靜態的方法或變量?

  非靜態的方法可以調用靜態的方法,但是靜態的方法不可以調用非靜態的方法。

  類的靜態成員(變量和方法)屬於類本身,在類加載的時候就會分配內存,可以通過類名直接去訪問;非靜態成員(變量和方法)屬於類的對象,所以只有在類的對象產生(創建類的實例)時才會分配內存,然后通過類的對象(實例)去訪問。

  在一個類的靜態成員中去訪問其非靜態成員之所以會出錯是因為在類的非靜態成員不存在的時候類的靜態成員就已經存在了,訪問一個內存中不存在的東西當然會出錯。

參考https://blog.csdn.net/l18649805795/article/details/48939487

12、靜態方法和實例方法有何不同?

  1. 在外部調用靜態方法時,可以使用"類名.方法名"的方式,也可以使用"對象名.方法名"的方式。而實例方法只有后面這種方式。也就是說,調用靜態方法可以無需創建對象。

  2. 靜態方法在訪問本類的成員時,只允許訪問靜態成員(即靜態成員變量和靜態方法),而不允許訪問實例成員變量和實例方法;實例方法則無此限制。

問題:static修飾變量、代碼塊時什么時候執行?執行幾次?

  在類加載的init階段,類的類構造器中會收集所有的static塊和字段並執行;static塊只執行一次。

【注】:

  • static語句塊,不是在實例化的時候被執行的;
  • 在調用類中任何一個方法時,jvm進行類加載,static語句塊是在類加載器加載該類的最后階段進行初始化的。並且只會被初始化一次。  (注:若一次性調用多個方法,則只會執行一次static代碼塊。)

13、在 Java 中定義一個不做事且沒有參數的構造方法的作用?

  Java 程序在執行子類的構造方法之前,如果沒有用super()來調用父類特定的構造方法,則會調用父類中“沒有參數的構造方法”。因此,如果父類中只定義了有參數的構造方法,而在子類的構造方法中又沒有用 super()來調用父類中特定的構造方法,則編譯時將發生錯誤,因為 Java 程序在父類中找不到沒有參數的構造方法可供執行。解決辦法是在父類里加上一個不做事且沒有參數的構造方法。

問題:子類繼承父類時,父類的構造方法什么時候調用?

  實例化一個子類對象時會先執行其父類的構造函數,然后再執行子類的構造函數。

  super()必須先被調用;如果子類構造方法里沒有寫super(),編譯器會自動調用super()方法,即調用父類的默認無參構造方法。所以不可以父類中只定義了有參數的構造方法(在Java中,如果一個類沒有定義構造方法,編譯器會默認插入一個無參數的構造方法;但是如果一個構造方法在父類中已定義,在這種情況,編譯器是不會自動插入一個默認的無參構造方法)

14、構造方法有哪些特性?

  1. 名字與類名相同。
  2. 沒有返回值,但不能用void聲明構造函數。
  3. 生成類的對象時自動執行,無需調用。

15、接口(interface)和抽象類(abstract class)的區別是什么?

  1. 接口中的所有方法必須都是抽象的,不能有非抽象的普通方法(所有方法在接口中不能有實現);而抽象類中可以包含非抽象的普通方法。
  2. 接口中不能有構造方法,抽象類可以有構造方法。
  3. 接口中除了static、final變量,不能有其他變量,而抽象類中則不一定。
  4. 一個類可以實現多個接口,但只能繼承一個抽象類。接口自己本身可以通過extends關鍵字擴展多個接口。
  5. 接口中的抽象方法只能是public類型的,並且默認修飾符是public;抽象方法可以有public、protected和default這些修飾符(抽象方法就是為了被重寫所以不能使用private關鍵字修飾!)。
  6. 接口中不能包含靜態方法;抽象類中可以包含靜態方法。
  7. 抽象類和接口中都可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型可以任意,但接口中定義的變量只能是public static final類型,並且默認即為public static final類型。

接口和抽象類的相同點:

  1. 都可以被繼承
  2. 都不能被實例化
  3. 都可以包含方法聲明
  4. 派生類必須實現未實現的方法

16、成員變量與局部變量的區別有那些?

  1. 從語法形式上看:成員變量是屬於類的,而局部變量是在方法中定義的變量或是方法的參數;成員變量可以被 public,private,static 等修飾符所修飾,而局部變量不能被訪問控制修飾符及 static 所修飾;但是,成員變量和局部變量都能被 final 所修飾。
  2. 從變量在內存中的存儲方式來看:如果成員變量是使用static修飾的,那么這個成員變量是屬於類的,如果沒有使用static修飾,這個成員變量是屬於實例的。而對象存在於堆內存,局部變量則存在於棧內存。
  3. 從變量在內存中的生存時間上看:成員變量是對象的一部分,它隨着對象的創建而存在,而局部變量隨着方法的調用而自動消失。
  4. 成員變量如果沒有被賦初值:則會自動以類型的默認值而賦值(一種情況例外:被 final 修飾的成員變量也必須顯式地賦值),而局部變量則不會自動賦值。

17、== 與 equals的區別?(重要)

  1)==比較的是值是否相等

         如果作用於基本數據類型的變量,則直接比較其存儲的 “值”是否相等;

    如果作用於引用類型的變量,則比較的是所指向的對象的地址。

  2)equals方法不能作用於基本數據類型的變量,只能用於類變量。(對於基本數據類型要用其包裝類)

    如果沒有對equals方法進行重寫,則比較的是引用類型的變量所指向的對象的地址;

    諸如String、Date等類對equals方法進行了重寫的話,比較的是所指向的對象的內容

【注】Object類中的equals方法和“==”是一樣的,沒有區別,而String類,Integer類等等一些類,是重寫了equals方法,才使得equals和“==不同”,所以,當自己創建類時,自動繼承了Object的equals方法,要想實現不同的等於比較,必須重寫equals方法。

    String a = new String("ab");  // a為一個引用
    String b = new String("ab");  // b為另一個引用,對象的內容一樣
    String aa = "ab";   //放在常量池中
    String bb = "ab";   //從常量池中查找
        
    System.out.println(aa==bb);//true

    System.out.println(a==b); //false,非同一對象
            
    System.out.println((a.equals(b)); //true
            
    System.out.println((42 == 42.0); //true

  • String 中的 equals 方法是被重寫過的,因為 object 的 equals 方法是比較的對象的內存地址,而 String 的 equals 方法比較的是對象的值。
  • 當創建 String 類型的對象時,虛擬機會在常量池中查找有沒有已經存在的值和要創建的值相同的對象,如果有就把它賦給當前引用。如果沒有就在常量池中重新創建一個 String 對象。

 18、為什么重寫equals時必須重寫hashCode方法? (重要)

當對象的equals()方法被重寫時,通常有必要重寫 hashCode() 方法,以維護 hashCode 方法的常規協定,該協定聲明相等對象必須具有相等的哈希碼

          (1)兩個對象相等,hashcode一定相等

          (2)兩個對象不等,hashcode不一定不等

          (3)hashcode相等,兩個對象不一定相等

          (4)hashcode不等,兩個對象一定不等

          hashcode是用於散列數據的快速存取,如利用HashSet/HashMap/Hashtable類來存儲數據時,都是根據存儲對象的hashcode值來進行判斷是否相同的。這樣如果我們對一個對象重寫了euqals,意思是只要對象的成員變量值都相等那么euqals就等於true,但不重寫hashcode,那么我們再new一個新的對象,當原對象.equals(新對象)等於true時,兩者的hashcode卻是不一樣的,由此將產生了理解的不一致

https://www.cnblogs.com/wang-meng/p/7501378.html

HashMap中的get與put:
(1)put:
              1.首先根據put元素的key獲取hashcode,然后根據hashcode算出數組的下標位置,如果下標位置沒有元素,直接放入元素即可。
              2.如果該下標位置有元素,則需要已有元素和put元素的key對象比較equals方法,如果equals不一樣,則說明可以放入進map中,會在該數組位置創建一個鏈表,后put進入的元素到放鏈表頭,原來的元素向后移動。       
(2)get:
             根據元素的key獲取hashcode,然后根據hashcode獲取數組下標位置,如果只有一個元素則直接取出。如果該位置是一個鏈表,則需要調用equals方法遍歷鏈表中的所有元素與當前的元素比較,得到真正想要的對象。(當兩個對象的hashcode不同的話,肯定他們不能equals。)

19、Java 中 final、finally、finalize 的區別?

(1) final 是一個修飾符,

  1. 如果一個類被聲明為 final 則其不能再派生出新的子類,所以一個類不能既被聲明為 abstract 又被聲明為 final [所謂不可同時出現]的;
  2. 將變量或方法聲明為 final 可以保證它們在使用中不被改變(對於對象變量來說其引用不可變,即不能再指向其他的對象,但是對象的值可變)。

   注:

  1. 被聲明為 final 的變量必須在聲明時給定初值,而在以后的引用中只能讀取不可修改,被聲明為 final 的方法也同樣只能使用不能重載。
  2. 使用 final 關鍵字如果編譯器能夠在編譯階段確定某變量的值則編譯器就會把該變量當做編譯期常量來使用,如果需要在運行時確定(譬如方法調用)則編譯器就不會優化相關代碼;將類、方法、變量聲明為 final 能夠提高性能,這樣 JVM 就有機會進行估計並進行優化;接口中的變量都是 public static final 的。

final關鍵字主要用在三個地方:變量、方法、類。

  1. 對於一個final變量,如果是基本數據類型的變量,則其數值一旦在初始化之后便不能更改;如果是引用類型的變量,則在對其初始化之后便不能再讓其指向另一個對象。
  2. 當用final修飾一個類時,表明這個類不能被繼承。final類中的所有成員方法都會被隱式地指定為final方法。
  3. 使用final方法的原因有兩個。第一個原因是把方法鎖定,以防任何繼承類修改它的含義;第二個原因是效率。在早期的Java實現版本中,會將final方法轉為內嵌調用。但是如果方法過於龐大,可能看不到內嵌調用帶來的任何性能提升(現在的Java版本已經不需要使用final方法進行這些優化了)。類中所有的private方法都隱式地指定為final。

(2)finally:用來在異常處理中,如果拋出一個異常,則相匹配的 catch 子句就會執行,然后控制就會進入 finally 塊

  finally是對Java異常處理模型的最佳補充。finally結構使代碼總會執行,而不管無異常發生。使用finally可以維護對象的內部狀態,並可以清理非內存資源。特別是在關閉數據庫連接這方面,如果程序員把數據庫連接的close()方法放到finally中,就會大大降低程序出錯的幾率。

異常處理:

  • try 塊:用於捕獲異常。其后可接零個或多個catch塊,如果沒有catch塊,則必須跟一個finally塊。
  • catch 塊:用於處理try捕獲到的異常。
  • finally 塊:無論是否捕獲或處理異常,finally塊里的語句都會被執行。當在try塊或catch塊中遇到return語句時,finally語句塊將在方法返回之前被執行。

在以下4種特殊情況下,finally塊不會被執行

  1. 在finally語句塊第一行發生了異常。 因為在其他行,finally塊還是會得到執行
  2. 在前面的代碼中用了System.exit(int)已退出程序。 exit是帶參函數 ;若該語句在異常語句之后,finally會執行
  3. 程序所在的線程死亡。
  4. 關閉CPU。

(3)finalize():是一個方法,它是在對象被垃圾回收之前由Java虛擬機來調用的。

  finalize()方法是GC運行機制的一部分,finalize()方法是在GC清理它所從屬的對象時被調用的,如果執行它的過程中拋出了無法捕獲的異常,GC將終止對改對象的清理,並且該異常會被忽略;直到下一次GC開始清理這個對象時,它的finalize()會被再次調用。

20、this、super

(1)this:代表對象本身,可以理解為:指向對象本身的一個指針

this的用法在java中大體可以分為3種:

1)普通的直接引用

這種就不用講了,this相當於是指向當前對象本身:

2)形參與成員名字重名,用this來區分:

3)引用構造函數

this(參數):調用本類中另一種形式的構造方法(應該為構造方法中的第一條語句)

 

(2)super:代指父類,可以用於調用父類的普通方法和構造方法。

調用父類構造方法:super()(無參構造方法)或 super(參數)(有參構造方法)

調用父類普通方法:super.方法名(參數)

 

21、Java序列化中如果有些字段不想進行序列化,怎么辦?

   對於不想進行序列化的變量,使用transient關鍵字修飾。

  transient關鍵字的作用是:阻止實例中那些用此關鍵字修飾的的變量序列化;當對象被反序列化時,被transient修飾的變量值不會被持久化和恢復。transient只能修飾變量,不能修飾類和方法。

 22、 獲取用鍵盤輸入常用的的兩種方法

 方法1:通過 Scanner

Scanner sc = new Scanner(System.in);
String s  = sc.nextLine();
input.close();

方法2:通過 BufferedReader

BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); 
String s = input.readLine();

 

 參考:https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/Java%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86.md


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM