国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

2023面試八股文 ——Java基礎(chǔ)知識(shí)

這篇具有很好參考價(jià)值的文章主要介紹了2023面試八股文 ——Java基礎(chǔ)知識(shí)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一.Java概述

何為編程

編程就是讓計(jì)算機(jī)為解決某個(gè)問(wèn)題而使用某種程序設(shè)計(jì)語(yǔ)言編寫(xiě)程序代碼,并 終得到結(jié)果的過(guò)程。

為了使計(jì)算機(jī)能夠理解人的意圖,人類(lèi)就必須要將需解決的問(wèn)題的思路、方法、 和手段通過(guò)計(jì)算機(jī)能夠理解的形式告訴計(jì)算機(jī),使得計(jì)算機(jī)能夠根據(jù)人的指令一 步一步去工作,完成某種特定的任務(wù)。這種人和計(jì)算機(jī)之間交流的過(guò)程就是編 程。

什么是Java

Java是一門(mén)面向?qū)ο缶幊陶Z(yǔ)言,不僅吸收了C++語(yǔ)言的各種優(yōu)點(diǎn),還摒棄了 C++里難以理解的多繼承、指針等概念,因此Java語(yǔ)言具有功能強(qiáng)大和簡(jiǎn)單易 用兩個(gè)特征。Java語(yǔ)言作為靜態(tài)面向?qū)ο缶幊陶Z(yǔ)言的代表,極好地實(shí)現(xiàn)了面向?qū)?象理論,允許程序員以優(yōu)雅的思維方式進(jìn)行復(fù)雜的編程 。

jdk1.5之后的三大版本

  • Java SE(J2SE,Java 2 Platform Standard Edition,標(biāo)準(zhǔn)版) Java SE 以前稱(chēng)為 J2SE。它允許開(kāi)發(fā)和部署在桌面、服務(wù)器、嵌入式環(huán)境和實(shí)時(shí)環(huán)境中使 用的 Java 應(yīng)用程序。Java SE 包含了支持 Java Web 服務(wù)開(kāi)發(fā)的類(lèi),并為Java EE和Java ME提供基礎(chǔ)。
  • Java EE(J2EE,Java 2 Platform Enterprise Edition,企業(yè)版) Java EE 以前稱(chēng)為 J2EE。企業(yè)版本幫助開(kāi)發(fā)和部署可移植、健壯、可伸縮且安全的服務(wù)器 端Java 應(yīng)用程序。Java EE 是在 Java SE 的基礎(chǔ)上構(gòu)建的,它提供 Web 服務(wù)、組件模型、 管理和通信 API,可以用來(lái)實(shí)現(xiàn)企業(yè)級(jí)的面向服務(wù)體系結(jié)構(gòu)(service-oriented architecture,SOA)和 Web2.0應(yīng)用程序。2018年2月,Eclipse 宣布正式將 JavaEE 更名 為 JakartaEE
  • Java ME(J2ME,Java 2 Platform Micro Edition,微型版) Java ME 以前稱(chēng)為 J2ME。Java ME 為在移動(dòng)設(shè)備和嵌入式設(shè)備(比如手機(jī)、PDA、電視 機(jī)頂盒和打印機(jī))上運(yùn)行的應(yīng)用程序提供一個(gè)健壯且靈活的環(huán)境。Java ME 包括靈活的用 戶界面、健壯的安全模型、許多內(nèi)置的網(wǎng)絡(luò)協(xié)議以及對(duì)可以動(dòng)態(tài)下載的連網(wǎng)和離線應(yīng)用程序 的豐富支持?;?Java ME 規(guī)范的應(yīng)用程序只需編寫(xiě)一次,就可以用于許多設(shè)備,而且可 以利用每個(gè)設(shè)備的本機(jī)功能。

JVM、JRE和JDK的關(guān)系

JVM

Java Virtual Machine是Java虛擬機(jī),Java程序需要運(yùn)行在虛擬機(jī)上,不同的平 臺(tái)有自己的虛擬機(jī),因此Java語(yǔ)言可以實(shí)現(xiàn)跨平臺(tái)。

JRE

Java Runtime Environment包括Java虛擬機(jī)和Java程序所需的核心類(lèi)庫(kù)等。核 心類(lèi)庫(kù)主要是java.lang包:包含了運(yùn)行Java程序必不可少的系統(tǒng)類(lèi),如基本數(shù) 據(jù)類(lèi)型、基本數(shù)學(xué)函數(shù)、字符串處理、線程、異常處理類(lèi)等,系統(tǒng)缺省加載這個(gè)包

如果想要運(yùn)行一個(gè)開(kāi)發(fā)好的Java程序,計(jì)算機(jī)中只需要安裝JRE即可。

JDK

Java Development Kit是提供給Java開(kāi)發(fā)人員使用的,其中包含了Java的開(kāi)發(fā) 工具,也包括了JRE。所以安裝了JDK,就無(wú)需再單獨(dú)安裝JRE了。其中的開(kāi)發(fā)工 具:編譯工具(javac.exe),打包工具(jar.exe)等

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-mFIOelzo-1692506313322)(01-Java基礎(chǔ)知識(shí)面試題(2020最新版).assets/image-20201106172325865.png)]

什么是跨平臺(tái)性?原理是什么

所謂跨平臺(tái)性,是指java語(yǔ)言編寫(xiě)的程序,一次編譯后,可以在多個(gè)系統(tǒng)平臺(tái)上 運(yùn)行。

實(shí)現(xiàn)原理:Java程序是通過(guò)java虛擬機(jī)在系統(tǒng)平臺(tái)上運(yùn)行的,只要該系統(tǒng)可以安 裝相應(yīng)的java虛擬機(jī),該系統(tǒng)就可以運(yùn)行java程序。

Java語(yǔ)言有哪些特點(diǎn)

簡(jiǎn)單易學(xué)(Java語(yǔ)言的語(yǔ)法與C語(yǔ)言和C++語(yǔ)言很接近)

面向?qū)ο螅ǚ庋b,繼承,多態(tài))

平臺(tái)無(wú)關(guān)性(Java虛擬機(jī)實(shí)現(xiàn)平臺(tái)無(wú)關(guān)性)

支持網(wǎng)絡(luò)編程并且很方便(Java語(yǔ)言誕生本身就是為簡(jiǎn)化網(wǎng)絡(luò)編程設(shè)計(jì)的)

支持多線程(多線程機(jī)制使應(yīng)用程序在同一時(shí)間并行執(zhí)行多項(xiàng)任)

健壯性(Java語(yǔ)言的強(qiáng)類(lèi)型機(jī)制、異常處理、垃圾的自動(dòng)收集等)

安全性

什么是字節(jié)碼?采用字節(jié)碼的大好處是什么

字節(jié)碼:Java源代碼經(jīng)過(guò)虛擬機(jī)編譯器編譯后產(chǎn)生的文件(即擴(kuò)展為.class的文 件),它不面向任何特定的處理器,只面向虛擬機(jī)。

采用字節(jié)碼的好處:

Java語(yǔ)言通過(guò)字節(jié)碼的方式,在一定程度上解決了傳統(tǒng)解釋型語(yǔ)言執(zhí)行效率低的 問(wèn)題,同時(shí)又保留了解釋型語(yǔ)言可移植的特點(diǎn)。所以Java程序運(yùn)行時(shí)比較高效, 而且,由于字節(jié)碼并不專(zhuān)對(duì)一種特定的機(jī)器,因此,Java程序無(wú)須重新編譯便可 在多種不同的計(jì)算機(jī)上運(yùn)行。

先看下java中的編譯器和解釋器:

Java中引入了虛擬機(jī)的概念,即在機(jī)器和編譯程序之間加入了一層抽象的虛擬機(jī) 器。這臺(tái)虛擬的機(jī)器在任何平臺(tái)上都提供給編譯程序一個(gè)的共同的接口。編譯程 序只需要面向虛擬機(jī),生成虛擬機(jī)能夠理解的代碼,然后由解釋器來(lái)將虛擬機(jī)代 碼轉(zhuǎn)換為特定系統(tǒng)的機(jī)器碼執(zhí)行。在Java中,這種供虛擬機(jī)理解的代碼叫做字節(jié) 碼(即擴(kuò)展為.class的文件),它不面向任何特定的處理器,只面向虛擬機(jī)。每 一種平臺(tái)的解釋器是不同的,但是實(shí)現(xiàn)的虛擬機(jī)是相同的。Java源程序經(jīng)過(guò)編譯 器編譯后變成字節(jié)碼,字節(jié)碼由虛擬機(jī)解釋執(zhí)行,虛擬機(jī)將每一條要執(zhí)行的字節(jié) 碼送給解釋器,解釋器將其翻譯成特定機(jī)器上的機(jī)器碼,然后在特定的機(jī)器上運(yùn) 行,這就是上面提到的Java的特點(diǎn)的編譯與解釋并存的解釋。

Java源代碼‐‐‐‐>編譯器‐‐‐‐>jvm可執(zhí)行的Java字節(jié)碼(即虛擬指令)‐‐‐‐>jvm‐‐‐‐>jvm中 解釋器‐‐‐‐‐>機(jī)器可執(zhí)行的二進(jìn)制機(jī)器碼‐‐‐‐>程序運(yùn)行。

什么是Java程序的主類(lèi)?應(yīng)用程序和小程序的主類(lèi)有何不同?

一個(gè)程序中可以有多個(gè)類(lèi),但只能有一個(gè)類(lèi)是主類(lèi)。在Java應(yīng)用程序中,這個(gè)主 類(lèi)是指包含main()方法的類(lèi)。而在Java小程序中,這個(gè)主類(lèi)是一個(gè)繼承自系統(tǒng) 類(lèi)JApplet或Applet的子類(lèi)。應(yīng)用程序的主類(lèi)不一定要求是public類(lèi),但小程序 的主類(lèi)要求必須是public類(lèi)。主類(lèi)是Java程序執(zhí)行的入口點(diǎn)。

Java應(yīng)用程序與小程序之間有那些差別?

簡(jiǎn)單說(shuō)應(yīng)用程序是從主線程啟動(dòng)(也就是main()方法)。applet小程序沒(méi)有main 方法,主要是嵌在瀏覽器頁(yè)面上運(yùn)行(調(diào)用init()線程或者run()來(lái)啟動(dòng)),嵌入瀏 覽器這點(diǎn)跟flash的小游戲類(lèi)似。

Java和C++的區(qū)別

我知道很多人沒(méi)學(xué)過(guò)C++,但是面試官就是沒(méi)事喜歡拿咱們Java和C++比呀! 沒(méi)辦法!??!就算沒(méi)學(xué)過(guò)C++,也要記下來(lái)!

  • 都是面向?qū)ο蟮恼Z(yǔ)言,都支持封裝、繼承和多態(tài)
  • Java不提供指針來(lái)直接訪問(wèn)內(nèi)存,程序內(nèi)存更加安全
  • Java的類(lèi)是單繼承的,C++支持多重繼承;雖然Java的類(lèi)不可以多繼承,但是 接口可以多繼承。
  • Java有自動(dòng)內(nèi)存管理機(jī)制,不需要程序員手動(dòng)釋放無(wú)用內(nèi)存

Oracle JDK 和 OpenJDK 的對(duì)比

  1. Oracle JDK版本將每三年發(fā)布一次,而OpenJDK版本每三個(gè)月發(fā)布一 次;
  2. OpenJDK 是一個(gè)參考模型并且是完全開(kāi)源的,而Oracle JDK是 OpenJDK的一個(gè)實(shí)現(xiàn),并不是完全開(kāi)源的;
  3. Oracle JDK 比 OpenJDK 更穩(wěn)定。OpenJDK和Oracle JDK的代碼幾乎 相同,但Oracle JDK有更多的類(lèi)和一些錯(cuò)誤修復(fù)。因此,如果您想開(kāi)發(fā)企 業(yè)/商業(yè)軟件,我建議您選擇Oracle JDK,因?yàn)樗?jīng)過(guò)了徹底的測(cè)試和穩(wěn) 定。某些情況下,有些人提到在使用OpenJDK 可能會(huì)遇到了許多應(yīng)用程 序崩潰的問(wèn)題,但是,只需切換到Oracle JDK就可以解決問(wèn)題;
  4. 在響應(yīng)性和JVM性能方面,Oracle JDK與OpenJDK相比提供了更好的 性能;
  5. Oracle JDK不會(huì)為即將發(fā)布的版本提供長(zhǎng)期支持,用戶每次都必須通過(guò) 更新到最新版本獲得支持來(lái)獲取最新版本;
  6. Oracle JDK根據(jù)二進(jìn)制代碼許可協(xié)議獲得許可,而OpenJDK根據(jù)GPL v2許可獲得許可。

二.基礎(chǔ)語(yǔ)法

1.數(shù)據(jù)類(lèi)型

Java有哪些數(shù)據(jù)類(lèi)型

定義:Java語(yǔ)言是強(qiáng)類(lèi)型語(yǔ)言,對(duì)于每一種數(shù)據(jù)都定義了明確的具體的數(shù)據(jù)類(lèi) 型,在內(nèi)存中分配了不同大小的內(nèi)存空間。

分類(lèi)

基本數(shù)據(jù)類(lèi)型

  • ? 數(shù)值型
    ? 整數(shù)類(lèi)型(byte,short,int,long)
    ? 浮點(diǎn)類(lèi)型(float,double)
  • ? 字符型(char)
  • ? 布爾型(boolean)

引用數(shù)據(jù)類(lèi)型

  • ? 類(lèi)(class)
  • ? 接口(interface)
  • ? 數(shù)組([])

Java基本數(shù)據(jù)類(lèi)型圖
2023面試八股文 ——Java基礎(chǔ)知識(shí),面試,面試,java,python

