1. <tbody id="y0n05"><nobr id="y0n05"><input id="y0n05"></input></nobr></tbody><strong id="y0n05"><acronym id="y0n05"></acronym></strong>

          1. 最最最常見的Java面試題總結-第一周

            小編:艷芬 954閱讀 2020.09.11

            一 Java中的值傳遞和引用傳遞(非常重要)

            首先要明確的是:“對象傳遞(數組、類、接口)是引用傳遞,原始類型數據(整型、浮點型、字符型、布爾型)傳遞是值傳遞?!?/strong>

            那么什么是值傳遞和應用傳遞呢?

            值傳遞是指對象被值傳遞,意味著傳遞了對象的一個副本,即使副本被改變,也不會影響源對象。(因為值傳遞的時候,實際上是將實參的值復制一份給形參。)

            引用傳遞是指對象被引用傳遞,意味著傳遞的并不是實際的對象,而是對象的引用。因此,外部對引用對象的改變會反映到所有的對象上。(因為引用傳遞的時候,實際上是將實參的地址值復制一份給形參。)

            有時候面試官不是單純問你“Java中是值傳遞還是引用傳遞”是什么啊,騷年?而是給出一個例子,然后讓你寫出答案,這種也常見在筆試題目中!所以,非常重要了,請看下面的例子:

            值傳遞和應用傳遞實例1. 值傳遞
            public static void main(String[] args) {
                int num1 = 10;
                int num2 = 20;
            
                swap(num1, num2);
            
                System.out.println("num1 = " + num1);
                System.out.println("num2 = " + num2);
            }
            
            public static void swap(int a, int b) {
                int temp = a;
                a = b;
                b = temp;
            
                System.out.println("a = " + a);
                System.out.println("b = " + b);
            }

            結果:

            a = 20
            b = 10
            num1 = 10
            num2 = 20

            解析:

            在swap方法中,a、b的值進行交換,并不會影響到num1、num2。因為,a、b中的值,只是從num1、num2的復制過來的。

            也就是說,a、b相當于num1、num2的副本,副本的內容無論怎么修改,都不會影響到原件本身。

            2. 引用傳遞
            public static void main(String[] args) {
                int[] arr = {1,2,3,4,5};
            
                change(arr);
            
                System.out.println(arr[0]);
            }
            
            public static void change(int[] array) {
            //將數組的第一個元素變為0
                array[0] = 0;
            }

            結果:

            1
            0

            解析:

            無論是主函數,還是change方法,操作的都是同一個地址值對應的數組。 。因此,外部對引用對象的改變會反映到所有的對象上。

            一些特殊的例子1. StringBuffer類型傳遞
            	// 測試引用傳遞:StringBuffer
            	@org.junit.Test
            	public void method1() {
            		StringBuffer str = new StringBuffer("公眾號:Java面試通關手冊");
            		System.out.println(str);
            		change1(str);
            		System.out.println(str);
            	}
            
            	public static void change1(StringBuffer str) {
            		str = new StringBuffer("abc");//輸出:“公眾號:Java面試通關手冊”
            		//str.append("歡迎大家關注");//輸出:公眾號:Java面試通關手冊歡迎大家關注
            		//str.insert(3, "(編程)");//輸出:公眾號(編程):Java面試通關手冊
            		
            	}

            結果:

            公眾號:Java面試通關手冊
            公眾號:Java面試通關手冊

            解析:

            很多要這個時候要問了:StringBuffer創建的明明也是對象,那為什么輸出結果依然是原來的值呢?

            因為在change1方法內部我們是新建了一個StringBuffer對象,所以str指向了另外一個地址,相應的操作也同樣是指向另外的地址的。

            那么,如果將change1方法改成如下圖所示,想必大家應該知道輸出什么了,如果你還不知道,那可能就是我講的有問題了,我反思(開個玩笑,上面程序中已經給出答案):

            	public static void change1(StringBuffer str) {
            
            		str.append("歡迎大家關注");
            		str.insert(3, "(編程)");
            		
            	}
            2. String類型傳遞
            	// 測試引用傳遞:Sring
            	@org.junit.Test
            	public void method2() {
            		String str = new String("公眾號:Java面試通關手冊");
            		System.out.println(str);
            		change2(str);
            		System.out.println(str);
            	}
            
            	public static void change2(String str) {
            		// str="abc"; //輸出:公眾號:Java面試通關手冊
            		str = new String("abc"); //輸出:公眾號:Java面試通關手冊
            	}

            結果:

            公眾號:Java面試通關手冊
            公眾號:Java面試通關手冊

            可以看到不論是執行str="abc;"還是str = new String("abc");str的輸出的值都不變。

            按照我們上面講“StringBuffer類型傳遞”的時候說的,str="abc;"應該會讓str的輸出的值都不變。為什么呢?因為String在創建之后是不可變的。

            3. 一道類似的題目

            下面的程序輸出是什么?

            public class Demo {
            	public static void main(String[] args) {
            		Person p = new Person("張三");
            
            		change(p);
            
            		System.out.println(p.name);
            	}
            
            	public static void change(Person p) {
            		Person person = new Person("李四");
            		p = person;
            	}
            }
            
            class Person {
            	String name;
            
            	public Person(String name) {
            		this.name = name;
            	}
            }

            很明顯仍然會輸出張三。因為change方法中重新創建了一個Person對象。

            那么,如果把change方法改為下圖所示,輸出結果又是什么呢?

            	public static void change(Person p) {
            		p.name="李四";
            	}

            答案我就不說了,我覺得大家如果認真看完上面的內容之后應該很很清楚了。

            二 ==與equals(重要)

            == : 它的作用是判斷兩個對象的地址是不是相等。即,判斷兩個對象是不是同一個對象。(基本數據類型==比較的是值,引用數據類型==比較的是內存地址)

            equals() : 它的作用也是判斷兩個對象是否相等。但它一般有兩種使用情況:

            • 情況1:類沒有覆蓋equals()方法。則通過equals()比較該類的兩個對象時,等價于通過“==”比較這兩個對象。
            • 情況2:類覆蓋了equals()方法。一般,我們都覆蓋equals()方法來兩個對象的內容相等;若它們的內容相等,則返回true(即,認為這兩個對象相等)。

            舉個例子:

            public class test1 {
                public static void main(String[] args) {
                    String a = new String("ab"); // a 為一個引用
                    String b = new String("ab"); // b為另一個引用,對象的內容一樣
                    String aa = "ab"; // 放在常量池中
                    String bb = "ab"; // 從常量池中查找
                    if (aa == bb) // true
                        System.out.println("aa==bb");
                    if (a == b) // false,非同一對象
                        System.out.println("a==b");
                    if (a.equals(b)) // true
                        System.out.println("aEQb");
                    if (42 == 42.0) { // true
                        System.out.println("true");
                    }
                }
            }

            說明:

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

            面試官可能會問你:“你重寫過 hashcode 和 equals 么,為什么重寫equals時必須重寫hashCode方法?”

            hashCode()介紹

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

            散列表存儲的是鍵值對(key-value),它的特點是:能根據“鍵”快速的檢索出對應的“值”。這其中就利用到了散列碼?。ǹ梢钥焖僬业剿枰膶ο螅?

            為什么要有hashCode

            我們以“HashSet如何檢查重復”為例子來說明為什么要有hashCode:

            當你把對象加入HashSet時,HashSet會先計算對象的hashcode值來判斷對象加入的位置,同時也會與其他已經加入的對象的hashcode值作比較,如果沒有相符的hashcode,HashSet會假設對象沒有重復出現。但是如果發現有相同hashcode值的對象,這時會調用equals()方法來檢查hashcode相等的對象是否真的相同。如果兩者相同,HashSet就不會讓其加入操作成功。如果不同的話,就會重新散列到其他位置。(摘自我的Java啟蒙書《Head fist java》第二版)。這樣我們就大大減少了equals的次數,相應就大大提高了執行速度。

            hashCode()與equals()的相關規定
            1. 如果兩個對象相等,則hashcode一定也是相同的
            2. 兩個對象相等,對兩個對象分別調用equals方法都返回true
            3. 兩個對象有相同的hashcode值,它們也不一定是相等的
            4. 因此,equals方法被覆蓋過,則hashCode方法也必須被覆蓋
            5. hashCode()的默認行為是對堆上的對象產生獨特值。如果沒有重寫hashCode(),則該class的兩個對象無論如何都不會相等(即使這兩個對象指向相同的數據)
            關聯標簽:
            国产欧美日韩激情视频一区,久久无码中文字幕无码网站,99久久久成人毛片无码,国产国语脏话对白免费视频,丰满熟女大屁股水多多