【面試題每日學習】9

1.Java 中的內部類有哪些?

答:內部類包含如下 4 種:html

  • 靜態內部類:static class StaticInnerClass{};
  • 成員內部類:private class InstanceInnerClass{};
  • 局部內部類:定義在方法或者表達式內部;
  • 匿名內部類:(new Thread(){}).start()。

2.如下關於匿名內部類說法錯誤的是?

A:匿名內部類必須繼承一個父類或者實現一個接口 B:匿名內部類中的方法不能是抽象的 C:匿名內部類能夠實現接口的部分抽象方法 D:匿名內部類不能定義任何靜態成員和方法java

答:C 題目解析:匿名內部類規定必須實現接口的全部抽象方法,不然程序會報錯,以下圖所示。api

enter image description here

3.如下枚舉類比較「==」和「equals」結果一致嗎?爲何?

class EnumTest {
    public static void main(String[] args) {
        ColorEnum redColor = ColorEnum.RED;
        ColorEnum redColor2 = ColorEnum.RED;
        System.out.println(redColor == redColor2);
        System.out.println(redColor.equals(redColor2));
    }
}
enum ColorEnum {
    RED,
    BLUE
}

答:結果一致,都是 true。 題目分析:由於枚舉類重寫了 equals 方法,equals 方法裏直接使用的 == 比較的,而枚舉類不能經過 new 進行建立,使用 ColorEnum.RED 獲得的對象,其實使用的是對象的引用地址,因此 == 比較的結果必定是 true。equals 被重寫的源碼以下圖:安全

enter image description here

4.使用靜態內部類的好處有哪些?

答:使用靜態內部類的好處以下: 做用域不會擴散到包外;oracle

  • 能夠經過「外部類.內部類」的方式直接訪問;
  • 內部類能夠訪問外部類中的全部靜態屬性和方法。

5.如下代碼執行的結果是?

class OuterClass {
    String name = "OuterClass";
    protected static class InnerClass {
        String name = "InnerClass";
        public void sayHi() {
            System.out.println(OuterClass.this.name);
        }
    }
}
class InnerClassTest {
    public static void main(String[] args) {
        OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
        innerClass.sayHi();
    }
}

答:程序報錯。 題目解析:在靜態成員內部類中不能直接訪問非靜態外部類,所以程序會報錯。app

6.成員內部類和局部內部類有什麼區別?

答:內部成員類和局部內部類的區別以下。this

  • 內部成員類能夠使用任意訪問修飾符,局部內部類不能使用任何訪問修飾符;
  • 局部內部類是聲明在外部類的方法或其餘做用域範圍內的,內部類是直接聲明在外部類之中的,與方法和屬性平級。

7.爲何要使用內部類?內部類的使用場景有哪些?

答:使用內部類的好處有如下兩個。線程

  • 能夠做爲多繼承的一種實現方式,最先內部類的實現就是平衡 Java 語言中沒有多繼承的一種方式;
  • 方便將存在必定邏輯關係的類組織在一塊兒,又能夠對外界隱藏。 內部類能夠做爲多繼承的一種實現方式進行使用,由於每一個內部類都能獨立的繼承一個類或接口,因此整個類就能夠實現多繼承。

8.如下代碼執行的結果是?

class Outer {
    public int num = 1;
    class Inner {
        public int num = 2;
        public void show() {
            int num = 3;
            System.out.println(num);
            System.out.println(this.num);
            System.out.println(Outer.this.num);
        }
    }
}
class InnerTest {
    public static void main(String[] args) {
        new Outer().new Inner().show();
    }
}

答:輸出內容以下。code

3
2
1

9.枚舉有哪些應用場景?

答:枚舉類的主要應用場景以下: ① 枚舉類可做爲高級的常量類 示例代碼以下:orm

public enum Color {
    RED("#FF0000", "255,0,0"),
    GREEN("#00FFFF", "0,255,255"),
    YELLOW("#FFFF00", "255,255,0");
    String hex, rgb;
    Color(String hex, String rgb) {
 this.hex = hex;
 this.rgb = rgb;
    }
}

② 枚舉類可方便的用於 switch 判斷 示例代碼以下:

switch(color)
{
case RED:
    System.out.println("紅燈停");
    break;
case GREEN:
    System.out.println("綠燈行");
    break;
case YELLOW:
    System.out.println("看狀況");
    break;
default:
    System.out.println("燈壞了");
}

10.枚舉類在 JVM 中是如何實現的?

答:枚舉類在 JVM(Java 虛擬機) 中實際上是經過普通的 static final 形式實現的。 題目解析:咱們使用 javap 命令來分析枚舉類最終編譯的結果,查看編譯後的結果,就找到了枚舉類在 JVM 中的具體實現了。 首先定義一個枚舉類,代碼以下:

enum DBEnum {
    ORACLE,
    DB2,
    MYSQL,
    SQLSERVER
}

再使用命令 javac DBEnum.java 編譯 .class 文件,而後再使用命令 javap DBEnum.class,咱們看到最終執行的結果以下:

Compiled from "EnumTest.java"
final class DBEnum extends java.lang.Enum<DBEnum> {
public static final DBEnum ORACLE;
public static final DBEnum DB2;
public static final DBEnum MYSQL;
public static final DBEnum SQLSERVER;
public static DBEnum[] values();
public static DBEnum valueOf(java.lang.String);
static {};
}

由此能夠判定,枚舉類在 JVM 中的實現也是經過普通的 static final 實現的。

11.枚舉類能夠被繼承嗎?

答:不能被繼承,由於枚舉類編譯後的實際代碼是 final class 的形式,類被 final 修飾了天然不能被繼承。

12.枚舉類是不是線程安全的?

答:枚舉類是線程安全的,由於枚舉類被編譯後是 final class 的形式存在的,因此枚舉類是線程安全的。

13.枚舉是否能夠被序列化?

答:枚舉是能夠被序列化的,Oracle 官方對此給出了說明,內容以下:

Enum constants are serialized differently than ordinary serializable or externalizable objects. The serialized form of an enum constant consists solely of its name; field values of the constant are not transmitted. To serialize an enum constant, ObjectOutputStream writes the string returned by the constant's name method. Like other serializable or externalizable objects, enum constants can function as the targets of back references appearing subsequently in the serialization stream. The process by which enum constants are serialized cannot be customized; any class-specific writeObject and writeReplace methods defined by enum types are ignored during serialization. Similarly, any serialPersistentFields or serialVersionUID field declarations are also ignored--all enum types have a fixed serialVersionUID of 0L

原文地址:https://docs.oracle.com/javase/8/docs/api/java/io/ObjectOutputStream.html 大體的意思是說:枚舉的序列化和其餘普通類的序列化不一樣,枚舉序列化的時候,只是將枚舉對象的 name 屬性輸出到結果中,反序列化的時候則是經過 java.lang.Enum 的 valueOf 方法根據名字查找枚舉對象。

相關文章
相關標籤/搜索