Java高频必背面试题基础篇02
一、Java 语⾔中关键字 static 的作⽤是什么?
static 的主要作⽤有两个:
(1)为某种特定数据类型或对象分配与创建对象个数⽆关的单⼀的存储空间。
(2)使得某个⽅法或属性与类⽽不是对象关联在⼀起,即在不创建对象的情况下可通过类直接调⽤⽅法或使⽤类的属性。
static 具体可分为 4 种使⽤⽅式:
(1)修饰成员变量。⽤ static 关键字修饰的静态变量在内存中只有⼀个副本。只要静态变量所在的类被加载,这个静态变量就会被分配空间,可以使⽤“类.静态变量”和“对象.静态变量”的⽅法使⽤。
(2)修饰成员⽅法。static 修饰的⽅法⽆需创建对象就可以被调⽤。static ⽅法中不能使⽤ this 和 super 关键字,不能调⽤⾮ static ⽅法,只能访问所属类的静态成员变量和静态成员⽅法。
(3)修饰代码块。JVM 在加载类的时候会执⾏ static 代码块。static 代码块常⽤于初始化静态变量。static代码块只会被执⾏⼀次。
(4)修饰内部类。static 内部类可以不依赖外部类实例对象⽽被实例化。静态内部类不能与外部类有相同的名字,不能访问普通成员变量,只能访问外部类中的静态成员和静态成员⽅法。
二、为什么要把 String 设计为不可变?
(1)节省空间:字符串常量存储在 JVM 的字符串池中可以被⽤户共享。
(2)提⾼效率:String 可以被不同线程共享,是线程安全的。在涉及多线程操作中不需要同步操作。
(3)安全:String 常被⽤于⽤户名、密码、⽂件名等使⽤,由于其不可变,可避免⿊客⾏为对其恶意修改。
三、简述 String/StringBuffer 与 StringBuilder。
(1)String 类采⽤利⽤ final 修饰的字符数组进⾏字符串保存,因此不可变。如果对 String 类型对象修改,需要新建对象,将⽼字符和新增加的字符⼀并存进去。
(2)StringBuffer,采⽤⽆ final 修饰的字符数组进⾏保存,可理解为实现线程安全的 StringBuilder。
(3)StringBuilder,采⽤⽆ final 修饰的字符数组进⾏保存,因此可变。但线程不安全。
四、判等运算符“==” 与equals的区别?
(1)“== ” ⽐较的是引⽤,equals ⽐较的是内容。
(2)如果变量是基础数据类型,“== ”⽤于⽐较其对应值是否相等。如果变量指向的是对象,“== ”⽤于⽐较两个对象是否指向同⼀块存储空间。
(3)equals 是 Object 类提供的⽅法之⼀,每个 Java 类都继承⾃ Object 类,所以每个对象都具有 equals 这个⽅法。Object 类中定义的 equals ⽅法内部是直接调⽤ == ⽐较对象的。但通过覆盖的⽅法可以让它不是⽐较引⽤⽽是⽐较数据内容。
五、简述 Object 类常⽤⽅法。
(1)hashCode:通过对象计算出的散列码。⽤于 map 型或 equals ⽅法。需要保证同⼀个对象多次调⽤该⽅法,总返回相同的整型值。
(2)equals:判断两个对象是否⼀致。需保证 equals ⽅法相同对应的对象 hashCode 也相同。
(3)toString: ⽤字符串表示该对象。
(4)clone:深拷⻉⼀个对象。
六、Java 中⼀维数组和⼆维数组的声明⽅式?
⼀维数组的声明⽅式:
type arrayName[]
type[] arrayName
⼆维数组的声明⽅式:
type arrayName[][]
type[][] arrayName
type[] arrayName[]
其中 type 为基本数据类型或类,arrayName 为数组名字。
七、简述 Java 异常的分类。
Java 异常分为 Error(程序⽆法处理的错误),和 Exception(程序本身可以处理的异常)。这两个类均继承 Throwable。
(1)Error 常⻅的有 StackOverFlowError、OutOfMemoryError 等等。
(2)Exception 可分为运⾏时异常和⾮运⾏时异常。对于运⾏时异常,可以利⽤ try catch 的⽅式进⾏处理,也可以不处理。对于⾮运⾏时异常,必须处理,不处理的话程序⽆法通过编译。
八、简述 throw 与 throws 的区别。
(1)throw ⼀般是⽤在⽅法体的内部,由开发者定义当程序语句出现问题后主动抛出⼀个异常。
(2)throws ⼀般⽤于⽅法声明上,代表该⽅法可能会抛出的异常列表。
九、出现在 Java 程序中的 finally 代码块是否⼀定会执⾏?
(1)当遇到下⾯情况不会执:
当程序在进⼊ try 语句块之前就出现异常时会直接结束;
当程序在 try 块中强制退出时,如使⽤ System.exit(0),也不会执⾏ finally 块中的代码。
(2)其它情况下,在 try/catch/finally 语句执⾏的时候,try 块先执⾏,当有异常发⽣,catch 和 finally 进⾏处理后程序就结束了,当没有异常发⽣,在执⾏完 finally 中的代码后,后⾯代码会继续执⾏。值得注意的是,当 try/catch 语句块中有 return 时,finally 语句块中的代码会在 return 之前执⾏。如果try/catch/finally 块中都有 return 语句,finally 块中的 return 语句会覆盖 try/catch 模块中的 return 语句。
十、final、finally 和 finalize 的区别是什么?
(1)final ⽤于声明属性、⽅法和类,分别表示属性不可变、⽅法不可覆盖、类不可继承。
(2)finally 作为异常处理的⼀部分,只能在 try/catch 语句中使⽤,finally 附带⼀个语句块⽤来表示这个语句最终⼀定被执⾏,经常被⽤在需要释放资源的情况下。
(3)finalize 是 Object 类的⼀个⽅法,在垃圾收集器执⾏的时候会调⽤被回收对象的 finalize()⽅法。当垃圾回收器准备好释放对象占⽤空间时,⾸先会调⽤ finalize()⽅法,并在下⼀次垃圾回收动作发⽣时真正回收对象占⽤的内存。
十一、简述泛型。
泛型,即“参数化类型”,解决不确定对象具体类型的问题。在编译阶段有效。在泛型使⽤过程中,操作的数据类型被指定为⼀个参数,这种参数类型在类中称为泛型类、接⼝中称为泛型接⼝和⽅法中称为泛型⽅法。
十二、简述泛型擦除。
Java 编译器⽣成的字节码是不包涵泛型信息的,泛型类型信息将在编译处理是被擦除,这个过程被称为泛型擦除。
十三、简述注解。
Java 注解⽤于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执⾏,但也有⼀些类型的注解实际上可以⽤于这⼀⽬的。
其可以⽤于提供信息给编译器,在编译阶段时给软件提供信息进⾏相关的处理,在运⾏时处理写相应代码,做对应操作。
十四、简述元注解。
元注解可以理解为注解的注解,即在注解中使⽤,实现想要的功能。其具体分为:
@Retention: 表示注解存在阶段是保留在源码,还是在字节码(类加载)或者运⾏期(JVM 中运⾏)。
@Target:表示注解作⽤的范围。
@Documented:将注解中的元素包含到 Javadoc 中去。
@Inherited:⼀个被@Inherited 注解了的注解修饰了⼀个⽗类,如果他的⼦类没有被其他注解修饰,则它的⼦类也继承了⽗类的注解。
@Repeatable:被这个元注解修饰的注解可以同时作⽤⼀个对象多次,但是每次作⽤注解⼜可以代表不同的含义。
十五、简述 Java 中 Class 对象。
java 中对象可以分为实例对象和 Class 对象,每⼀个类都有⼀个 Class 对象,其包含了与该类有关的信
息。
获取 Class 对象的⽅法:
Class.forName(“类的全限定名”)
实例对象.getClass()
类名.class