那些你所不知道的Java小知識(持續(xù)更新)

本文主要是收錄一些人們可能經常會忽略辜膝,但又挺重要的Java方面的小知識爱葵。有推薦的也可以在下方留言错维,大家一起進步呀敷待!

目錄:
1.a=a+b和a+=b的區(qū)別
2.String str1 = new String("a"); String str2 = "a"+"b"; 這兩行代碼分別創(chuàng)建了幾個對象场仲,是什么
3.啟動線程的方式以及如何更好地結束一個線程和悦?
4.Java 中 == 和 equals 和 hashCode的區(qū)別
5.Java浮點數(shù)的默認類型是什么
6.多態(tài)成員訪問特點
7.用來實現(xiàn)線程間通知和喚醒的方式
8.初始化過程
9.值傳遞和引用傳遞
10.線程共享的內容和私有的內容
11.Thread和Runnable的區(qū)別
12.迭代器遍歷元素的時候,通過集合是不能修改元素的
13.EditText中的值為手機號時不能轉為int

2019-7-7

1.a=a+b和a+=b的區(qū)別

(1)從效率上看
a+=b要略高于a=a+b
(2)從運算符上看
a+=b的執(zhí)行過程是先計算出a的值渠缕,然后用一個temp對象存儲鸽素,之后和b進行相加,然后將值賦給a引用亦鳞。
a=a+b的執(zhí)行過程是先計算a+b馍忽,然后再賦值給a引用棒坏,賦值給a引用的時候如果引用a有計算過程,則會再次計算遭笋。
(3)從類型自動轉換上看
當a和b的數(shù)據類型不一樣時坝冕,a+=b會自動進行類型轉換;而a=a+b不會瓦呼,需要手動進行類型轉換
比如:

byte a = 1;
int b = 4;
a = a + b;//此時編譯會報錯喂窟,因為a為byte,b為int央串,
//a+b的時候默認會向大類型即int轉換磨澡,則a+b的類型為int,而a為byte蹋辅,所以報錯

a += b;//此時編譯不會報錯钱贯,因為+=會自動進行類型轉換挫掏,并且向低轉換
2.String str1 = new String("a"); String str2 = "a"+"b"; 這兩行代碼分別創(chuàng)建了幾個對象侦另,是什么

(1)首先第一行代碼中創(chuàng)建了兩個對象(因為字符串池中沒有a字符串),一個是new String創(chuàng)建出來的str1對象尉共,一個是在字符串池中創(chuàng)建的a對象褒傅。
(2)然后因為a字符串已經在常量池中存在了,所以在第二行代碼中就不會再創(chuàng)建a對象了袄友。接著創(chuàng)建的就是b對象殿托,最后是str2對象,值為ab剧蚣。
總結:要先看字符串池中有沒有該字符串支竹,有的話會直接拿過來,沒有再重新創(chuàng)建鸠按。

3.啟動線程的方式以及如何更好地結束一個線程礼搁?

(1)啟動線程的方式

  • 繼承Thread類
  • 實現(xiàn)Runnable接口
  • 實現(xiàn)Callable接口通過FutureTask包裝器來創(chuàng)建Thread線程
  • 匿名內部類
圖片.png

(2)如何更好地結束一個線程

線程中調用interrupt()方法僅僅是在當前線程中打了個停止的標記,并不是真的停止線程目尖。
如何判斷線程的狀態(tài)是否是停止馒吴,主要包含以下兩種方法:
1、this.interrupted():測試當前線程是否已經是中斷狀態(tài)瑟曲,執(zhí)行后具有將狀態(tài)標志置清除為false的功能饮戳。
2、this.isInterrupted():測試線程thread對象是否已經是中斷狀態(tài)洞拨,但不具備清除狀態(tài)標志扯罐。
注:使用stop()方法停止線程是非常暴力的,該方法已經作廢烦衣,不考慮歹河。

注意:官方文檔中說明If this thread is blocked in an invocation of the [wait()], [wait(long)], or [wait(long, int)] methods of the [Object] class, or of the [join()], [join(long)], [join(long, int)], [sleep(long)], or [sleep(long, int)], methods of this class, then its interrupt status will be cleared and it will receive an [InterruptedException].
也就是說齿椅,在run方法里面調用Object類的wait或線程的join/sleep方法之后,這個標記會被清空并拋出InterruptedException異常启泣。解決方法:可在調用的方法的catch中再this.interrupt一次涣脚。(不是下文例子中的catch)