switch 是否能作用在 byte 上,是否能作用在 long 上,是否 能作用在 String 上

在 Java 5 以前,switch(expr)中,expr 只能是 byte、short、char、int。從 Java5 開(kāi)始,Java 中引入了枚舉類(lèi)型,expr 也可以是 enum 類(lèi)型,從 Java 7 開(kāi)始,expr 還可以是字符串(String),但是長(zhǎng)整型(long)在目前所有的版 本中都是不可以的

用最有效率的方法計(jì)算 2 乘以 8

2 << 3(左移 3 位相當(dāng)于乘以 2 的 3 次方,右移 3 位相當(dāng)于除以 2 的 3 次 方)。

Math.round(11.5) 等于多少?Math.round(-11.5) 等于多少

Math.round(11.5)的返回值是 12,Math.round(-11.5)的返回值是-11。四舍 五入的原理是在參數(shù)上加 0.5 然后進(jìn)行下取整。

loat f=3.4;是否正確

不正確。3.4 是雙精度數(shù),將雙精度型(double)賦值給浮點(diǎn)型(float)屬于 下轉(zhuǎn)型(down-casting,也稱(chēng)為窄化)會(huì)造成精度損失,因此需要強(qiáng)制類(lèi)型轉(zhuǎn) 換float f =(float)3.4; 或者寫(xiě)成 float f =3.4F;。

short s1 = 1; s1 = s1 + 1;有錯(cuò)嗎?short s1 = 1; s1 += 1;有錯(cuò)嗎

對(duì)于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 類(lèi)型,因此 s1+1 運(yùn)算結(jié)果也是 int型,需要強(qiáng)制轉(zhuǎn)換類(lèi)型才能賦值給 short 型。 而 short s1 = 1; s1 += 1;可以正確編譯,因?yàn)?s1+= 1;相當(dāng)于 s1 = (short(s1 + 1);其中有隱含的強(qiáng)制類(lèi)型轉(zhuǎn)換。

2.編碼

Java語(yǔ)言采用何種編碼方案?有何特點(diǎn)?

Java語(yǔ)言采用Unicode編碼標(biāo)準(zhǔn),Unicode(標(biāo)準(zhǔn)碼),它為每個(gè)字符制訂了一 個(gè)唯一的數(shù)值,因此在任何的語(yǔ)言,平臺(tái),程序都可以放心的使用。

3. 注釋

什么Java注釋

定義:用于解釋說(shuō)明程序的文字
分類(lèi)
  • 單行注釋 格式: // 注釋文字
  • 多行注釋 格式: /* 注釋文字 */
  • 文檔注釋 格式:/** 注釋文字 */
作用

在程序中,尤其是復(fù)雜的程序中,適當(dāng)?shù)丶尤胱⑨尶梢栽黾映绦虻目勺x性,有利 于程序的修改、調(diào)試和交流。注釋的內(nèi)容在程序編譯的時(shí)候會(huì)被忽視,不會(huì)產(chǎn)生 目標(biāo)代碼,注釋的部分不會(huì)對(duì)程序的執(zhí)行結(jié)果產(chǎn)生任何影響。 注意事項(xiàng):多行和文檔注釋都不能嵌套使用。 訪問(wèn)修飾符

訪問(wèn)修飾符 public,private,protected,以及不寫(xiě)(默認(rèn))時(shí)的 區(qū)別

定義:Java中,可以使用訪問(wèn)修飾符來(lái)保護(hù)對(duì)類(lèi)、變量、方法和構(gòu)造方法的訪 問(wèn)。Java 支持 4 種不同的訪問(wèn)權(quán)限。

分類(lèi)

  • private : 在同一類(lèi)內(nèi)可見(jiàn)。使用對(duì)象:變量、方法。 注意:不能修飾類(lèi)(外部 類(lèi))
  • default (即缺省,什么也不寫(xiě),不使用任何關(guān)鍵字): 在同一包內(nèi)可見(jiàn),不使用 任何修飾符。使用對(duì)象:類(lèi)、接口、變量、方法。
  • protected : 對(duì)同一包內(nèi)的類(lèi)和所有子類(lèi)可見(jiàn)。使用對(duì)象:變量、方法。 注意: 不能修飾類(lèi)(外部類(lèi))。
  • public : 對(duì)所有類(lèi)可見(jiàn)。使用對(duì)象:類(lèi)、接口、變量、方法

訪問(wèn)修飾符圖

2023面試八股文 ——Java基礎(chǔ)知識(shí),面試,面試,java,python

4.運(yùn)算符

&和&&的區(qū)別

&運(yùn)算符有兩種用法:(1)按位與;(2)邏輯與。

&&運(yùn)算符是短路與運(yùn)算。邏輯與跟短路與的差別是非常巨大的,雖然二者都要 求運(yùn)算符左右兩端的布爾值都是true 整個(gè)表達(dá)式的值才是 true。&&之所以稱(chēng)
為短路運(yùn)算,是因?yàn)槿绻?amp;&左邊的表達(dá)式的值是 false,右邊的表達(dá)式會(huì)被直 接短路掉,不會(huì)進(jìn)行運(yùn)算。

注意:邏輯或運(yùn)算符(|)和短路或運(yùn)算符(||)的差別也是如此。

5.關(guān)鍵字

Java 有沒(méi)有 goto

goto 是 Java 中的保留字,在目前版本的 Java 中沒(méi)有使用。

final 有什么用?

用于修飾類(lèi)、屬性和方法;

  • 被final修飾的類(lèi)不可以被繼承
  • 被final修飾的方法不可以被重寫(xiě)
  • 被final修飾的變量不可以被改變,被final修飾不可變的是變量的引用,而不是引用指向的內(nèi)容,引用指向的內(nèi)容是可以改變的

final finally finalize區(qū)別

  • final可以修飾類(lèi)、變量、方法,修飾類(lèi)表示該類(lèi)不能被繼承、修飾方法表示該方法不能被重寫(xiě)、修飾變量表示該變量是一個(gè)常量不能被重新賦值。
  • finally一般作用在try-catch代碼塊中,在處理異常的時(shí)候,通常我們將一定要執(zhí)行的代碼方法finally代碼塊中,表示不管是否出現(xiàn)異常,該代碼塊都會(huì)執(zhí)行,一般用來(lái)存放一些關(guān)閉資源的代碼。
  • finalize是一個(gè)方法,屬于Object類(lèi)的一個(gè)方法,而Object類(lèi)是所有類(lèi)的父類(lèi),該方法一般由垃圾回收器來(lái)調(diào)用,當(dāng)我們調(diào)用System.gc() 方法的時(shí)候,由垃圾回收器調(diào)用finalize(),回收垃圾,一個(gè)對(duì)象是否可回收的最后判斷。

this關(guān)鍵字的用法

this是自身的一個(gè)對(duì)象,代表對(duì)象本身,可以理解為:指向?qū)ο蟊旧淼囊粋€(gè)指
針。

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

1.普通的直接引用,this相當(dāng)于是指向當(dāng)前對(duì)象本身。

2.形參與成員名字重名,用this來(lái)區(qū)分:

1 public Person(String name, int age) {
2 this.name = name;
3 this.age = age;
4 }

3.引用本類(lèi)的構(gòu)造函數(shù)

1 class Person{
2 private String name;
3 private int age;
4
5 public Person() {
6 }
7
8 public Person(String name) {
9 this.name = name;
10 }
11 public Person(String name, int age) {
12 this(name);
13 this.age = age;
14 }
15 }

super關(guān)鍵字的用法

super可以理解為是指向自己超(父)類(lèi)對(duì)象的一個(gè)指針,而這個(gè)超類(lèi)指的是離
自己最近的一個(gè)父類(lèi)。

super也有三種用法:

1.普通的直接引用
與this類(lèi)似,super相當(dāng)于是指向當(dāng)前對(duì)象的父類(lèi)的引用,這樣就可以用
super.xxx來(lái)引用父類(lèi)的成員。
2.子類(lèi)中的成員變量或方法與父類(lèi)中的成員變量或方法同名時(shí),用super進(jìn)行區(qū)

1 class Person{
2 protected String name;
3
4 public Person(String name) {
5 this.name = name;
6 }
7
8 }
9
10 class Student extends Person{
11 private String name;
12
13 public Student(String name, String name1) {
14 super(name);
15 this.name = name1;
16 }
17
18 public void getInfo(){
19 System.out.println(this.name); //Child
20 System.out.println(super.name); //Father
21 }
22
23 }
24
25 public class Test {
26 public static void main(String[] args) {
27 Student s1 = new Student("Father","Child");
28 s1.getInfo();
29
30 }
31 }

3.引用父類(lèi)構(gòu)造函數(shù)

super(參數(shù)):調(diào)用父類(lèi)中的某一個(gè)構(gòu)造函數(shù)(應(yīng)該為構(gòu)造函數(shù)中的第一條語(yǔ)句)。

this(參數(shù)):調(diào)用本類(lèi)中另一種形式的構(gòu)造函數(shù)(應(yīng)該為構(gòu)造函數(shù)中的第一條語(yǔ)句)。

this與super的區(qū)別

  • super: 它引用當(dāng)前對(duì)象的直接父類(lèi)中的成員(用來(lái)訪問(wèn)直接父類(lèi)中被隱藏的父類(lèi)中成員數(shù)據(jù)或函數(shù),基類(lèi)與派生類(lèi)中有相同成員定義時(shí)如:super.變量名 super.成員函數(shù)據(jù)名(實(shí)參)
  • this:它代表當(dāng)前對(duì)象名(在程序中易產(chǎn)生二義性之處,應(yīng)使用this來(lái)指明當(dāng)前對(duì)象;如果函數(shù)的形參與類(lèi)中的成員數(shù)據(jù)同名,這時(shí)需用this來(lái)指明成員變量名)
  • super()和this()類(lèi)似,區(qū)別是,super()在子類(lèi)中調(diào)用父類(lèi)的構(gòu)造方法,this()在本類(lèi)內(nèi)調(diào)用本類(lèi)的其它構(gòu)造方法。
  • super()和this()均需放在構(gòu)造方法內(nèi)第一行。
  • 盡管可以用this調(diào)用一個(gè)構(gòu)造器,但卻不能調(diào)用兩個(gè)。
  • this和super不能同時(shí)出現(xiàn)在一個(gè)構(gòu)造函數(shù)里面,因?yàn)閠his必然會(huì)調(diào)用其它的構(gòu)造函數(shù),其它的構(gòu)造函數(shù)必然也會(huì)有super語(yǔ)句的存在,所以在同一個(gè)構(gòu)造函數(shù)里面有相同的語(yǔ)句,就失去了語(yǔ)句的意義,編譯器也不會(huì)通過(guò)。
  • this()和super()都指的是對(duì)象,所以,均不可以在static環(huán)境中使用。包括:
    static變量,static方法,static語(yǔ)句塊。
  • 從本質(zhì)上講,this是一個(gè)指向本對(duì)象的指針, 然而super是一個(gè)Java關(guān)鍵字。

static存在的主要意義

static的主要意義是在于創(chuàng)建獨(dú)立于具體對(duì)象的域變量或者方法。以致于即使沒(méi)有創(chuàng)建對(duì)象,也能使用屬性和調(diào)用方法!

static關(guān)鍵字還有一個(gè)比較關(guān)鍵的作用就是 用來(lái)形成靜態(tài)代碼塊以優(yōu)化程序性能。static塊可以置于類(lèi)中的任何地方,類(lèi)中可以有多個(gè)static塊。在類(lèi)初次被加載的時(shí)候,會(huì)按照static塊的順序來(lái)執(zhí)行每個(gè)static塊,并且只會(huì)執(zhí)行一次。為什么說(shuō)static塊可以用來(lái)優(yōu)化程序性能,是因?yàn)樗奶匦?只會(huì)在類(lèi)加載的時(shí)候
執(zhí)行一次。因此,很多時(shí)候會(huì)將一些只需要進(jìn)行一次的初始化操作都放在static代碼塊中進(jìn)行。

static的獨(dú)特之處

1、被static修飾的變量或者方法是獨(dú)立于該類(lèi)的任何對(duì)象,也就是說(shuō),這些變量和方法不屬于任何一個(gè)實(shí)例對(duì)象,而是被類(lèi)的實(shí)例對(duì)象所共享。

怎么理解 “被類(lèi)的實(shí)例對(duì)象所共享” 這句話呢?就是說(shuō),一個(gè)類(lèi)的靜態(tài)成員,它是屬于大伙的【大伙指的是這個(gè)類(lèi)的多個(gè)對(duì)象實(shí)例,我們都知道一個(gè)類(lèi)可以創(chuàng)建多個(gè)實(shí)例!】,所有的類(lèi)對(duì)象共享的,不像成員變量是自個(gè)的【自個(gè)指的是這個(gè)類(lèi)的單個(gè)實(shí)例對(duì)象】…我覺(jué)得我已經(jīng)講的很通俗了,你明白了咩?

2、在該類(lèi)被第一次加載的時(shí)候,就會(huì)去加載被static修飾的部分,而且只在類(lèi)第一次使用時(shí)加載并進(jìn)行初始化,注意這是第一次用就要初始化,后面根據(jù)需要是可以再次賦值的。

3、static變量值在類(lèi)加載的時(shí)候分配空間,以后創(chuàng)建類(lèi)對(duì)象的時(shí)候不會(huì)重新分配。賦值的話,是可以任意賦值的!

4、被static修飾的變量或者方法是優(yōu)先于對(duì)象存在的,也就是說(shuō)當(dāng)一個(gè)類(lèi)加載完畢之后,即便沒(méi)有創(chuàng)建對(duì)象,也可以去訪問(wèn)。

