【面试题每日学习】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 方法根据名字查找枚举对象。

相关文章
相关标签/搜索