① 拋異常法

public static void main(String[] args) throws InterruptedException {
        MyThread t1 = new MyThread();
        t1.start();
        Thread.sleep(100);
        t1.interrupt();
    }

    public static class MyThread extends Thread {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 5000000; i++) {
                    if (this.isInterrupted()) {
                        System.out.println("Thread Stop!");
                        throw new InterruptedException();
                    }
                    System.out.println("i: " + i);
                }
                System.out.println("我在for下面");
            } catch (InterruptedException e) {
                System.out.println("進入到catch了寥茫!");
            }
        }
    }

運行結果:
...
i: 11759
i: 11760
i: 11761
i: 11762
Thread Stop遣蚀!
進入到catch了!

② 使用return

public static void main(String[] args) throws InterruptedException {
        MyThread t1 = new MyThread();
        t1.start();
        Thread.sleep(100);
        t1.interrupt();
    }

    public static class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 5000000; i++) {
                if (this.isInterrupted()) {
                    System.out.println("Thread Stop纱耻!");
                    return;
                }
                System.out.println("i: " + i);
            }
            System.out.println("我在for下面");
        }
    }

運行結果:
...
i: 12301
i: 12302
i: 12303
i: 12304
i: 12305
Thread Stop芭梯!

③ 使用退出標志
和上面兩種方法差不多,只不過是用一個布爾變量代替this.isInterrupted()弄喘,然后要想停止線程玖喘,賦值該布爾變量為false即可。

2019-8-2

4.Java 中 == 和 equals 和 hashCode的區(qū)別

(1)==
對于八種基本數(shù)據類型蘑志,比較的是他們的值
對于引用數(shù)據類型(類累奈,接口和數(shù)組),比較的是他們在內存中的地址急但,所以澎媒,除非是同一個new出來的對象,他們比較之后的結果為true波桩,否則為false戒努。eg:

Integer a = new Integer(127);
Integer b = 127;
Integer c = 127;
//a==b為false,b==c為true
Integer d = 128;
Integer e = 128;
//d==e為false
//這里為什么b==c為true而d==e為false呢镐躲?
//Integer b = 127在編譯時會被翻譯成Integer.valueOf(127)储玫,該方法對于[-128,127]之間
//的數(shù)會進行緩存,如果已經有的話會直接從緩存中拿出萤皂,不會再new
//因為128不在該區(qū)間撒穷,那么d和e就只是new出來的兩個不同的對象了,所以就為false

Java中堆和棧的區(qū)別
最主要的區(qū)別就是:new出來的對象和數(shù)組是存放在堆中的敌蚜,基本數(shù)據類型的變量和對象的引用變量是存放在棧中的桥滨。

Java的內存機制:
棧:當在一段代碼塊定義一個變量時,Java就在棧中為這個變量分配內存空間弛车,當該變量超過它的作用域后齐媒,Java會自動釋放掉為該變量所分配的內存空間。
堆:在堆中分配的內存纷跛,由GC來管理喻括。在堆中產生了一個數(shù)組或對象之后,還可以在棧中定義一個特殊的變量贫奠,讓棧中這個變量的值等于該數(shù)組或者對象在堆內存中的首地址唬血,棧中的這個變量就成了數(shù)組或者對象的引用變量望蜡,以后可以在程序中使用棧中的引用變量來訪問數(shù)組或者對象。

(2)equals
默認情況下的equals方法是沒有被覆蓋的拷恨,調用的都是Object類的equals方法脖律,這種情況下的equals方法和==是等效的。

public boolean equals(Object obj) {
   return (this == obj);
   }
如果equals方法被覆蓋腕侄,則按照新的方法來判斷小泉,覆蓋后一般
都是通過對象的內容是否相等來判斷對象是否相等。比如String類的equals方法:

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

String類的equals方法總結為:
首先看是不是同一個對象冕杠,是的話返回true
然后看對比對象是不是String類型微姊,
接著看長度是否一致
最后比較逐個字符是否相同

實現(xiàn)高質量的equals方法的技巧如下:
首先比較兩個是否==,
然后檢查對比對象是否是該類型分预,
接著比較他們的域是否相同
最后檢查對稱性兢交,傳遞性,一致性

(3)hashCode
hashCode()方法也是Object類的一個方法笼痹,返回的是一個int型的整數(shù)配喳。在集合類操作中使用,主要是為了提高查詢速度与倡。
兩者的hashCode相同界逛,他們不一定equals昆稿。
兩者的hashCode不相同纺座,他們一定不equals。
他們equals溉潭,hashCode一定相同净响。
他們不equals,hashCode有可能相同喳瓣。