static應(yīng)用場(chǎng)景

因?yàn)閟tatic是被類(lèi)的實(shí)例對(duì)象所共享,因此如果某個(gè)成員變量是被所有對(duì)象所共享的,那么這個(gè)成員變量就應(yīng)該定義為靜態(tài)變量。

因此比較常見(jiàn)的static應(yīng)用場(chǎng)景有:

1、修飾成員變量
2、修飾成員方法
3、靜態(tài)代碼塊
4、修飾類(lèi)【只能修飾內(nèi)部類(lèi)也就是靜態(tài)內(nèi)部類(lèi)】
5、靜態(tài)導(dǎo)包

static注意事項(xiàng)

1、靜態(tài)只能訪問(wèn)靜態(tài)。 2、非靜態(tài)既可以訪問(wèn)非靜態(tài)的,也可以訪問(wèn)靜態(tài)的。

6.流程控制語(yǔ)句

break ,continue ,return 的區(qū)別及作用

break 跳出總上一層循環(huán),不再執(zhí)行循環(huán)(結(jié)束當(dāng)前的循環(huán)體)continue 跳出本次循環(huán),繼續(xù)執(zhí)行下次循環(huán)(結(jié)束正在執(zhí)行的循環(huán) 進(jìn)入下一個(gè)循環(huán)條件)

return 程序返回,不再執(zhí)行下面的代碼(結(jié)束當(dāng)前的方法 直接返回)

在 Java 中,如何跳出當(dāng)前的多重嵌套循環(huán)

在Java中,要想跳出多重循環(huán),可以在外面的循環(huán)語(yǔ)句前定義一個(gè)標(biāo)號(hào),然后在里層循環(huán)體的代碼中使用帶有標(biāo)號(hào)的break 語(yǔ)句,即可跳出外層循環(huán)。例如:

1 public static void main(String[] args) {
2 ok:
3 for (int i = 0; i < 10; i++) {
4 for (int j = 0; j < 10; j++) {
5 System.out.println("i=" + i + ",j=" + j);
6 if (j == 5) {
7 break ok;
8 }
9
10 }
11 }
12 }

三.面向?qū)ο?/h2>

1.面向?qū)ο蟾攀?/h3>

面向?qū)ο蠛兔嫦蜻^(guò)程的區(qū)別

面向過(guò)程:

優(yōu)點(diǎn):性能比面向?qū)ο蟾?,因?yàn)轭?lèi)調(diào)用時(shí)需要實(shí)例化,開(kāi)銷(xiāo)比較大,比較消耗資源;比如單片機(jī)、嵌入式開(kāi)發(fā)、Linux/Unix等一般采用面向過(guò)程開(kāi)發(fā),能是最重要的因素。
缺點(diǎn):沒(méi)有面向?qū)ο笠拙S護(hù)、易復(fù)用、易擴(kuò)展

面向?qū)ο螅?/h5>

優(yōu)點(diǎn):易維護(hù)、易復(fù)用、易擴(kuò)展,由于面向?qū)ο笥蟹庋b、繼承、多態(tài)性的特性,可以設(shè)計(jì)出低耦合的系統(tǒng),使系統(tǒng)更加靈活、更加易于維護(hù)

缺點(diǎn):性能比面向過(guò)程低
面向過(guò)程是具體化的,流程化的,解決一個(gè)問(wèn)題,你需要一步一步的分析,一步
一步的實(shí)現(xiàn)。

面向?qū)ο笫悄P突?,你只需抽象出一個(gè)類(lèi),這是一個(gè)封閉的盒子,在這里你擁有數(shù)據(jù)也擁有解決問(wèn)題的方法。需要什么功能直接使用就可以了,不必去一步一步的實(shí)現(xiàn),至于這個(gè)功能是如何實(shí)現(xiàn)的,管我們什么事?我們會(huì)用就可以了。

面向?qū)ο蟮牡讓悠鋵?shí)還是面向過(guò)程,把面向過(guò)程抽象成類(lèi),然后封裝,方便我們使用的就是面向?qū)ο罅恕?/p>

2.面向?qū)ο笕筇匦?/h3>

面向?qū)ο蟮奶卣饔心男┓矫?/h4>

**面向?qū)ο蟮奶卣髦饕幸韵聨讉€(gè)方面: **

**抽象:**抽象是將一類(lèi)對(duì)象的共同特征總結(jié)出來(lái)構(gòu)造類(lèi)的過(guò)程,包括數(shù)據(jù)抽象和行 為抽象兩方面。抽象只關(guān)注對(duì)象有哪些屬性和行為,并不關(guān)注這些行為的細(xì)節(jié)是 什么。

  • 封裝 : 封裝把一個(gè)對(duì)象的屬性私有化,同時(shí)提供一些可以被外界訪問(wèn)的屬性的方法,如 果屬性不想被外界訪問(wèn),我們大可不必提供方法給外界訪問(wèn)。但是如果一個(gè)類(lèi)沒(méi) 有提供給外界訪問(wèn)的方法,那么這個(gè)類(lèi)也沒(méi)有什么意義了。

  • 繼承 : 繼承是使用已存在的類(lèi)的定義作為基礎(chǔ)建立新類(lèi)的技術(shù),新類(lèi)的定義可以增加新 的數(shù)據(jù)或新的功能,也可以用父類(lèi)的功能,但不能選擇性地繼承父類(lèi)。通過(guò)使用 繼承我們能夠非常方便地復(fù)用以前的代碼。

    ? 關(guān)于繼承如下 3 點(diǎn)請(qǐng)記?。?/p>

    ? 1.子類(lèi)擁有父類(lèi)非 private 的屬性和方法。

    ? 2.子類(lèi)可以擁有自己屬性和方法,即子類(lèi)可以對(duì)父類(lèi)進(jìn)行擴(kuò)展。

    ? 3.子類(lèi)可以用自己的方式實(shí)現(xiàn)父類(lèi)的方法。

  • 多態(tài) : 所謂多態(tài)就是指程序中定義的引用變量所指向的具體類(lèi)型和通過(guò)該引用變量發(fā)出 的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量到 底會(huì)指向哪個(gè)類(lèi)的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類(lèi)中實(shí)現(xiàn)的 方法,必須在由程序運(yùn)行期間才能決定。

    在Java中有兩種形式可以實(shí)現(xiàn)多態(tài):繼承(多個(gè)子類(lèi)對(duì)同一方法的重寫(xiě))和接口 (實(shí)現(xiàn)接口并覆蓋接口中同一方法)。

其中Java 面向?qū)ο缶幊倘筇匦裕悍庋b 繼承 多態(tài)

封裝:隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外提供公共訪問(wèn)方式,將變化隔離,便 于使用,提高復(fù)用性和安全性。

繼承:繼承是使用已存在的類(lèi)的定義作為基礎(chǔ)建立新類(lèi)的技術(shù),新類(lèi)的定義可以 增加新的數(shù)據(jù)或新的功能,也可以用父類(lèi)的功能,但不能選擇性地繼承父類(lèi)。通 過(guò)使用繼承可以提高代碼復(fù)用性。繼承是多態(tài)的前提。

**關(guān)于繼承如下 3 點(diǎn)請(qǐng)記住: **

  1. 子類(lèi)擁有父類(lèi)非 private 的屬性和方法。
  2. 子類(lèi)可以擁有自己屬性和方法,即子類(lèi)可以對(duì)父類(lèi)進(jìn)行擴(kuò)展。
  3. 子類(lèi)可以用自己的方式實(shí)現(xiàn)父類(lèi)的方法。

多態(tài)性:父類(lèi)或接口定義的引用變量可以指向子類(lèi)或具體實(shí)現(xiàn)類(lèi)的實(shí)例對(duì)象。提 高了程序的拓展性。

在Java中有兩種形式可以實(shí)現(xiàn)多態(tài):繼承(多個(gè)子類(lèi)對(duì)同一方法的重寫(xiě))和接口 (實(shí)現(xiàn)接口并覆蓋接口中同一方法)。

方法重載(overload)實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性(也稱(chēng)為前綁定),而方法重 寫(xiě)(override)實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性(也稱(chēng)為后綁定)。

一個(gè)引用變量到底會(huì)指向哪個(gè)類(lèi)的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是 哪個(gè)類(lèi)中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定。運(yùn)行時(shí)的多態(tài)是面向?qū)?象精髓的東西,要實(shí)現(xiàn)多態(tài)需要做兩件事:

  • 方法重寫(xiě)(子類(lèi)繼承父類(lèi)并重寫(xiě)父類(lèi)中已有的或抽象的方法);
  • 對(duì)象造型(用父類(lèi)型引用子類(lèi)型對(duì)象,這樣同樣的引用調(diào)用同樣的方法就會(huì)根據(jù) 子類(lèi)對(duì)象的不同而表現(xiàn)出不同的行為)。

什么是多態(tài)機(jī)制?Java語(yǔ)言是如何實(shí)現(xiàn)多態(tài)的?

所謂多態(tài)就是指程序中定義的引用變量所指向的具體類(lèi)型和通過(guò)該引用變量發(fā)出 的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量倒 底會(huì)指向哪個(gè)類(lèi)的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類(lèi)中實(shí)現(xiàn)的 方法,必須在由程序運(yùn)行期間才能決定。因?yàn)樵诔绦蜻\(yùn)行時(shí)才確定具體的類(lèi),這 樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類(lèi)實(shí)現(xiàn)上,從而 導(dǎo)致該引用調(diào)用的具體方法隨之改變,即不修改程序代碼就可以改變程序運(yùn)行時(shí) 所綁定的具體代碼,讓程序可以選擇多個(gè)運(yùn)行狀態(tài),這就是多態(tài)性。 多態(tài)分為編譯時(shí)多態(tài)和運(yùn)行時(shí)多態(tài)。其中編輯時(shí)多態(tài)是靜態(tài)的,主要是指方法的 重載,它是根據(jù)參數(shù)列表的不同來(lái)區(qū)分不同的函數(shù),通過(guò)編輯之后會(huì)變成兩個(gè)不 同的函數(shù),在運(yùn)行時(shí)談不上多態(tài)。而運(yùn)行時(shí)多態(tài)是動(dòng)態(tài)的,它是通過(guò)動(dòng)態(tài)綁定來(lái) 實(shí)現(xiàn)的,也就是我們所說(shuō)的多態(tài)性

多態(tài)的實(shí)現(xiàn)

Java實(shí)現(xiàn)多態(tài)有三個(gè)必要條件:繼承、重寫(xiě)、向上轉(zhuǎn)型。

繼承:在多態(tài)中必須存在有繼承關(guān)系的子類(lèi)和父類(lèi)。

重寫(xiě):子類(lèi)對(duì)父類(lèi)中某些方法進(jìn)行重新定義,在調(diào)用這些方法時(shí)就會(huì)調(diào)用子類(lèi)的 方法。

向上轉(zhuǎn)型:在多態(tài)中需要將子類(lèi)的引用賦給父類(lèi)對(duì)象,只有這樣該引用才能夠具 備技能調(diào)用父類(lèi)的方法和子類(lèi)的方法。

只有滿足了上述三個(gè)條件,我們才能夠在同一個(gè)繼承結(jié)構(gòu)中使用統(tǒng)一的邏輯實(shí)現(xiàn) 代碼處理不同的對(duì)象,從而達(dá)到執(zhí)行不同的行為。

對(duì)于Java而言,它多態(tài)的實(shí)現(xiàn)機(jī)制遵循一個(gè)原則:當(dāng)超類(lèi)對(duì)象引用變量引用子類(lèi) 對(duì)象時(shí),被引用對(duì)象的類(lèi)型而不是引用變量的類(lèi)型決定了調(diào)用誰(shuí)的成員方法,但 是這個(gè)被調(diào)用的方法必須是在超類(lèi)中定義過(guò)的,也就是說(shuō)被子類(lèi)覆蓋的方法。

面向?qū)ο笪宕蠡驹瓌t是什么(可選)

  • 單一職責(zé)原則SRP(Single Responsibility Principle)類(lèi)的功能要單一,不能包羅萬(wàn)象,跟雜貨鋪似的。
    開(kāi)放封閉原則OCP(Open-Close Principle)
  • 一個(gè)模塊對(duì)于拓展是開(kāi)放的,對(duì)于修改是封閉的,想要增加功能熱烈歡迎,想要修改,哼,
    一萬(wàn)個(gè)不樂(lè)意。
  • 里式替換原則LSP(the Liskov Substitution Principle LSP)子類(lèi)可以替換父類(lèi)出現(xiàn)在父類(lèi)能夠出現(xiàn)的任何地方。比如你能代表你爸去你姥姥家干活。哈哈~~
  • 依賴(lài)倒置原則DIP(the Dependency Inversion Principle DIP)高層次的模塊不應(yīng)該依賴(lài)于低層次的模塊,他們都應(yīng)該依賴(lài)于抽象。抽象不應(yīng)該依賴(lài)于具體實(shí)現(xiàn),具體實(shí)現(xiàn)應(yīng)該依賴(lài)于抽象。就是你出國(guó)要說(shuō)你是中國(guó)人,而不能說(shuō)你是哪個(gè)村子的。比如說(shuō)中國(guó)人是抽象的,下面有具體的xx省,xx市,xx縣。你要依賴(lài)的抽象是中國(guó)人,而不是你是xx村的。
  • 接口分離原則ISP(the Interface Segregation Principle ISP)
    設(shè)計(jì)時(shí)采用多個(gè)與特定客戶類(lèi)有關(guān)的接口比采用一個(gè)通用的接口要好。就比如一個(gè)手機(jī)擁有
    打電話,看視頻,玩游戲等功能,把這幾個(gè)功能拆分成不同的接口,比在一個(gè)接口里要好的
    多。