2019-8-9

5.Java浮點數(shù)的默認類型是什么

答案:double馋贤。

6.多態(tài)成員訪問特點

成員變量:編譯看左邊,運行看左邊
靜態(tài)變量:編譯看左邊畏陕,運行看左邊
成員方法:編譯看左邊配乓,運行看右邊
靜態(tài)方法:編譯看左邊,運行看左邊

7.用來實現(xiàn)線程間通知和喚醒的方式

① Object.wait/notify/notifyAll
② Condition.await/signal/signalAll

2019-8-10

8.初始化過程

① 首先惠毁,初始化父類中的靜態(tài)成員變量和靜態(tài)代碼塊犹芹,按照在程序中出現(xiàn)的順序初始化;
② 然后鞠绰,初始化子類中的靜態(tài)成員變量和靜態(tài)代碼塊腰埂,按照在程序中出現(xiàn)的順序初始化;
③ 其次蜈膨,初始化父類的普通成員變量和代碼塊屿笼,在執(zhí)行父類的構造方法牺荠;
④ 最后,初始化子類的普通成員變量和代碼塊驴一,在執(zhí)行子類的構造方法休雌;
比如:

class C {
    C() {
        System.out.print("C");
    }
}
 
class A {
    C c = new C();
 
    A() {
        this("A");
        System.out.print("A");
    }
 
    A(String s) {
        System.out.print(s);
    }
}
 
class Test extends A {
    Test() {
        super("B");
        System.out.print("B");
    }
 
    public static void main(String[] args) {
        new Test();
    }
}

Output:
CBB

(1)初始化父類的普通成員變量和代碼塊,執(zhí)行 C c = new C(); 輸出C 
(2)super("B"); 表示調用父類的構造方法肝断,不調用父類的無參構造函數(shù)挑辆,輸出B 
(3) System.out.print("B"); 
 所以輸出CBB 

2019-8-23

9.值傳遞和引用傳遞

“在Java里面參數(shù)傳遞都是按值傳遞”這句話的意思是:按值傳遞是傳遞的值的拷貝,按引用傳遞其實傳遞的是引用的地址值孝情,所以統(tǒng)稱按值傳遞鱼蝉。

簡單的說,

基本類型是按值傳遞箫荡,方法的實參是一個原值的副本魁亦。
類對象是按對象的引用地址(內存地址)傳遞地址的值,那么在方法內對這個對象進行修改是會直接反應在原對象上的(或者說這兩個引用指向同一內存地址)羔挡。
但是String類除外洁奈,其規(guī)則和基本類型是一樣的,因為String是final關鍵字修飾的绞灼,不可變的
eg:

public static void main(String[] args){
  String x = new String("LongSh1z");
  change(x);
  System.out.println(x);
}

public static void change(String x){
  x = "changed";
}

輸出結果應該是LongSh1z利术,而不是changed。

解釋如下:

當執(zhí)行到change方法時低矮,Main就入棧印叁,change開啟一片棧空間军掂,x是形參轮蜕,在change的棧內有一份拷貝引用x。(這時Main棧上的x和change棧上的是指向同一片堆空間蝗锥,即“LongSh1z”)跃洛。接著執(zhí)行x = "changed",此時change棧上的x會指向新的一片空間(方法區(qū)上的常量池)终议,而Main棧上的x沒有改變汇竭。

還不懂的同學可以去看看這一篇,講的巨詳細
https://blog.csdn.net/bntx2jsqfehy7/article/details/83508006

2019-9-5

10.線程共享的內容和私有的內容

(1)線程共享的內容包括:
進程代碼段
進程 數(shù)據段
進程打開的文件描述符
信號的處理器
進程的當前目錄
進程用戶 ID 與進程組 ID
(2)線程獨有的內容包括:
線程 ID
寄存器組的值
線程的堆棧
錯誤返回碼
線程的信號屏蔽碼

2019-9-17

11.Thread和Runnable的區(qū)別

(1)Runnable方式可以避免Thread方式由于Java單繼承的特性帶來的缺陷
(2)Runnable的代碼可以被多個線程(Thread實例)共享穴张,適合于多個線程處理同一資源(這里的同一資源指的是同一個Runnable對象)的情況

2019-10-26