四.類(lèi)與接口

抽象類(lèi)和接口的對(duì)比

抽象類(lèi)是用來(lái)捕捉子類(lèi)的通用特性的。接口是抽象方法的集合。
從設(shè)計(jì)層面來(lái)說(shuō),抽象類(lèi)是對(duì)類(lèi)的抽象,是一種模板設(shè)計(jì),接口是行為的抽象,是一種行為的規(guī)范。

相同點(diǎn)

  • 接口和抽象類(lèi)都不能實(shí)例化
  • 都位于繼承的頂端,用于被其他實(shí)現(xiàn)或繼承
  • 都包含抽象方法,其子類(lèi)都必須覆寫(xiě)這些抽象方法

不同點(diǎn)

參數(shù) 抽象類(lèi) 接口
聲明 抽象類(lèi)使用abstract關(guān)鍵字聲明 接口使用interface關(guān)鍵字聲明
實(shí)現(xiàn) 子類(lèi)使用extends關(guān)鍵字來(lái)繼承抽象類(lèi)。如果子類(lèi)不是抽象類(lèi)的話,它需要提供抽象類(lèi)中所有聲明的方法的實(shí)現(xiàn) 子類(lèi)使用implements關(guān)鍵字來(lái)實(shí)現(xiàn)接口。它需要提供接口中所有聲明的方法的實(shí)現(xiàn)
構(gòu)造器 抽象類(lèi)可以有構(gòu)造器 接口不能有構(gòu)造器
訪問(wèn)修飾符 抽象類(lèi)中的方法可以是任意訪問(wèn)修飾符 接口方法默認(rèn)修飾符是public。并且不允許定義為 private 或者 protected
多繼承 一個(gè)類(lèi)最多只能繼承一個(gè)抽象類(lèi) 一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口
字段聲明 抽象類(lèi)的字段聲明可以是任意的 接口的字段默認(rèn)都是 static 和 final 的

備注:Java8中接口中引入默認(rèn)方法和靜態(tài)方法,以此來(lái)減少抽象類(lèi)和接口之間 的差異。

現(xiàn)在,我們可以為接口提供默認(rèn)實(shí)現(xiàn)的方法了,并且不用強(qiáng)制子類(lèi)來(lái)實(shí)現(xiàn)它。 接口和抽象類(lèi)各有優(yōu)缺點(diǎn),在接口和抽象類(lèi)的選擇上,必須遵守這樣一個(gè)原則:

  • 行為模型應(yīng)該總是通過(guò)接口而不是抽象類(lèi)定義,所以通常是優(yōu)先選用接口,盡量 少用抽象類(lèi)。
  • 選擇抽象類(lèi)的時(shí)候通常是如下情況:需要定義子類(lèi)的行為,又要為子類(lèi)提供通用 的功能。

普通類(lèi)和抽象類(lèi)有哪些區(qū)別?

  • 普通類(lèi)不能包含抽象方法,抽象類(lèi)可以包含抽象方法。
  • 抽象類(lèi)不能直接實(shí)例化,普通類(lèi)可以直接實(shí)例化。

抽象類(lèi)能使用 final 修飾嗎?

不能,定義抽象類(lèi)就是讓其他類(lèi)繼承的,如果定義為 final 該類(lèi)就不能被繼承, 這樣彼此就會(huì)產(chǎn)生矛盾,所以 final 不能修飾抽象類(lèi)

創(chuàng)建一個(gè)對(duì)象用什么關(guān)鍵字?對(duì)象實(shí)例與對(duì)象引用有何不同?

new關(guān)鍵字,new創(chuàng)建對(duì)象實(shí)例(對(duì)象實(shí)例在堆內(nèi)存中),對(duì)象引用指向?qū)ο髮?shí) 例(對(duì)象引用存放在棧內(nèi)存中)。一個(gè)對(duì)象引用可以指向0個(gè)或1個(gè)對(duì)象(一根 繩子可以不系氣球,也可以系一個(gè)氣球);一個(gè)對(duì)象可以有n個(gè)引用指向它(可以 用n條繩子系住一個(gè)氣球)

五.變量與方法

成員變量與局部變量的區(qū)別有哪些

變量:在程序執(zhí)行的過(guò)程中,在某個(gè)范圍內(nèi)其值可以發(fā)生改變的量。從本質(zhì)上 講,變量其實(shí)是內(nèi)存中的一小塊區(qū)域 成員變量:方法外部,類(lèi)內(nèi)部定義的變量 局部變量:類(lèi)的方法中的變量。 成員變量和局部變量的區(qū)別

作用域

成員變量:針對(duì)整個(gè)類(lèi)有效。

局部變量:只在某個(gè)范圍內(nèi)有效。(一般指的就是方法,語(yǔ)句體內(nèi))

存儲(chǔ)位置

成員變量:隨著對(duì)象的創(chuàng)建而存在,隨著對(duì)象的消失而消失,存儲(chǔ)在堆內(nèi)存中。

局部變量:在方法被調(diào)用,或者語(yǔ)句被執(zhí)行的時(shí)候存在,存儲(chǔ)在棧內(nèi)存中。當(dāng)方法調(diào)用完,或者語(yǔ)句結(jié)束后,就自動(dòng)釋放。

生命周期

成員變量:隨著對(duì)象的創(chuàng)建而存在,隨著對(duì)象的消失而消失

局部變量:當(dāng)方法調(diào)用完,或者語(yǔ)句結(jié)束后,就自動(dòng)釋放。

初始值

成員變量:有默認(rèn)初始值。

局部變量:沒(méi)有默認(rèn)初始值,使用前必須賦值。

使用原則

在使用變量時(shí)需要遵循的原則為:就近原則 首先在局部范圍找,有就使用;接著在成員位置找。

在Java中定義一個(gè)不做事且沒(méi)有參數(shù)的構(gòu)造方法的作用

Java程序在執(zhí)行子類(lèi)的構(gòu)造方法之前,如果沒(méi)有用super()來(lái)調(diào)用父類(lèi)特定的構(gòu) 造方法,則會(huì)調(diào)用父類(lèi)中“沒(méi)有參數(shù)的構(gòu)造方法”。因此,如果父類(lèi)中只定義了 有參數(shù)的構(gòu)造方法,而在子類(lèi)的構(gòu)造方法中又沒(méi)有用super()來(lái)調(diào)用父類(lèi)中特定 的構(gòu)造方法,則編譯時(shí)將發(fā)生錯(cuò)誤,因?yàn)镴ava程序在父類(lèi)中找不到?jīng)]有參數(shù)的構(gòu) 造方法可供執(zhí)行。解決辦法是在父類(lèi)里加上一個(gè)不做事且沒(méi)有參數(shù)的構(gòu)造方法。

在調(diào)用子類(lèi)構(gòu)造方法之前會(huì)先調(diào)用父類(lèi)沒(méi)有參數(shù)的構(gòu)造方法,其 目的是?

幫助子類(lèi)做初始化工作。

一個(gè)類(lèi)的構(gòu)造方法的作用是什么?若一個(gè)類(lèi)沒(méi)有聲明構(gòu)造方法, 改程序能正確執(zhí)行嗎?為什么?

主要作用是完成對(duì)類(lèi)對(duì)象的初始化工作。可以執(zhí)行。因?yàn)橐粋€(gè)類(lèi)即使沒(méi)有聲明構(gòu) 造方法也會(huì)有默認(rèn)的不帶參數(shù)的構(gòu)造方法。

構(gòu)造方法有哪些特性?

名字與類(lèi)名相同;

沒(méi)有返回值,但不能用void聲明構(gòu)造函數(shù);

生成類(lèi)的對(duì)象時(shí)自動(dòng)執(zhí)行,無(wú)需調(diào)用。

靜態(tài)變量和實(shí)例變量區(qū)別

靜態(tài)變量: 靜態(tài)變量由于不屬于任何實(shí)例對(duì)象,屬于類(lèi)的,所以在內(nèi)存中只會(huì) 有一份,在類(lèi)的加載過(guò)程中,JVM只為靜態(tài)變量分配一次內(nèi)存空間。

實(shí)例變量: 每次創(chuàng)建對(duì)象,都會(huì)為每個(gè)對(duì)象分配成員變量?jī)?nèi)存空間,實(shí)例變量 是屬于實(shí)例對(duì)象的,在內(nèi)存中,創(chuàng)建幾次對(duì)象,就有幾份成員變量。

靜態(tài)變量與普通變量區(qū)別

static變量也稱(chēng)作靜態(tài)變量,靜態(tài)變量和非靜態(tài)變量的區(qū)別是:靜態(tài)變量被所有 的對(duì)象所共享,在內(nèi)存中只有一個(gè)副本,它當(dāng)且僅當(dāng)在類(lèi)初次加載時(shí)會(huì)被初始 化。而非靜態(tài)變量是對(duì)象所擁有的,在創(chuàng)建對(duì)象的時(shí)候被初始化,存在多個(gè)副 本,各個(gè)對(duì)象擁有的副本互不影響。

還有一點(diǎn)就是static成員變量的初始化順序按照定義的順序進(jìn)行初始化。

靜態(tài)方法和實(shí)例方法有何不同?

靜態(tài)方法和實(shí)例方法的區(qū)別主要體現(xiàn)在兩個(gè)方面:

  1. 在外部調(diào)用靜態(tài)方法時(shí),可以使用"類(lèi)名.方法名"的方式,也可以使 用"對(duì)象名.方法名"的方式。而實(shí)例方法只有后面這種方式。也就是說(shuō),調(diào) 用靜態(tài)方法可以無(wú)需創(chuàng)建對(duì)象。

  2. 靜態(tài)方法在訪問(wèn)本類(lèi)的成員時(shí),只允許訪問(wèn)靜態(tài)成員(即靜態(tài)成員變量 和靜態(tài)方法),而不允許訪問(wèn)實(shí)例成員變量和實(shí)例方法;實(shí)例方法則無(wú)此 限制

在一個(gè)靜態(tài)方法內(nèi)調(diào)用一個(gè)非靜態(tài)成員為什么是非法的?

由于靜態(tài)方法可以不通過(guò)對(duì)象進(jìn)行調(diào)用,因此在靜態(tài)方法里,不能調(diào)用其他非靜 態(tài)變量,也不可以訪問(wèn)非靜態(tài)變量成員。

什么是方法的返回值?返回值的作用是什么?

方法的返回值是指我們獲取到的某個(gè)方法體中的代碼執(zhí)行后產(chǎn)生的結(jié)果?。ㄇ疤?是該方法可能產(chǎn)生結(jié)果)。返回值的作用:接收出結(jié)果,使得它可以用于其他的 操作!

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

什么是內(nèi)部類(lèi)?

在Java中,可以將一個(gè)類(lèi)的定義放在另外一個(gè)類(lèi)的定義內(nèi)部,這就是內(nèi)部類(lèi)。內(nèi) 部類(lèi)本身就是類(lèi)的一個(gè)屬性,與其他屬性定義方式一致。

內(nèi)部類(lèi)的分類(lèi)有哪些

內(nèi)部類(lèi)可以分為四種:成員內(nèi)部類(lèi)、局部?jī)?nèi)部類(lèi)、匿名內(nèi)部類(lèi)和靜態(tài)內(nèi)部類(lèi)。

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

定義在類(lèi)內(nèi)部的靜態(tài)類(lèi),就是靜態(tài)內(nèi)部類(lèi)。

1 public class Outer {
2
3 private static int radius = 1;
4
5 static class StaticInner {
6 public void visit() {
7 System.out.println("visit outer static variable:" + radius);
8 }
9 }
10 }

靜態(tài)內(nèi)部類(lèi)可以訪問(wèn)外部類(lèi)所有的靜態(tài)變量,而不可訪問(wèn)外部類(lèi)的非靜態(tài)變量; 靜態(tài)內(nèi)部類(lèi)的創(chuàng)建方式,new 外部類(lèi).靜態(tài)內(nèi)部類(lèi)(),如下:

1 Outer.StaticInner inner = new Outer.StaticInner();
2 inner.visit
成員內(nèi)部類(lèi)

定義在類(lèi)內(nèi)部,成員位置上的非靜態(tài)類(lèi),就是成員內(nèi)部類(lèi)。

1 public class Outer {
2
3 private static int radius = 1;
4 private int count =2;
5
6 class Inner {
7 public void visit() {
8 System.out.println("visit outer static variable:" + radius);
9 System.out.println("visit outer variable:" + count);
10 }
11 }
12 }

成員內(nèi)部類(lèi)可以訪問(wèn)外部類(lèi)所有的變量和方法,包括靜態(tài)和非靜態(tài),私有和公 有。成員內(nèi)部類(lèi)依賴(lài)于外部類(lèi)的實(shí)例,它的創(chuàng)建方式外部類(lèi)實(shí)例.new 內(nèi)部類(lèi)(),如 下:

1 Outer outer = new Outer();
2 Outer.Inner inner = outer.new Inner();
3 inner.visit();
局部?jī)?nèi)部類(lèi)

定義在方法中的內(nèi)部類(lèi),就是局部?jī)?nèi)部類(lèi)

1 public class Outer {
2
3 private int out_a = 1;
4 private static int STATIC_b = 2;
5
6 public void testFunctionClass(){
7 int inner_c =3;
8 class Inner {
9 private void fun(){
10 System.out.println(out_a);
11 System.out.println(STATIC_b);
12 System.out.println(inner_c);
13 }
14 }
15 Inner inner = new Inner();
16 inner.fun();
17 }
18 public static void testStaticFunctionClass(){
19 int d =3;
20 class Inner {
21 private void fun(){
22 // System.out.println(out_a); 編譯錯(cuò)誤,定義在靜態(tài)方法中的局部類(lèi)不可以訪問(wèn)外
部類(lèi)的實(shí)例變量
23 System.out.println(STATIC_b);
24 System.out.println(d);
25 }
26 }
27 Inner inner = new Inner();
28 inner.fun();
29 }
30 }

定義在實(shí)例方法中的局部類(lèi)可以訪問(wèn)外部類(lèi)的所有變量和方法,定義在靜態(tài)方法 中的局部類(lèi)只能訪問(wèn)外部類(lèi)的靜態(tài)變量和方法。局部?jī)?nèi)部類(lèi)的創(chuàng)建方式,在對(duì)應(yīng) 方法內(nèi),new 內(nèi)部類(lèi)(),如下:

1 public static void testStaticFunctionClass(){
2 class Inner {
3 }
4 Inner inner = new Inner();
5 }
匿名內(nèi)部類(lèi)

匿名內(nèi)部類(lèi)就是沒(méi)有名字的內(nèi)部類(lèi),日常開(kāi)發(fā)中使用的比較多。

1 public class Outer {
2
3 private void test(final int i) {
4 new Service() {
5 public void method() {
6 for (int j = 0; j < i; j++) {
7 System.out.println("匿名內(nèi)部類(lèi)" );
8 }
9 }
10 }.method();
11 }
12 }
13 //匿名內(nèi)部類(lèi)必須繼承或?qū)崿F(xiàn)一個(gè)已有的接口
14 interface Service{
15 void method();
16 }

除了沒(méi)有名字,匿名內(nèi)部類(lèi)還有以下特點(diǎn):

  • 匿名內(nèi)部類(lèi)必須繼承一個(gè)抽象類(lèi)或者實(shí)現(xiàn)一個(gè)接口。
  • 匿名內(nèi)部類(lèi)不能定義任何靜態(tài)成員和靜態(tài)方法。
  • 當(dāng)所在的方法的形參需要被匿名內(nèi)部類(lèi)使用時(shí),必須聲明為 final。
  • 匿名內(nèi)部類(lèi)不能是抽象的,它必須要實(shí)現(xiàn)繼承的類(lèi)或者實(shí)現(xiàn)的接口的所有抽象方 法。
匿名內(nèi)部類(lèi)創(chuàng)建方式:
1 new 類(lèi)/接口{
2 //匿名內(nèi)部類(lèi)實(shí)現(xiàn)部分
3 }

內(nèi)部類(lèi)的優(yōu)點(diǎn)

我們?yōu)槭裁匆褂脙?nèi)部類(lèi)呢?因?yàn)樗幸韵聝?yōu)點(diǎn):

  • 一個(gè)內(nèi)部類(lèi)對(duì)象可以訪問(wèn)創(chuàng)建它的外部類(lèi)對(duì)象的內(nèi)容,包括私有數(shù)據(jù)!
  • 內(nèi)部類(lèi)不為同一包的其他類(lèi)所見(jiàn),具有很好的封裝性;
  • 內(nèi)部類(lèi)有效實(shí)現(xiàn)了“多重繼承”,優(yōu)化 java 單繼承的缺陷。
  • 匿名內(nèi)部類(lèi)可以很方便的定義回調(diào)。

內(nèi)部類(lèi)有哪些應(yīng)用場(chǎng)景

  1. 一些多算法場(chǎng)合

  2. 解決一些非面向?qū)ο蟮恼Z(yǔ)句塊。

  3. 適當(dāng)使用內(nèi)部類(lèi),使得代碼更加靈活和富有擴(kuò)展性。

  4. 當(dāng)某個(gè)類(lèi)除了它的外部類(lèi),不再被其他的類(lèi)使用時(shí)。

局部?jī)?nèi)部類(lèi)和匿名內(nèi)部類(lèi)訪問(wèn)局部變量的時(shí)候,為什么變量必須 要加上final?

局部?jī)?nèi)部類(lèi)和匿名內(nèi)部類(lèi)訪問(wèn)局部變量的時(shí)候,為什么變量必須要加上final呢? 它內(nèi)部原理是什么呢?

先看這段代碼:

1 public class Outer {
2
3 void outMethod(){
4 final int a =10;
5 class Inner {
6 void innerMethod(){
7 System.out.println(a);
8 }
9
10 }
11 }
12 }

以上例子,為什么要加final呢?是因?yàn)樯芷诓灰恢拢?局部變量直接存儲(chǔ)在 棧中,當(dāng)方法執(zhí)行結(jié)束后,非final的局部變量就被銷(xiāo)毀。而局部?jī)?nèi)部類(lèi)對(duì)局部變 量的引用依然存在,如果局部?jī)?nèi)部類(lèi)要調(diào)用局部變量時(shí),就會(huì)出錯(cuò)。加了final, 可以確保局部?jī)?nèi)部類(lèi)使用的變量與外層的局部變量區(qū)分開(kāi),解決了這個(gè)問(wèn)題。

內(nèi)部類(lèi)相關(guān),看程序說(shuō)出運(yùn)行結(jié)果

1 public class Outer {
2 private int age = 12;
3
4 class Inner {
5 private int age = 13;
6 public void print() {
7 int age = 14;
8 System.out.println("局部變量:" + age);
9 System.out.println("內(nèi)部類(lèi)變量:" + this.age);
10 System.out.println("外部類(lèi)變量:" + Outer.this.age);
11 }
12 }
13
14 public static void main(String[] args) {
15 Outer.Inner in = new Outer().new Inner();
16 in.print();
17 }
18
19 }

運(yùn)行結(jié)果:

1 局部變量:14
2 內(nèi)部類(lèi)變量:13
3 外部類(lèi)變量:12

七.重寫(xiě)與重載

構(gòu)造器(constructor)是否可被重寫(xiě)(override)

構(gòu)造器不能被繼承,因此不能被重寫(xiě),但可以被重載。

重載(Overload)和重寫(xiě)(Override)的區(qū)別。重載的方法能 否根據(jù)返回類(lèi)型進(jìn)行區(qū)分?

方法的重載和重寫(xiě)都是實(shí)現(xiàn)多態(tài)的方式,區(qū)別在于前者實(shí)現(xiàn)的是編譯時(shí)的多態(tài) 性,而后者實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性。

重載:發(fā)生在同一個(gè)類(lèi)中,方法名相同參數(shù)列表不同(參數(shù)類(lèi)型不同、個(gè)數(shù)不 同、順序不同),與方法返回值和訪問(wèn)修飾符無(wú)關(guān),即重載的方法不能根據(jù)返回 類(lèi)型進(jìn)行區(qū)分

重寫(xiě):發(fā)生在父子類(lèi)中,方法名、參數(shù)列表必須相同,返回值小于等于父類(lèi),拋 出的異常小于等于父類(lèi),訪問(wèn)修飾符大于等于父類(lèi)(里氏代換原則);如果父類(lèi) 方法訪問(wèn)修飾符為private則子類(lèi)中就不是重寫(xiě)。

八.對(duì)象相等判斷

== 和 equals 的區(qū)別是什么

== : 它的作用是判斷兩個(gè)對(duì)象的地址是不是相等。即,判斷兩個(gè)對(duì)象是不是同 一個(gè)對(duì)象。(基本數(shù)據(jù)類(lèi)型 == 比較的是值,引用數(shù)據(jù)類(lèi)型 == 比較的是內(nèi)存地址)

equals() : 它的作用也是判斷兩個(gè)對(duì)象是否相等。但它一般有兩種使用情況: 情況1:類(lèi)沒(méi)有覆蓋 equals() 方法。則通過(guò) equals() 比較該類(lèi)的兩個(gè)對(duì)象時(shí), 等價(jià)于通過(guò)“==”比較這兩個(gè)對(duì)象。

情況2:類(lèi)覆蓋了 equals() 方法。一般,我們都覆蓋 equals() 方法來(lái)兩個(gè)對(duì)象 的內(nèi)容相等;若它們的內(nèi)容相等,則返回 true (即,認(rèn)為這兩個(gè)對(duì)象相等)。

舉個(gè)例子:

1 public class test1 {
2 public static void main(String[] args) {
3 String a = new String("ab"); // a 為一個(gè)引用
4 String b = new String("ab"); // b為另一個(gè)引用,對(duì)象的內(nèi)容一樣
5 String aa = "ab"; // 放在常量池中
6 String bb = "ab"; // 從常量池中查找
7 if (aa == bb) // true
8 System.out.println("aa==bb");
9 if (a == b) // false,非同一對(duì)象
10 System.out.println("a==b");
11 if (a.equals(b)) // true
12 System.out.println("aEQb");
13 if (42 == 42.0) { // true
14 System.out.println("true");
15 }
16 }
17 }

說(shuō)明:

  • String中的equals方法是被重寫(xiě)過(guò)的,因?yàn)閛bject的equals方法是比較的對(duì)象的 內(nèi)存地址,而String的equals方法比較的是對(duì)象的值。
  • 當(dāng)創(chuàng)建String類(lèi)型的對(duì)象時(shí),虛擬機(jī)會(huì)在常量池中查找有沒(méi)有已經(jīng)存在的值和要 創(chuàng)建的值相同的對(duì)象,如果有就把它賦給當(dāng)前引用。如果沒(méi)有就在常量池中重新創(chuàng)建 一個(gè)String對(duì)象。

hashCode 與 equals (重要)

HashSet如何檢查重復(fù)

兩個(gè)對(duì)象的 hashCode() 相同,則 equals() 也一定為 true,對(duì)嗎?

hashCode和equals方法的關(guān)系

面試官可能會(huì)問(wèn)你:“你重寫(xiě)過(guò) hashcode 和 equals 么,為什么重寫(xiě)equals時(shí) 必須重寫(xiě)hashCode方法?”

hashCode()介紹

hashCode() 的作用是獲取哈希碼,也稱(chēng)為散列碼;它實(shí)際上是返回一個(gè)int整 數(shù)。這個(gè)哈希碼的作用是確定該對(duì)象在哈希表中的索引位置。hashCode() 定義 在JDK的Object.java中,這就意味著Java中的任何類(lèi)都包含有hashCode()函數(shù)。

散列表存儲(chǔ)的是鍵值對(duì)(key-value),它的特點(diǎn)是:能根據(jù)“鍵”快速的檢索出 對(duì)應(yīng)的“值”。這其中就利用到了散列碼!(可以快速找到所需要的對(duì)象)

為什么要有 hashCode

我們以“HashSet 如何檢查重復(fù)”為例子來(lái)說(shuō)明為什么要有 hashCode:

當(dāng)你把對(duì)象加入 HashSet 時(shí),HashSet 會(huì)先計(jì)算對(duì)象的 hashcode 值來(lái)判斷對(duì) 象加入的位置,同時(shí)也會(huì)與其他已經(jīng)加入的對(duì)象的 hashcode 值作比較,如果 沒(méi)有相符的hashcode,HashSet會(huì)假設(shè)對(duì)象沒(méi)有重復(fù)出現(xiàn)。但是如果發(fā)現(xiàn)有相 同 hashcode 值的對(duì)象,這時(shí)會(huì)調(diào)用 equals()方法來(lái)檢查 hashcode 相等的對(duì) 象是否真的相同。如果兩者相同,HashSet 就不會(huì)讓其加入操作成功。如果不 同的話,就會(huì)重新散列到其他位置。(摘自我的Java啟蒙書(shū)《Head first java》 第二版)。這樣我們就大大減少了 equals 的次數(shù),相應(yīng)就大大提高了執(zhí)行速 度。

hashCode()與equals()的相關(guān)規(guī)定

如果兩個(gè)對(duì)象相等,則hashcode一定也是相同的 兩個(gè)對(duì)象相等,對(duì)兩個(gè)對(duì)象分別調(diào)用equals方法都返回true 兩個(gè)對(duì)象有相同的hashcode值,它們也不一定是相等的

因此,equals 方法被覆蓋過(guò),則 hashCode 方法也必須被覆蓋

hashCode() 的默認(rèn)行為是對(duì)堆上的對(duì)象產(chǎn)生獨(dú)特值。如果沒(méi)有重寫(xiě)

hashCode(),則該 class 的兩個(gè)對(duì)象無(wú)論如何都不會(huì)相等(即使這兩個(gè)對(duì)象指 向相同的數(shù)據(jù))

對(duì)象的相等與指向他們的引用相等,兩者有什么不同?

對(duì)象的相等 比的是內(nèi)存中存放的內(nèi)容是否相等而 引用相等 比較的是他們指向的 內(nèi)存地址是否相等。

九.值傳遞

當(dāng)一個(gè)對(duì)象被當(dāng)作參數(shù)傳遞到一個(gè)方法后,此方法可改變這個(gè)對(duì) 象的屬性,并可返回變化后的結(jié)果,那么這里到底是值傳遞還是 引用傳遞

是值傳遞。Java 語(yǔ)言的方法調(diào)用只支持參數(shù)的值傳遞。當(dāng)一個(gè)對(duì)象實(shí)例作為一 個(gè)參數(shù)被傳遞到方法中時(shí),參數(shù)的值就是對(duì)該對(duì)象的引用。對(duì)象的屬性可以在被 調(diào)用過(guò)程中被改變,但對(duì)對(duì)象引用的改變是不會(huì)影響到調(diào)用者的

為什么 Java 中只有值傳遞

首先回顧一下在程序設(shè)計(jì)語(yǔ)言中有關(guān)將參數(shù)傳遞給方法(或函數(shù))的一些專(zhuān)業(yè)術(shù) 語(yǔ)。按值調(diào)用(call by value)表示方法接收的是調(diào)用者提供的值,而按引用調(diào)用 (call by reference)表示方法接收的是調(diào)用者提供的變量地址。一個(gè)方法可以 修改傳遞引用所對(duì)應(yīng)的變量值,而不能修改傳遞值調(diào)用所對(duì)應(yīng)的變量值。 它用 來(lái)描述各種程序設(shè)計(jì)語(yǔ)言(不只是Java)中方法參數(shù)傳遞方式。