12.迭代器遍歷元素的時候细燎,通過集合是不能修改元素的
List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(6);

        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            list.add(6);
            System.out.println(iterator.next());
        }

//會報Exception in thread "main" java.util.ConcurrentModificationException異常

//正確做法:
//①使用ListIterator(List集合特有的迭代器。該迭代器繼承了Iterator迭代器)
ListIterator iterator= list.listItertor();
while(lit.hasNext()){
    String s = (String)lit.next();
    if(s.equals("java")){
        iterator.add("love");
//注意:此處是利用迭代器進行添加元素陆馁,剛添加的元素處于剛才迭代的元素的后面找颓。
//!67贰击狮!是iterator添加佛析,不是list添加。1肱睢4缒!
    }
}
 
//②使用普通循環(huán)方法档冬,即使用get()方法
for(int i = 0;i<list.size();i++){
    String s = (String)list.get(i);
    if(s.equals("java")){
        list.add("love");//注意:此處是將新的元素添加到了集合的最后
    }
}

//③要想繼續(xù)使用Iterator而不是ListIterator 膘茎,可以將ArrayList改為CopyOnWriteArrayList

2019-10-27

13.EditText中的值為手機號時不能轉為int

很多時候我們都需要拿到editText里面的值,并且轉為int酷誓,但是每次Integer.parseInt()時拿到的值都為0披坏。
參照了網上的方法(比如轉化之前判斷呀,try-catch呀盐数,在監(jiān)聽器里面寫呀等等)都沒用棒拂。
網上的方法可以點擊這個看看:http://blog.sina.com.cn/s/blog_a4dda2480101asy3.html
但是最重要的如果editText里面的是String類型的手機號碼轉為int的話,可以將int改為long玫氢。
因為在Java中int的范圍是從-21474836482147483647(10位),即2的31次方帚屉,而手機號碼為11位

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市漾峡,隨后出現(xiàn)的幾起案子攻旦,更是在濱河造成了極大的恐慌,老刑警劉巖生逸,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牢屋,死亡現(xiàn)場離奇詭異,居然都是意外死亡牺陶,警方通過查閱死者的電腦和手機伟阔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掰伸,“玉大人,你說我怎么就攤上這事怀估∈ㄑ迹” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵多搀,是天一觀的道長歧蕉。 經常有香客問我,道長康铭,這世上最難降的妖魔是什么惯退? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮从藤,結果婚禮上催跪,老公的妹妹穿的比我還像新娘锁蠕。我一直安慰自己,他們只是感情好懊蒸,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布荣倾。 她就那樣靜靜地躺著,像睡著了一般骑丸。 火紅的嫁衣襯著肌膚如雪舌仍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天通危,我揣著相機與錄音铸豁,去河邊找鬼。 笑死菊碟,一個胖子當著我的面吹牛推姻,可吹牛的內容都是我干的。 我是一名探鬼主播框沟,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼藏古,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了忍燥?” 一聲冷哼從身側響起拧晕,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梅垄,沒想到半個月后厂捞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡队丝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年靡馁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片机久。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡臭墨,死狀恐怖,靈堂內的尸體忽然破棺而出膘盖,到底是詐尸還是另有隱情胧弛,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布侠畔,位于F島的核電站结缚,受9級特大地震影響,放射性物質發(fā)生泄漏软棺。R本人自食惡果不足惜红竭,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧茵宪,春花似錦最冰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至憾股,卻和暖如春鹿蜀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背服球。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工茴恰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人斩熊。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓往枣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親粉渠。 傳聞我的和親對象是個殘疾皇子分冈,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內容

  • 從網上復制的,看別人的比較全面霸株,自己搬過來雕沉,方便以后查找。原鏈接:https://www.cnblogs.com/...
    lxtyp閱讀 1,345評論 0 9
  • 前言 RTFSC (Read the fucking source code )才是生活中最重要的去件。我們天天就是要...
    二毛_coder閱讀 452評論 1 1
  • 在C語言中,五種基本數(shù)據類型存儲空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 3,333評論 0 2
  • 一:在JAVA中坡椒,有六個不同的地方可以存儲數(shù)據: 1. 寄存器(register)。 這是最快的存儲區(qū)尤溜,因為它位...
    辰321閱讀 409評論 0 0
  • 總概 - 命名規(guī)范 - 數(shù)據類型 - eclipse常用快捷鍵 1倔叼、java開發(fā)中的命名規(guī)則 除去一些硬性要求,比...
    panda_Hi閱讀 327評論 0 0