Java程序設(shè)計(jì)語(yǔ)言總是采用按值調(diào)用。也就是說(shuō),方法得到的是所有參數(shù)值的 一個(gè)拷貝,也就是說(shuō),方法不能修改傳遞給它的任何參數(shù)變量的內(nèi)容。

下面通過(guò) 3 個(gè)例子來(lái)給大家說(shuō)明

example 1

1 public static void main(String[] args) {
2 int num1 = 10;
3 int num2 = 20;
4
5 swap(num1, num2);
6
7 System.out.println("num1 = " + num1);
8 System.out.println("num2 = " + num2);
9 }
10
11 public static void swap(int a, int b) {
12 int temp = a;
13 a = b;
14 b = temp;
15
16 System.out.println("a = " + a);
17 System.out.println("b = " + b);
18 }

結(jié)果:

1 a = 20
2 b = 10
3 num1 = 10
4 num2 = 20

解析:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-9kxuHrjo-1692506313325)(01-Java基礎(chǔ)知識(shí)面試題(2020最新版).assets/image-20201106190311218.png)]

在swap方法中,a、b的值進(jìn)行交換,并不會(huì)影響到 num1、num2。因?yàn)椋琣、 b中的值,只是從 num1、num2 的復(fù)制過(guò)來(lái)的。也就是說(shuō),a、b相當(dāng)于 num1、num2 的副本,副本的內(nèi)容無(wú)論怎么修改,都不會(huì)影響到原件本身。

通過(guò)上面例子,我們已經(jīng)知道了一個(gè)方法不能修改一個(gè)基本數(shù)據(jù)類(lèi)型的參數(shù),而 對(duì)象引用作為參數(shù)就不一樣,請(qǐng)看 example2.

example 2

1 public static void main(String[] args) {
2 int[] arr = { 1, 2, 3, 4, 5 };
3 System.out.println(arr[0]);
4 change(arr);
5 System.out.println(arr[0]);
6 }
7
8 public static void change(int[] array) {
9 // 將數(shù)組的第一個(gè)元素變?yōu)?
10 array[0] = 0;
11 }

結(jié)果:

1 1
2 0

解析:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-oIrslCIg-1692506313325)(01-Java基礎(chǔ)知識(shí)面試題(2020最新版).assets/image-20201106190416793.png)]

array 被初始化 arr 的拷貝也就是一個(gè)對(duì)象的引用,也就是說(shuō) array 和 arr 指向 的時(shí)同一個(gè)數(shù)組對(duì)象。 因此,外部對(duì)引用對(duì)象的改變會(huì)反映到所對(duì)應(yīng)的對(duì)象 上。

通過(guò) example2 我們已經(jīng)看到,實(shí)現(xiàn)一個(gè)改變對(duì)象參數(shù)狀態(tài)的方法并不是一件 難事。理由很簡(jiǎn)單,方法得到的是對(duì)象引用的拷貝,對(duì)象引用及其他的拷貝同時(shí) 引用同一個(gè)對(duì)象。

很多程序設(shè)計(jì)語(yǔ)言(特別是,C++和Pascal)提供了兩種參數(shù)傳遞的方式:值調(diào) 用和引用調(diào)用。有些程序員(甚至本書(shū)的作者)認(rèn)為Java程序設(shè)計(jì)語(yǔ)言對(duì)對(duì)象 采用的是引用調(diào)用,實(shí)際上,這種理解是不對(duì)的。由于這種誤解具有一定的普遍 性,所以下面給出一個(gè)反例來(lái)詳細(xì)地闡述一下這個(gè)問(wèn)題。

example 3

1 public class Test {
2
3 public static void main(String[] args) {
4 // TODO Auto‐generated method stub
5 Student s1 = new Student("小張");
6 Student s2 = new Student("小李");
7 Test.swap(s1, s2);
8 System.out.println("s1:" + s1.getName());
9 System.out.println("s2:" + s2.getName());
10 }
11
12 public static void swap(Student x, Student y) {
13 Student temp = x;
14 x = y;
15 y = temp;
16 System.out.println("x:" + x.getName());
17 System.out.println("y:" + y.getName());
18 }
19 }

結(jié)果:

1 x:小李
2 y:小張
3 s1:小張
4 s2:小李

解析:

交換之前:

2023面試八股文 ——Java基礎(chǔ)知識(shí),面試,面試,java,python

交換之后:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-z5tEDeCP-1692506313326)(01-Java基礎(chǔ)知識(shí)面試題(2020最新版).assets/image-20201106190619059.png)]

通過(guò)上面兩張圖可以很清晰的看出: 方法并沒(méi)有改變存儲(chǔ)在變量 s1 和 s2 中的 對(duì)象引用。swap方法的參數(shù)x和y被初始化為兩個(gè)對(duì)象引用的拷貝,這個(gè)方法交 換的是這兩個(gè)拷貝

總結(jié)

Java程序設(shè)計(jì)語(yǔ)言對(duì)對(duì)象采用的不是引用調(diào)用,實(shí)際上,對(duì)象引用是按值傳遞的。

下面再總結(jié)一下Java中方法參數(shù)的使用情況:

  • 一個(gè)方法不能修改一個(gè)基本數(shù)據(jù)類(lèi)型的參數(shù)(即數(shù)值型或布爾型》
  • 一個(gè)方法可以改變一個(gè)對(duì)象參數(shù)的狀態(tài)。
  • 一個(gè)方法不能讓對(duì)象參數(shù)引用一個(gè)新的對(duì)象。

值傳遞和引用傳遞有什么區(qū)別

值傳遞:指的是在方法調(diào)用時(shí),傳遞的參數(shù)是按值的拷貝傳遞,傳遞的是值的拷 貝,也就是說(shuō)傳遞后就互不相關(guān)了。 引用傳遞:指的是在方法調(diào)用時(shí),傳遞的參數(shù)是按引用進(jìn)行傳遞,其實(shí)傳遞的引 用的地址,也就是變量所對(duì)應(yīng)的內(nèi)存空間的地址。傳遞的是值的引用,也就是說(shuō) 傳遞前和傳遞后都指向同一個(gè)引用(也就是同一個(gè)內(nèi)存空間)。

十.Java包

JDK 中常用的包有哪些

  • java.lang:這個(gè)是系統(tǒng)的基礎(chǔ)類(lèi);
  • java.io:這里面是所有輸入輸出有關(guān)的類(lèi),比如文件操作等;
  • java.nio:為了完善 io 包中的功能,提高 io 包中性能而寫(xiě)的一個(gè)新包;
  • java.net:這里面是與網(wǎng)絡(luò)有關(guān)的類(lèi);
  • java.util:這個(gè)是系統(tǒng)輔助類(lèi),特別是集合類(lèi);
  • java.sql:這個(gè)是數(shù)據(jù)庫(kù)操作的類(lèi)。

import java和javax有什么區(qū)別

剛開(kāi)始的時(shí)候 JavaAPI 所必需的包是 java 開(kāi)頭的包,javax 當(dāng)時(shí)只是擴(kuò)展 API 包來(lái)說(shuō)使用。然而隨著時(shí)間的推移,javax 逐漸的擴(kuò)展成為 Java API 的組成部 分。但是,將擴(kuò)展從 javax 包移動(dòng)到 java 包將是太麻煩了,最終會(huì)破壞一堆現(xiàn) 有的代碼。因此,最終決定 javax 包將成為標(biāo)準(zhǔn)API的一部分。 所以,實(shí)際上java和javax沒(méi)有區(qū)別。這都是一個(gè)名字。

十一.IO流

java 中 IO 流分為幾種?

按照流的流向分,可以分為輸入流和輸出流; 按照操作單元?jiǎng)澐?,可以劃分為字?jié)流和字符流; 按照流的角色劃分為節(jié)點(diǎn)流和處理流。 Java Io流共涉及40多個(gè)類(lèi),這些類(lèi)看上去很雜亂,但實(shí)際上很有規(guī)則,而且彼 此之間存在非常緊密的聯(lián)系, Java I0流的40多個(gè)類(lèi)都是從如下4個(gè)抽象類(lèi)基類(lèi) 中派生出來(lái)的。

  • InputStream/Reader: 所有的輸入流的基類(lèi),前者是字節(jié)輸入流,后者是字符 輸入流。
  • OutputStream/Writer: 所有輸出流的基類(lèi),前者是字節(jié)輸出流,后者是字符輸 出流。

按操作方式分類(lèi)結(jié)構(gòu)圖:
2023面試八股文 ——Java基礎(chǔ)知識(shí),面試,面試,java,python

IO-操作方式分類(lèi)按操作對(duì)象分類(lèi)結(jié)構(gòu)圖:

2023面試八股文 ——Java基礎(chǔ)知識(shí),面試,面試,java,python

BIO,NIO,AIO 有什么區(qū)別?

簡(jiǎn)答

  • BIO:Block IO 同步阻塞式 IO,就是我們平常使用的傳統(tǒng) IO,它的特點(diǎn)是模式簡(jiǎn)單使用方便,并發(fā)處理能力低。

  • NIO:Non IO 同步非阻塞 IO,是傳統(tǒng) IO 的升級(jí),客戶端和服務(wù)器端通過(guò)
    Channel(通道)通訊,實(shí)現(xiàn)了多路復(fù)用。

  • AIO:Asynchronous IO 是 NIO 的升級(jí),也叫 NIO2,實(shí)現(xiàn)了異步非堵塞 IO
    ,異步 IO 的操作基于事件和回調(diào)機(jī)制。

詳細(xì)回答

  • BIO (Blocking I/O): 同步阻塞I/O模式,數(shù)據(jù)的讀取寫(xiě)入必須阻塞在一個(gè)線程內(nèi)等待其完成。在活動(dòng)連接數(shù)不是特別高(小于單機(jī)1000)的情況下,這種模型是比較不錯(cuò)的,可以讓每一個(gè)連接專(zhuān)注于自己的 I/O 并且編程模型簡(jiǎn)單,也不用過(guò)多考慮系統(tǒng)的過(guò)載、限流等問(wèn)題。線程池本身就是一個(gè)天然的漏斗,可以緩沖一些系統(tǒng)處理不了的連接或請(qǐng)求。但是,當(dāng)面對(duì)十萬(wàn)甚至百萬(wàn)級(jí)連接的時(shí)候,傳統(tǒng)的 BIO 模型是無(wú)能為力的。因此,我們需要一種更高效的 I/O 處理模型來(lái)應(yīng)對(duì)更高的并發(fā)量。

  • NIO (New I/O): NIO是一種同步非阻塞的I/O模型,在Java 1.4 中引入了NIO框架,對(duì)應(yīng) java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的 N可以理解為Non-blocking,不單純是New。它支持面向緩沖的,基于通道的I/O操作方法。 NIO提供了與傳統(tǒng)BIO模型中的 Socket 和 ServerSocket 相對(duì)應(yīng)的 SocketChannel 和 ServerSocketChannel 兩種不同的套接字通道實(shí)現(xiàn),兩種通道都支持阻塞和非阻塞兩種模式。阻塞模式使用就像傳統(tǒng)中的支持一樣,比較簡(jiǎn)單,但是性能和可靠性都不好;非阻塞模式正好與之相反。對(duì)于低負(fù)載、低并發(fā)的應(yīng)用程序,可以使用同步阻塞I/O來(lái)提升開(kāi)發(fā)速率和更好的維護(hù)性;對(duì)于高負(fù)載、高并發(fā)的(網(wǎng)絡(luò))應(yīng)用,應(yīng)使用 NIO 的非阻塞模式來(lái)開(kāi)發(fā)

  • AIO (Asynchronous I/O): AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改進(jìn)版 NIO 2,它是異步非阻塞的IO模型。異步 IO 是基于事件和回調(diào)機(jī)制實(shí)現(xiàn)的,也就是應(yīng)用操作之后會(huì)直接返回,不會(huì)堵塞在那里,當(dāng)后臺(tái)處理完成,操作系統(tǒng)會(huì)通知相應(yīng)的線程進(jìn)行后續(xù)的操作。AIO 是異步IO的縮寫(xiě),雖然 NIO 在網(wǎng)絡(luò)操作中,提供了非阻塞的方法,但是 NIO 的 IO 行為還是同步的。對(duì)于 NIO 來(lái)說(shuō),我們的業(yè)務(wù)線程是在 IO 操作準(zhǔn)備好時(shí),得到通知,接著就由這個(gè)線程自行進(jìn)行 IO 操作,IO操作本身是同步的。查閱網(wǎng)上相關(guān)資料,我發(fā)現(xiàn)就目前來(lái)說(shuō) AIO 的應(yīng)用還不是很廣泛,Netty 之前也嘗試使用過(guò) AIO,不過(guò)又放棄了。

Files的常用方法都有哪些?

  • Files. exists():檢測(cè)文件路徑是否存在。
  • Files. createFile():創(chuàng)建文件。
  • Files. createDirectory():創(chuàng)建文件夾。
  • Files. delete():刪除一個(gè)文件或目錄。
  • Files. copy():復(fù)制文件。
  • Files. move():移動(dòng)文件。
  • Files. size():查看文件個(gè)數(shù)。
  • Files. read():讀取文件。
  • Files. write():寫(xiě)入文件。

十二.反射

什么是反射機(jī)制?

JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi),都能夠知道這個(gè)類(lèi)的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱(chēng)為java語(yǔ)言的反射機(jī)制。

靜態(tài)編譯和動(dòng)態(tài)編譯

**靜態(tài)編譯:**在編譯時(shí)確定類(lèi)型,綁定對(duì)象

**動(dòng)態(tài)編譯:**運(yùn)行時(shí)確定類(lèi)型,綁定對(duì)象

反射機(jī)制優(yōu)缺點(diǎn)

優(yōu)點(diǎn): 運(yùn)行期類(lèi)型的判斷,動(dòng)態(tài)加載類(lèi),提高代碼靈活度。

缺點(diǎn): 性能瓶頸:反射相當(dāng)于一系列解釋操作,通知 JVM 要做的事情,性能

比直接的java代碼要慢很多。

反射機(jī)制的應(yīng)用場(chǎng)景有哪些?

反射是框架設(shè)計(jì)的靈魂。

在我們平時(shí)的項(xiàng)目開(kāi)發(fā)過(guò)程中,基本上很少會(huì)直接使用到反射機(jī)制,但這不能說(shuō)明反射機(jī)制沒(méi)有用,實(shí)際上有很多設(shè)計(jì)、開(kāi)發(fā)都與反射機(jī)制有關(guān),例如模塊化的開(kāi)發(fā),通過(guò)反射去調(diào)用對(duì)應(yīng)的字節(jié)碼;動(dòng)態(tài)代理設(shè)計(jì)模式也采用了反射機(jī)制,還有我們?nèi)粘J褂玫?Spring/Hibernate 等框架也大量使用到了反射機(jī)制。

舉例:①我們?cè)谑褂肑DBC連接數(shù)據(jù)庫(kù)時(shí)使用Class.forName()通過(guò)反射加載數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序;②Spring框架也用到很多反射機(jī)制, 經(jīng)典的就是xml的配置模式。Spring 通過(guò) XML 配置模式裝載 Bean 的過(guò)程:1) 將程序內(nèi)所有 XML 或 Properties 配置文件加載入內(nèi)存中; 2)Java類(lèi)里面解析xml或properties里面的內(nèi)容,得到對(duì)應(yīng)實(shí)體類(lèi)的字節(jié)碼字符串以及相關(guān)的屬性信息; 3)使用反射機(jī)制,根據(jù)這個(gè)字符串獲得某個(gè)類(lèi)的Class實(shí)例; 4)動(dòng)態(tài)配置實(shí)例的屬性

Java獲取反射的三種方法

1.通過(guò)new對(duì)象實(shí)現(xiàn)反射機(jī)制

2.通過(guò)路徑實(shí)現(xiàn)反射機(jī)制

3.通過(guò)類(lèi)名實(shí)現(xiàn)反射機(jī)制

1  public class Student {
2  private int id;
3  String name;
4  protected boolean sex;
5  public float score;
6  }
1   public class Get {
2   //獲取反射機(jī)制三種方式
3   public static void main(String[] args) throws ClassNotFoundException {
4   //方式一(通過(guò)建立對(duì)象)
5   Student stu = new Student();
6   Class classobj1 = stu.getClass();
7   System.out.println(classobj1.getName());
8   //方式二(所在通過(guò)路徑‐相對(duì)路徑)
9   Class classobj2 = Class.forName("fanshe.Student");
10  System.out.println(classobj2.getName());
11  //方式三(通過(guò)類(lèi)名)
12  Class classobj3 = Student.class;
13  System.out.println(classobj3.getName());
14  }
15  }

十三.網(wǎng)絡(luò)編程

網(wǎng)絡(luò)編程的面試題可以查看我的這篇文章重學(xué)TCP/IP協(xié)議和三次握手四次揮手,內(nèi)容不僅包括TCP/IP協(xié)議和三次握手四次揮手的知識(shí),還包括計(jì)算機(jī)網(wǎng)絡(luò)

體系結(jié)構(gòu),HTTP協(xié)議,get請(qǐng)求和post請(qǐng)求區(qū)別,session和cookie的區(qū)別等,歡迎大家閱讀。

十四.常用API

String相關(guān)

字符型常量和字符串常量的區(qū)別

  1. 形式上: 字符常量是單引號(hào)引起的一個(gè)字符 字符串常量是雙引號(hào)引起的若干個(gè)字符

  2. 含義上: 字符常量相當(dāng)于一個(gè)整形值(ASCII值),可以參加表達(dá)式運(yùn)算 字符串常量代表一個(gè)地址值(該字符串在內(nèi)存中存放位置)

  3. 占內(nèi)存大小 字符常量只占一個(gè)字節(jié) 字符串常量占若干個(gè)字節(jié)(至少一個(gè)字符結(jié)束標(biāo)志)

什么是字符串常量池?

字符串常量池位于堆內(nèi)存中,專(zhuān)門(mén)用來(lái)存儲(chǔ)字符串常量,可以提高內(nèi)存的使用率,避免開(kāi)辟多塊空間存儲(chǔ)相同的字符串,在創(chuàng)建字符串時(shí) JVM 會(huì)首先檢查字符串常量池,如果該字符串已經(jīng)存在池中,則返回它的引用,如果不存在,則實(shí)例化一個(gè)字符串放到池中,并返回其引用。

String 是最基本的數(shù)據(jù)類(lèi)型嗎

不是。Java 中的基本數(shù)據(jù)類(lèi)型只有 8 個(gè) :byte、short、int、long、float、 double、char、boolean;除了基本類(lèi)型(primitive type),剩下的都是引用類(lèi)型(referencetype),Java 5 以后引入的枚舉類(lèi)型也算是一種比較特殊的引用類(lèi)型。

這是很基礎(chǔ)的東西,但是很多初學(xué)者卻容易忽視,Java 的 8 種基本數(shù)據(jù)類(lèi)型中不包括 String,基本數(shù)據(jù)類(lèi)型中用來(lái)描述文本數(shù)據(jù)的是 char,但是它只能表示單個(gè)字符,比如 ‘a(chǎn)’,‘好’ 之類(lèi)的,如果要描述一段文本,就需要用多個(gè)

char 類(lèi)型的變量,也就是一個(gè) char 類(lèi)型數(shù)組,比如“你好” 就是長(zhǎng)度為2的數(shù)組 char[] chars = {‘你’,‘好’};

但是使用數(shù)組過(guò)于麻煩,所以就有了 String,String 底層就是一個(gè) char 類(lèi)型的數(shù)組,只是使用的時(shí)候開(kāi)發(fā)者不需要直接操作底層數(shù)組,用更加簡(jiǎn)便的方式即可完成對(duì)字符串的使用。

String有哪些特性

  • 不變性:String 是只讀字符串,是一個(gè)典型的 immutable 對(duì)象,對(duì)它進(jìn)行任何操作,其實(shí)都是創(chuàng)建一個(gè)新的對(duì)象,再把引用指向該對(duì)象。不變模式的主要作用在于當(dāng)一個(gè)對(duì)象需要被多線程共享并頻繁訪問(wèn)時(shí),可以保證數(shù)據(jù)的一致性。
  • 常量池優(yōu)化:String 對(duì)象創(chuàng)建之后,會(huì)在字符串常量池中進(jìn)行緩存,如果下次創(chuàng)建同樣的對(duì)象時(shí),會(huì)直接返回緩存的引用。
  • final:使用 final 來(lái)定義 String 類(lèi),表示 String 類(lèi)不能被繼承,提高了系統(tǒng)的安全性。

String為什么是不可變的嗎?

簡(jiǎn)單來(lái)說(shuō)就是String類(lèi)利用了final修飾的char類(lèi)型數(shù)組存儲(chǔ)字符,源碼如下圖所以:

1  /** The value is used for character storage. */

2  private final char value[];

String真的是不可變的嗎?

我覺(jué)得如果別人問(wèn)這個(gè)問(wèn)題的話,回答不可變就可以了。 下面只是給大家看兩個(gè)有代表性的例子:

  1. String不可變但不代表引用不可以變
1  String str = "Hello";

2  str = str + " World";

3  System.out.println("str=" + str);

結(jié)果:

1 str=Hello World

解析:

實(shí)際上,原來(lái)String的內(nèi)容是不變的,只是str由原來(lái)指向"Hello"的內(nèi)存地址轉(zhuǎn)為指向"Hello World"的內(nèi)存地址而已,也就是說(shuō)多開(kāi)辟了一塊內(nèi)存區(qū)域給"Hello World"字符串。

  1. 通過(guò)反射是可以修改所謂的“不可變”對(duì)象
1  // 創(chuàng)建字符串"Hello World", 并賦給引用s

2  String s = "Hello World";

3

4 System.out.println("s = " + s); // Hello World

5

6  // 獲取String類(lèi)中的value字段

7  Field valueFieldOfString = String.class.getDeclaredField("value");

8

9  // 改變value屬性的訪問(wèn)權(quán)限

10  valueFieldOfString.setAccessible(true);

11

12  // 獲取s對(duì)象上的value屬性的值

13  char[] value = (char[]) valueFieldOfString.get(s);

14

15  // 改變value所引用的數(shù)組中的第5個(gè)字符

16  value[5] = '_';

17

18 System.out.println("s = " + s); // Hello_World

結(jié)果:

1  s = Hello World

2  s = Hello_World

解析:

用反射可以訪問(wèn)私有成員, 然后反射出String對(duì)象中的value屬性, 進(jìn)而改變通過(guò)獲得的value引用改變數(shù)組的結(jié)構(gòu)。但是一般我們不會(huì)這么做,這里只是簡(jiǎn)單提一下有這個(gè)東西。

是否可以繼承 String 類(lèi)

String 類(lèi)是 final 類(lèi),不可以被繼承。

String str="i"與 String str=new String(“i”)一樣嗎?不一樣,因?yàn)閮?nèi)存的分配方式不一樣。String str=“i"的方式,java 虛擬機(jī)會(huì)將其分配到常量池中;而 String str=new String(“i”) 則會(huì)被分到堆內(nèi)存中。 String s = new String(“xyz”);創(chuàng)建了幾個(gè)字符串對(duì)象兩個(gè)對(duì)象,一個(gè)是靜態(tài)區(qū)的"xyz”,一個(gè)是用new創(chuàng)建在堆上的對(duì)象。

1	String str1 = "hello"; //str1指向靜態(tài)區(qū)
2	String str2 = new String("hello"); //str2指向堆上的對(duì)象
3	String str3 = "hello";
4	String str4 = new String("hello");
5	System.out.println(str1.equals(str2)); //true
6	System.out.println(str2.equals(str4)); //true
7	System.out.println(str1 == str3); //true
8	System.out.println(str1 == str2); //false
9	System.out.println(str2 == str4); //false
10	System.out.println(str2 == "hello"); //false
11	str2 = str1;
12	System.out.println(str2 == "hello"); //true

如何將字符串反轉(zhuǎn)?使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。示例代碼:

1	// StringBuffer reverse
2	StringBuffer stringBuffer = new StringBuffer();
3	stringBuffer. append("abcdefg");
4	System. out. println(stringBuffer. reverse()); // gfedcba
5	// StringBuilder reverse
6	StringBuilder stringBuilder = new StringBuilder();
7	stringBuilder. append("abcdefg");
8	System. out. println(stringBuilder. reverse()); // gfedcba

數(shù)組有沒(méi)有 length()方法?String 有沒(méi)有 length()方法

數(shù)組沒(méi)有 length()方法 ,有 length 的屬性。String 有 length()方法。 JavaScript中,獲得字符串的長(zhǎng)度是通過(guò) length 屬性得到的,這一點(diǎn)容易和 Java 混淆。

String 類(lèi)的常用方法都有那些?

  • indexOf():返回指定字符的索引。
  • charAt():返回指定索引處的字符。
  • replace():字符串替換。
  • trim():去除字符串兩端空白。
  • split():分割字符串,返回一個(gè)分割后的字符串?dāng)?shù)組。
  • getBytes():返回字符串的 byte 類(lèi)型數(shù)組。
  • length():返回字符串長(zhǎng)度。
  • toLowerCase():將字符串轉(zhuǎn)成小寫(xiě)字母。
  • toUpperCase():將字符串轉(zhuǎn)成大寫(xiě)字符。
  • substring():截取字符串。
  • equals():字符串比較。

在使用 HashMap 的時(shí)候,用 String 做 key 有什么好處?

HashMap 內(nèi)部實(shí)現(xiàn)是通過(guò) key 的 hashcode 來(lái)確定 value 的存儲(chǔ)位置,因?yàn)樽址遣豢勺兊模援?dāng)創(chuàng)建字符串時(shí),它的 hashcode 被緩存下來(lái),不需要再次計(jì)算,所以相比于其他對(duì)象更快。

String和StringBuffer、StringBuilder的區(qū)別是什么?String 為什么是不可變的

可變性

String類(lèi)中使用字符數(shù)組保存字符串,private final char value[],所以 string對(duì)象是不可變的。StringBuilder與StringBuffer都繼承自

AbstractStringBuilder類(lèi),在AbstractStringBuilder中也是使用字符數(shù)組保存字符串,char[] value,這兩種對(duì)象都是可變的。線程安全性

String中的對(duì)象是不可變的,也就可以理解為常量,線程安全。

AbstractStringBuilder是StringBuilder與StringBuffer的公共父類(lèi),定義了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer對(duì)方法加了同步鎖或者對(duì)調(diào)用的方法加了同步鎖,所以是線程安全的。StringBuilder并沒(méi)有對(duì)方法進(jìn)行加同步鎖,所以是非線程安全的。

性能

每次對(duì)String 類(lèi)型進(jìn)行改變的時(shí)候,都會(huì)生成一個(gè)新的String對(duì)象,然后將指針指向新的String 對(duì)象。StringBuffer每次都會(huì)對(duì)StringBuffer對(duì)象本身進(jìn)行操

作,而不是生成新的對(duì)象并改變對(duì)象引用。相同情況下使用StirngBuilder 相比使用StringBuffer 僅能獲得10%~15% 左右的性能提升,但卻要冒多線程不安全的風(fēng)險(xiǎn)。

對(duì)于三者使用的總結(jié)

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

Date相關(guān)

包裝類(lèi)相關(guān)

自動(dòng)裝箱與拆箱

裝箱:將基本類(lèi)型用它們對(duì)應(yīng)的引用類(lèi)型包裝起來(lái);

拆箱:將包裝類(lèi)型轉(zhuǎn)換為基本數(shù)據(jù)類(lèi)型; int 和 Integer 有什么區(qū)別

Java 是一個(gè)近乎純潔的面向?qū)ο缶幊陶Z(yǔ)言,但是為了編程的方便還是引入了基本數(shù)據(jù)類(lèi)型,但是為了能夠?qū)⑦@些基本數(shù)據(jù)類(lèi)型當(dāng)成對(duì)象操作,Java 為每一個(gè)基本數(shù)據(jù)類(lèi)型都引入了對(duì)應(yīng)的包裝類(lèi)型(wrapper class),int 的包裝類(lèi)就是 Integer,從 Java 5 開(kāi)始引入了自動(dòng)裝箱/拆箱機(jī)制,使得二者可以相互轉(zhuǎn)換。

Java 為每個(gè)原始類(lèi)型提供了包裝類(lèi)型:

原始類(lèi)型: boolean,char,byte,short,int,long,float,double 包裝類(lèi)型:Boolean,Character,Byte,Short,Integer,Long,F(xiàn)loat,

Double

Integer a= 127 與 Integer b = 127相等嗎

對(duì)于對(duì)象引用類(lèi)型:==比較的是對(duì)象的內(nèi)存地址。

對(duì)于基本數(shù)據(jù)類(lèi)型:比較的是值。如果整型字面量的值在-128到127之間,那么自動(dòng)裝箱時(shí)不會(huì)new新的Integer 對(duì)象,而是直接引用常量池中的Integer對(duì)象,超過(guò)范圍 a1b1的結(jié)果是false文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-661454.html

1	public static void main(String[] args) {
2	Integer a = new Integer(3);
3	Integer b = 3; // 將3自動(dòng)裝箱成Integer類(lèi)型
4	int c = 3;
5	System.out.println(a == b); // false 兩個(gè)引用沒(méi)有引用同一對(duì)象
6	System.out.println(a == c); // true a自動(dòng)拆箱成int類(lèi)型再和c比較
7	System.out.println(b == c); // true
8
9	Integer a1 = 128;
10	Integer b1 = 128;
11	System.out.println(a1 == b1); // false
12
13	Integer a2 = 127;
14	Integer b2 = 127;
15	System.out.println(a2 == b2); // true
16	}

者對(duì)調(diào)用的方法加了同步鎖,所以是線程安全的。StringBuilder并沒(méi)有對(duì)方法進(jìn)行加同步鎖,所以是非線程安全的。

性能

每次對(duì)String 類(lèi)型進(jìn)行改變的時(shí)候,都會(huì)生成一個(gè)新的String對(duì)象,然后將指針指向新的String 對(duì)象。StringBuffer每次都會(huì)對(duì)StringBuffer對(duì)象本身進(jìn)行操

作,而不是生成新的對(duì)象并改變對(duì)象引用。相同情況下使用StirngBuilder 相比使用StringBuffer 僅能獲得10%~15% 左右的性能提升,但卻要冒多線程不安全的風(fēng)險(xiǎn)。

對(duì)于三者使用的總結(jié)

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

Date相關(guān)

包裝類(lèi)相關(guān)

自動(dòng)裝箱與拆箱

裝箱:將基本類(lèi)型用它們對(duì)應(yīng)的引用類(lèi)型包裝起來(lái);

拆箱:將包裝類(lèi)型轉(zhuǎn)換為基本數(shù)據(jù)類(lèi)型; int 和 Integer 有什么區(qū)別

Java 是一個(gè)近乎純潔的面向?qū)ο缶幊陶Z(yǔ)言,但是為了編程的方便還是引入了基本數(shù)據(jù)類(lèi)型,但是為了能夠?qū)⑦@些基本數(shù)據(jù)類(lèi)型當(dāng)成對(duì)象操作,Java 為每一個(gè)基本數(shù)據(jù)類(lèi)型都引入了對(duì)應(yīng)的包裝類(lèi)型(wrapper class),int 的包裝類(lèi)就是 Integer,從 Java 5 開(kāi)始引入了自動(dòng)裝箱/拆箱機(jī)制,使得二者可以相互轉(zhuǎn)換。

Java 為每個(gè)原始類(lèi)型提供了包裝類(lèi)型:

原始類(lèi)型: boolean,char,byte,short,int,long,float,double 包裝類(lèi)型:Boolean,Character,Byte,Short,Integer,Long,F(xiàn)loat,

Double

Integer a= 127 與 Integer b = 127相等嗎

對(duì)于對(duì)象引用類(lèi)型:==比較的是對(duì)象的內(nèi)存地址。

對(duì)于基本數(shù)據(jù)類(lèi)型:比較的是值。如果整型字面量的值在-128到127之間,那么自動(dòng)裝箱時(shí)不會(huì)new新的Integer 對(duì)象,而是直接引用常量池中的Integer對(duì)象,超過(guò)范圍 a1b1的結(jié)果是false

1	public static void main(String[] args) {
2	Integer a = new Integer(3);
3	Integer b = 3; // 將3自動(dòng)裝箱成Integer類(lèi)型
4	int c = 3;
5	System.out.println(a == b); // false 兩個(gè)引用沒(méi)有引用同一對(duì)象
6	System.out.println(a == c); // true a自動(dòng)拆箱成int類(lèi)型再和c比較
7	System.out.println(b == c); // true
8
9	Integer a1 = 128;
10	Integer b1 = 128;
11	System.out.println(a1 == b1); // false
12
13	Integer a2 = 127;
14	Integer b2 = 127;
15	System.out.println(a2 == b2); // true
16	}

到了這里,關(guān)于2023面試八股文 ——Java基礎(chǔ)知識(shí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 2023Java崗面試,進(jìn)互聯(lián)網(wǎng)大廠必備Java面試八股文真題解析

    2023Java崗面試,進(jìn)互聯(lián)網(wǎng)大廠必備Java面試八股文真題解析

    前言 一般技術(shù)面試官都會(huì)通過(guò)自己的方式去考察程序員的技術(shù)功底與基礎(chǔ)理論知識(shí)。 很多時(shí)候,面試官問(wèn)的問(wèn)題會(huì)和自己準(zhǔn)備的“題庫(kù)”中的問(wèn)題不太一樣,即使做了復(fù)盤(pán),下次面試還是不知道該從何處下手。 為此鄙人軟磨硬泡才把阿里P8專(zhuān)門(mén)歸納整理的 《Java進(jìn)階知識(shí)典藏

    2023年04月10日
    瀏覽(28)
  • 2023Java 崗面試,進(jìn)互聯(lián)網(wǎng)大廠必備 Java 面試八股文真題解析

    2023Java 崗面試,進(jìn)互聯(lián)網(wǎng)大廠必備 Java 面試八股文真題解析

    前言 一般技術(shù)面試官都會(huì)通過(guò)自己的方式去考察程序員的技術(shù)功底與基礎(chǔ)理論知識(shí)。 很多時(shí)候,面試官問(wèn)的問(wèn)題會(huì)和自己準(zhǔn)備的“題庫(kù)”中的問(wèn)題不太一樣,即使做了復(fù)盤(pán),下次面試還是不知道該從何處下手。 為此鄙人軟磨硬泡才把阿里 P8 專(zhuān)門(mén)歸納整理的 《Java 進(jìn)階知識(shí)典

    2024年02月15日
    瀏覽(35)
  • 三天吃透Java面試八股文(2023最新整理),面試通過(guò)率高達(dá)90%

    三天吃透Java面試八股文(2023最新整理),面試通過(guò)率高達(dá)90%

    什么樣的求職者能夠獲得面試官的青睞?求職者需要準(zhǔn)備哪些內(nèi)容來(lái)面對(duì)形形色色的面試官?這兩份資料是我在幾十場(chǎng)面試中被面試官問(wèn)到的問(wèn)題, 比其他復(fù)制粘貼的面試題強(qiáng)一百倍 ,堪稱(chēng) 全網(wǎng)最強(qiáng) (我不太喜歡“全網(wǎng)最強(qiáng)”這樣的字眼,但確實(shí)做到了全網(wǎng)最強(qiáng))。 寫(xiě)這

    2024年02月13日
    瀏覽(32)
  • java八股文面試[java基礎(chǔ)]—— 重載 和 重寫(xiě)

    java八股文面試[java基礎(chǔ)]—— 重載 和 重寫(xiě)

    ? Overload Override Overwrite三者區(qū)別: ? Java中,有一個(gè)名叫方法簽名的東西,它的定義是這樣的 Definition: Two of the components of a method declaration comprise the method signature—the method’s name and the parameter types. 大概意思是,方法簽名有兩部分組成——方法名和參數(shù)列表 我上面的函數(shù)的方法

    2024年02月12日
    瀏覽(28)
  • java八股文面試[java基礎(chǔ)]——面相對(duì)象特點(diǎn)

    java八股文面試[java基礎(chǔ)]——面相對(duì)象特點(diǎn)

    三大特點(diǎn): 封裝 繼承 多態(tài) ? 面試題:java如何實(shí)現(xiàn)多繼承(除了使用接口之外) 實(shí)現(xiàn)多繼承有三個(gè)方法 : 多層繼承 內(nèi)部類(lèi) 接口 參考?java實(shí)現(xiàn)多繼承的三種方式 多層繼承 ?如果要直接繼承類(lèi),子類(lèi)是不可以直接多繼承的,但是可以通過(guò)多層繼承來(lái)實(shí)現(xiàn)多繼承,但多層繼承

    2024年02月12日
    瀏覽(23)
  • Java 崗史上最全八股文面試真題匯總,堪稱(chēng) 2023 年面試天花板

    Java 崗史上最全八股文面試真題匯總,堪稱(chēng) 2023 年面試天花板

    現(xiàn)如今,Java 面試的本質(zhì)就是八股文,把八股文面試題背好,面試才有可能表現(xiàn)好。金九銀十招聘黃金季已經(jīng)來(lái)臨!大家在考研和找工作中糾結(jié)的時(shí)候,不妨先看一下面試題,畢竟我們的最終目標(biāo)就是為了找一份心儀的工作!好工作都是早下手為強(qiáng)的,所以同學(xué)們要早做準(zhǔn)備

    2024年02月05日
    瀏覽(31)
  • java八股文面試[java基礎(chǔ)]——淺拷貝和深拷貝

    java八股文面試[java基礎(chǔ)]——淺拷貝和深拷貝

    ? 自驗(yàn)證:創(chuàng)建Class Student兩個(gè)類(lèi), Student中含有Class對(duì)象 測(cè)試代碼: 輸出: 可以看到不同的Student對(duì)象,但是有相同的Class對(duì)象 修改Student clone方法: 可以看到不同的class對(duì)象,不同的值: 知識(shí)來(lái)源: 【23版面試突擊】什么是淺拷貝和深拷貝_嗶哩嗶哩_bilibili 強(qiáng)引用、弱引用介

    2024年02月11日
    瀏覽(22)
  • 2023金九銀十Java面試八股文大全1200道面試題附答案詳解,最全面詳細(xì)

    2023金九銀十Java面試八股文大全1200道面試題附答案詳解,最全面詳細(xì)

    我的回答是: 很有必要 。你可以討厭這種模式,但你一定要去背,因?yàn)椴槐衬憔瓦M(jìn)不了大廠?,F(xiàn)如今,Java 面試的本質(zhì)就是八股文,把八股文面試題背好,面試才有可能表現(xiàn)好。金九銀十招聘黃金季已經(jīng)來(lái)臨!大家在考研和找工作中糾結(jié)的時(shí)候,不妨先看一下面試題,畢竟我

    2024年02月13日
    瀏覽(99)
  • 2023版一線大廠Java面試八股文(最新版)1000+ 面試題附答案詳解,最全面詳細(xì)

    2023版一線大廠Java面試八股文(最新版)1000+ 面試題附答案詳解,最全面詳細(xì)

    我的回答是: 很有必要 。你可以討厭這種模式,但你一定要去背,因?yàn)椴槐衬憔瓦M(jìn)不了大廠?,F(xiàn)如今,Java 面試的本質(zhì)就是八股文,把八股文面試題背好,面試才有可能表現(xiàn)好。金九銀十招聘黃金季已經(jīng)來(lái)臨!大家在考研和找工作中糾結(jié)的時(shí)候,不妨先看一下面試題,畢竟我

    2024年02月08日
    瀏覽(33)
  • 2023互聯(lián)網(wǎng)大廠最全Java面試八股文(附大廠 P5-P8 技術(shù)棧)

    2023互聯(lián)網(wǎng)大廠最全Java面試八股文(附大廠 P5-P8 技術(shù)棧)

    為什么感覺(jué) Java 面試變難了? 幾年前,你只需要簡(jiǎn)單的 ssm 框架 ,就能輕松找到一份 Java 的工作,但現(xiàn)在不一樣了,隨著涌入這個(gè)行業(yè)的人越來(lái)越多,同一個(gè)崗位需要篩選掉更多人,要求自然水漲船高, 這也就是現(xiàn)在越來(lái)越多 Java 程序員抱怨行業(yè)越來(lái)越卷的原因 ,當(dāng)然這個(gè)

    2024年02月15日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包