建议收藏!2021进大厂必备的Java基础核心面试题-V1.0

大量培训机构课程资源,需要加V:【blwxzy_188】

1、final关键字

  • 修饰变量:只能赋一次值,且值不能被改变(基本数据类型),引用数据类型(地址不能被改变) 【栈中的值不能变】
    • 类变量/常量,在定义时就需要被初始化
    • 成员变量:在声明时或者在构造方法中就需要将其初始化
    • 局部变量:在局部变量的生存周期中,值不能被改变
  • 修饰类:类不能被继承
  • 修饰方法:方法不能被重写

2、static关键字

修饰属性

  • 只能修饰成员变量,不能修饰局部变量
  • 修饰成员变量,就变成了静态成员变量,那么它是在类加载时就进行初始化,不需要在实例化对象时进行初始化,静态的变量在整个内存中只有一份,被所有对象共享

修饰方法

  • 静态方法,不需要实例化对象就可以被调用,通过类名.的方式就可以调用,不依附于任何对象(不需要通过创建对象来调用)
  • 静态方法不能调用非静态方法和非静态变量,非静态的方法可以调用静态方法和静态变量
  • 静态的方法或静态变量在JVM加载类时,就已经存在内存中,不会被虚拟机GC回收掉
  • 静态方法不能被重写

修饰代码块

  • 用于优化程序,可以将代码中只需要初始化一次的操作,放入代码块中,在类加载时就直接被初始化

3、重写和重载的区别

重写(override)

  • 发生在具有继承关系的父子类中,子类重写父类的方法,除了方法体不一样之外,其他的要和父类一模一样,子类的权限修饰符要大于等于父类,不能小于父类,不能比父类抛出更大的异常,抛出的异常类型要小于等于父类。

重载(overload)

  • 发生在同一个类中,方法名要相同,参数不同(参数个数,参数类型,参数顺序),其他不做要求,返回值类型,权限修饰符,抛出的异常也不做要求。
    image-20210407112719079

4、abstract关键字

  • 修饰类: 抽象类
    • 不能被实例化,不能new对象,不能和final关键字连用(final关键字修饰的类不能被继承),因为abstract关键字修饰的类是用来被继承的。
    • 抽象类中也不可以存在静态的变量和静态方法,抽象类没有主体,不能通过类名.的方式调用静态的变量或者静态的方法。
  • 修饰方法:叫做抽象方法,是专门被子类重写的,则该方法的权限修饰符不能为private,也不能是static的。
  • 抽象类可以包含抽象方法也可以不包含抽象方法,但抽象方法必须存在于抽象类或者接口中。

5、==和equals的区别

  • 双等号 :判断的是栈中的值是否相等
  • equals:重写之后判断的是堆中的值,没有重写调用的是Object类中的equals,底层实现的还是用双等号 ,所以这个方法一般建议重写,再扯的细一点,讲基本数据类型比较用==和引用数据类型比较用equals

6、Object类中的方法

  • native clone();:克隆方法 创建并返回此对象的一个副本
  • final native getClass();:获取类的Class对象
  • toString();:将对象转换成字符串输出
  • equals();:结合hashCode一起被重写,可以结合==将一遍
  • native hashCode();:结合集合来学习
  • finalize();:GC垃圾回收器自己调用,回收垃圾内存用的,释放资源用的

线程之间通信的三个方法

  • final native wait();:让线程进入阻塞状态
  • fianl native notify();:唤醒当前线程
  • fianl native notifyAll();:唤醒所有线程

native关键词主要用于方法上

  1. 一个native方法就是一个Java调用非Java代码的接口。一个native方法是指该方法的实现由非Java语言实现,比如用C或C++实现。
  2. 在定义一个native方法时,并不提供实现体(比较像定义一个Java Interface),因为其实现体是由非Java语言在外面实现的,主要是因为JAVA无法对操作系统底层进行操作,但是可以通过jni(java native interface)调用其他语言来实现底层的访问。

hashCode方法:

  1. 两个对象堆中的内容相等,则两个对象的哈希值相同。
  2. 反过来说:两个对象的哈希值不同,则两个对象不一定相同,哈希值的计算是随机的,为了确保等价的两个对象有相同的哈希值,所以一般重写equals方法时需要把hashCode方法也重写。

7、JVM JDK 和 JRE 的区别和联系

JVM:运⾏ Java 字节码的虚拟机。 JVM 有针对不同系统的特定实现(Windows, Linux, macOS),⽬的是使⽤相同的字节码,它们都会给出相同的结果。

JRE: 是 Java 运⾏时环境。它是运⾏已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM), Java 类库, java 命令和其他的⼀些基础构件。但是,它不能⽤于创建新程序,只能运行Java程序。

JDK: 是 Java开发工具包,它拥有 JRE 所拥有的⼀切,还有编译器(javac)和⼯具(如 javadoc 等)。它能够创建和编译程序。

image-20210407112340909

8、构造器 Constructor 是否可被 override?

Constructor 不能被 override(重写) ,但是可以 overload(重载) ,所以你可以看到⼀个类中有多个构造函数的情况。

9、String 为什么是不可变的?

String 类中使⽤ final关键字修饰字符数组来保存字符串, private final charvalue[],所以 String 对象是不可变的。

在 Java 9 之后, String 类的实现改⽤ byte 数组存储字符串private final byte[] value

10、StringBuffer 和 StringBuilder 的区别是什么?

  • 可变性

StringBuilderStringBuffer 都继承⾃ AbstractStringBuilder 类,在 AbstractStringBuilder中也是使⽤字符数组保存字符串 char[]value 但是没有⽤ final关键字修饰,所以这两种对象都是可变的。

StringBuilderStringBuffer 的构造⽅法都是调⽤⽗类构造⽅法也就是 AbstractStringBuilder 实现的 。

AbstractStringBuilder.java 源码

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
    * The value is used for character storage.
    */
    char[] value;
    /**
    * The count is the number of characters used.
    */
    int count;
    AbstractStringBuilder(int capacity) {
    value = new char[capacity];
}
  • 线程安全性

String中的对象是不可变的,也就可以理解为常量,线程安全。

StringBuffer对⽅法加了同步锁或者对调⽤的⽅法加了同步锁,所以是线程安全的。

StringBuilder并没有对⽅法进⾏加同步锁,所以是⾮线程安全的。

  • 性能

每次对String类型进⾏改变的时候,都会⽣成⼀个新的 String对象,然后将指针指向新的String对象。

StringBuffer每次都会对 StringBuffer对象本身进⾏操作,⽽不是⽣成新的对象并改变对象引⽤。

相同情况下使⽤ StringBuilder相⽐使⽤StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的⻛险。

  • 总结
  1. 操作少量的数据: 适⽤ String
  2. 单线程操作字符串缓冲区下操作⼤量数据: 适⽤ StringBuilder
  3. 多线程操作字符串缓冲区下操作⼤量数据: 适⽤ StringBuffer

11、String和StringBuilder、StringBuffer能被继承吗?

三者都不能,原因:全部都是final修饰的,final修饰的类不能被继承

源码:

public final class String
    
    
public final class StringBuffer  
    

public final class StringBuilder    

12、String长度有限制吗?

  • 首先字符串的内容是由一个字符数组char[] 来存储的,由于数组的长度及索引是整数,且 String 类中返回字符串长度的方法 length() 的返回值也是 int ,所以通过查看 Java 源码中的类 Integer 我们可以看到 Integer 的最大范围是 2^31 -1,由于数组是从 0 开始的,所以数组的最大长度可以是【0~2^31】通过计算是大概 4GB。
  • 但是通过翻阅 Java 虚拟机手册对 class 文件格式的定义以及常量池中对 String 类型的结构体定义我们可以知道对于索引定义了 u2,就是无符号占 2 个字节,2 个字节可以表示的最大范围是 2^16 -1 = 65535。所以实际大小为65535,但是由于 JVM 需要 1 个字节表示结束指令,所以这个范围就为 65534 了。超出这个范围在编译时期是会报错的,但是运行时拼接或者赋值的话范围是在整形的最大范围

13、在⼀个静态方法内调用⼀个非静态成员为什么是非法的?

  • 由于静态方法可以不通过new对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员。
  • 其次静态方法在类加载时进行初始化的,在类加载时,非静态成员还尚未初始化

14、接口和抽象类的区别是什么?

  1. 接口的方法默认是 public ,所有方法在接口中不能有实现(Java 8 开始接⼝⽅法可以有默认实现),而抽象类可以有非抽象的方法。
  2. 接⼝中除了static 、 final变量【常量】,不能有其他变量,而抽象类中则不⼀定。
  3. ⼀个类可以实现多个接⼝,但只能继承⼀个抽象类。接口自己本身可以通过 extends关键字扩展多个接⼝。
  4. 接口方法默认修饰符是public ,抽象⽅法可以有 public 、 protected 和 default 这些修饰符(抽象⽅法就是为了被重写所以不能使⽤ private 关键字修饰!)。
  5. 从设计层⾯来说,抽象是对类的抽象,是⼀种模板设计,⽽接口是对行为的抽象,是⼀种行为的规范。

在 JDK8 中,接⼝也可以定义静态方法,可以直接⽤接⼝名调⽤。实现类和实现是不可以调⽤的。如果同时实现两个接⼝,接⼝中定义了⼀样的默认方法,则必须重写,不然会报错。

关于抽象类

  • JDK 1.8以前,抽象类的方法默认访问权限为protected
  • JDK 1.8时,抽象类的方法默认访问权限变为default

关于接口

  • JDK 1.8以前,接口中的方法必须是public的
  • JDK 1.8时,接口中的方法可以是public的,也可以是default的
  • JDK 1.9时,接口中的方法可以是private的

15、成员变量与局部变量的区别有哪些?

  1. 从语法形式上看:

    • 成员变量是属于类的,而局部变量是在⽅法中定义的变量或是⽅法的参数;
    • 成员变量可以被 public , private , static 等修饰符所修饰,而局部变量不能被访问控制修饰符及static所修饰;但是成员变量和局部变量都能被final 所修饰。
  2. 从变量在内存中的存储方式来看:

    • 如果成员变量是使⽤static修饰的,那么这个成员变量是属于类的,如果没有使⽤static修饰,这个成员变量是属于实例的。对象存于堆内存。
    • 如果局部变量类型为基本数据类型,那么存储在栈内存,如果为引⽤数据类型,那存放的是指向堆内存对象的引⽤或者是指向常量池中的地址。
  3. 从变量在内存中的生存时间上看

    • 成员变量是对象的⼀部分,它随着对象的创建而存在,而局部变量随着⽅法的调⽤而自动消失。
  4. 成员变量如果没有被赋初值:

    • 则会⾃动以类型的默认值而赋值(⼀种情况例外:被final修饰的成员变量也必须显式地赋值),而局部变量则不会⾃动赋值。

16、访问修饰符public,private,protected,以及不写时的区别?

image-20210408112120378

17、hashCode 与 equals(你重写过 hashcode 和 equals 么,为什么重写 equals 时必须重写hashCode ⽅法?)

  1. hashCode()介绍:

    hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回⼀个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。 hashCode() 定义在 JDK 的 Object 类中,这就意味着 Java 中的任何类都包含有hashCode() 函数。另外需要注意的是: Object 的 hashcode ⽅法是本地方法,也就是⽤ c 语⾔或 c++ 实现的,该方法通常用来将对象的内存地址转换为整数之后返回。

    public native int hashCode();
    

    散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利⽤到了散列码!(可以快速找到所需要的对象)。

  2. 为什么要有 hashCode?

    以“ HashSet 如何检查重复”为例⼦来说明为什么要有 hashCode

    当你把对象加入HashSet 时, HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加⼊的对象的 hashcode 值作比较,如果没有相符的 hashcodeHashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调⽤ equals() ⽅法来检查 hashcode 相等的对象是否真的相同。如果两者相同, HashSet 就不会让其加⼊操作成功。如果不同的话,就会重新散列到其他位置。这样我们就⼤⼤减少了 equals 的次数,相应就大大提高了执行速度。

  3. 为什么重写 equals 时必须重写 hashCode 方法?

    如果两个对象相等,则 hashcode ⼀定也是相同的。两个对象相等,对两个对象分别调⽤ equals方法都返回 true。但是,两个对象有相同的hashcode值,它们也不⼀定是相等的 。 因此,equals 方法被覆盖过,则 hashCode方法也必须被覆盖。

    hashCode() 的默认行为是对堆上的对象产⽣独特值。如果没有重写hashCode(),则该class 的两个对象⽆论如何都不会相等(即使这两个对象指向相同的数据)

  4. 为什么两个对象有相同的 hashcode 值,它们也不⼀定是相等的?

    因为 hashCode() 所使⽤的算法也许刚好会让多个对象传回相同的值。越糟糕的算法越容易碰撞,但这也与数据值域分布的特性有关(所谓碰撞也就是指的是不同的对象得到相同的 hashCode)。

    我们刚刚也提到了 HashSet ,如果 HashSet 在对⽐的时候,同样的 hashcode 有多个对象,它会使⽤ equals() 来判断是否真的相同。也就是说 hashcode 只是⽤来缩小查找成本。

18、String s = new String(“xyz”) 创建了几个字符串对象?

  • 一个或两个。如果字符串常量池已经有“xyz”,则是一个;否则,两个。

  • 当字符创常量池没有 “xyz”,此时会创建如下两个对象:

    • 一个是字符串字面量 “xyz” 所对应的、驻留(intern)在一个全局共享的字符串常量池中的实例,此时该实例也是在堆中,字符串常量池只放引用。
    • 另一个是通过 new String() 创建并初始化的,内容与"xyz"相同的实例,也是在堆中。

19、String s = “xyz” 和 String s = new String(“xyz”) 区别?

  • 两个语句都会先去字符串常量池中检查是否已经存在 “xyz”,如果有则直接使用,如果没有则会在常量池中创建 “xyz” 对象。

  • 另外,String s = new String(“xyz”) 还会通过 new String() 在堆里创建一个内容与 “xyz” 相同的对象实例。

所以前者其实理解为被后者的所包含。

20、下面两个代码块能正常编译和执行吗?

// 代码块1
short s1 = 1; s1 = s1 + 1;
// 代码块2
short s1 = 1; s1 += 1;

代码块1编译报错,原因:1默认是int类型,s1是short类型, int类型不能自动转换为short类型,需要进行强制类型转换。

代码块2正常执行,因为s1 += 1会隐式的进行强制类型转换(short)(s1 + 1)

21、指出下题的输出结果

public static void main(String[] args) {
    Integer a = 128, b = 128, c = 127, d = 127;
    System.out.println(a == b);//false
    System.out.println(c == d);//true
}

包装类和基本数据类型的自动装箱和自动拆箱

Integer 中引入了IntegerCache来缓存一定范围的值,IntegerCache默认情况下范围为:-128~127

这个缓存范围时可以修改的,可以通过JVM启动参数:-XX:AutoBoxCacheMax= 来修改上限值:

img

22、Java 序列化中如果有些字段不想进⾏序列化,怎么办?

对于不想进行序列化的变量,使用transient关键字修饰。

transient关键字的作用是:阻止实例中那些用此关键字修饰的变量序列化;当对象被反序列化时,被transient修饰的变量值不会被持久化和恢复。

transient只能修饰变量,不能修饰类和方法

23、switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上?

switch可以作用在byte,short,char,int,【及其对应的包装类】enum(枚举),String

不可作用于:long,boolean,float,double【及其包装类】

24、可以自定义 java.lang.String 类并使用吗?

可以自定义 java.lang.String 类并编译成功,但不能被加载使用。

原因:就在于双亲委派机制,用户自定义的加载器会将加载请求向上委派给父类加载器,如果父类加载器还有自己的父加载器,就继续向上委派。最终会由最顶层的加载器执行本次请求。顶层的加载器就是启动类加载(Bootstrap ClassLoader),启动类加载器会在自己的加载范围内(比如rt.jar包)下查找java.lang.String(原本的String就是在rt.jar包下)。此时在rt.jar包下找到了java.lang.String进行加载,所以自己写的String虽然也在自定的包java.lang下也没用呀。除非父类加载器在自己的加载范围内找不到要加载的类,才会反过来向下让子类加载器加载。

25、String 与 byte[]两者相互之间如何转换?

  • String > byte[] 通过 String 类的 getBytes 方法;
  • byte[] > String 通过 new String(byte[])构造器。

26、main 方法能被重载吗?

可以被重载,在一个类中,可以存在多个main方法

27、main 方法能被覆盖/重写吗?

main方法不能被重写,main方法是static的静态方法,不能被重写。

28、main 方法的返回类型是什么?能不能改变?

void,不能改变

29、main 方法的作用域用什么修饰?能不能改变?

public,不能改变

30、main 方法可以同步吗?

main 方法可以在 Java 中同步, synchronized 修饰符允许用于 main 方法的声明中,这样就可
以在 Java 中同步 main 方法了。

31、八种基本类型及其字节数

image-20210413104218731

32、i++和++i的异同之处

共同点:

  1. i++和++i都是变量自增1,都等价于i=i+1

  2. 如果i++,++i是一条单独的语句,两者没有任何区别

  3. i++和++i的使用仅仅针对变量。 5++和++5会报错,因为5不是变量。

不同点:

  1. 如果i++,++i不是一条单独的语句,他们就有区别

    i++  //先赋值后自增
    ++i  //先自增再赋值    
    

33、自动类型转换原则

小类型可以转为大类型,大类型转小类型需要进行强制类型转换
image-20210413110845821

34、this和super关键字的作用

  • this是对象内部指代自身的引用,同时也是解决成员变量和局部变量同名问题;this可以调用成员变量,不能调用局部变量。
  • this也可以调用成员方法,但是在普通方法中可以省略this,在构造方法中不允许省略,必须是构造方法的第
    一条语句。而且在静态方法当中不允许出现this关键字。
  • super代表对当前对象的直接父类对象的引用,super可以调用直接父类的成员变量(注意权限修饰符的影响,比如不能访问private成员)。
  • super可以调用直接父类的成员方法(注意权限修饰符的影响,比如不能访问private成员)。
  • super可以调用直接父类的构造方法,只限构造方法中使用,且必须是第一条语句。

35、不通过构造函数也能创建对象吗?

  1. new语句创建对象。
  2. 运用反射手段。
  3. 调用对象的clone()方法。
  4. 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
  • (1)和(2)都会明确的显式的调用构造函数 ;

  • (3)是在内存上对已有对象的影印,所以不会调用构造函数 ;

  • (4)是从文件中还原类的对象,也不会调用构造函数。

36、存在使i+1<i的数么?

存在, byte , int等基本数据类型的最大值, 加1后变为负数.

public class Test {
    public static void main(String[] args) {
        byte a = 127;
        byte b = (byte) (a+1);
        System.out.println(a+"\t"+b);
    }
} 

//输出结果
127 -128

37、接口可否继承接口?抽象类是否可实现接口?抽象类是否可继承实体类?

  • 接口可以继承接口
  • 抽象类可以实现接口
  • 抽象类可以继承实体类

38、为什么 Java 中只有值传递?

Java 程序设计语⾔总是采⽤按值调⽤。也就是说,⽅法得到的是所有参数值的⼀个拷⻉,也就是说,⽅法不能修改传递给它的任何参数变量的内容。

  • ⼀个⽅法不能修改⼀个基本数据类型的参数(即数值型或布尔型)。
  • ⼀个⽅法可以改变⼀个对象参数的状态。
  • ⼀个⽅法不能让对象参数引用⼀个新的对象。

39、Java 中的异常处理

异常结构图

image-20210416000439256

image-20210416000525473

Java 中,所有的异常都有⼀个共同的祖先 java.lang 包中的 Throwable 类。

  • Throwable 类有两个重要的⼦类 Exception (异常)Error (错误)
    • Exception能被程序本身处理( trycatch )
    • Error 是⽆法处理的(只能尽量避免)。
  • ExceptionError⼆者都是 Java 异常处理的重要⼦类,各⾃都包含⼤量⼦类。
    • Exception :程序本身可以处理的异常,可以通过 catch 来进⾏捕获。 Exception ⼜可以分
      为 受检查异常(必须处理) 和 不受检查异常(可以不处理)。
    • ErrorError属于程序⽆法处理的错误 ,我们没办法通过 catch 来进⾏捕获 。例如,Java 虚拟机运⾏错误( Virtual MachineError )、虚拟机内存不够错误( OutOfMemoryError )、类定义错误( NoClassDefFoundError )等 。这些异常发⽣时, Java虚拟机(JVM)⼀般会选择线程终⽌。

受检查异常

  • 受检查异常没有被 catch / throw 处理的话,就没办法通过编译
  • 除了 RuntimeException 及其⼦类以外,其他的 Exception 类及其⼦类都属于检查异常 。常⻅的受
    检查异常有:IO 相关的异常ClassNotFoundExceptionSQLException…。

不受检查异常

  • 即使不处理不受检查异常也可以正常通过编译。
  • RuntimeException及其⼦类都统称为⾮受检查异常,例如: NullPointExecrptionNumberFormatException (字符串转换为数字)、 ArrayIndexOutOfBoundsException (数组越界)、ClassCastException (类型转换错误)、 ArithmeticException(算术错误)等。

40、Throwable 类常⽤⽅法

  • public string getMessage():返回异常发生时的简要描述
  • public string toString() :返回异常发生时的详细信息
  • public string getLocalizedMessage() :返回异常对象的本地化信息。使⽤ Throwable的⼦类覆盖这个⽅法,可以⽣成本地化信息。如果⼦类没有覆盖该⽅法,则该⽅法返回的信息与getMessage()返回的结果相同
  • public void printStackTrace() :在控制台上打印 Throwable 对象封装的异常信息

41、 Error 和 Exception 区别是什么?

  • Error 类型的错误通常为虚拟机相关错误,如系统崩溃,内存不足,堆栈溢出等,编译器不会对这类错误进行检测,JAVA 应用程序也不应对这类错误进行捕获,一旦这类错误发生,通常应用程序会被终止,仅靠应用程序本身无法恢复;
  • Exception 类的错误是可以在应用程序中进行捕获并处理的,通常遇到这种错误,应对其进行处理,使应用程序可以继续正常运行。

42、运行时异常和一般异常(受检异常)区别是什么?

运行时异常包括 RuntimeException 类及其子类,表示 JVM 在运行期间可能出现的异常。 Java 编译器不会检查运行时异常。

受检异常是Exception 中除 RuntimeException 及其子类之外的异常。 Java 编译器会检查受检异常。

RuntimeException异常和受检异常之间的区别:是否强制要求调用者必须处理此异常,如果强制要求调用者必须进行处理,那么就使用受检异常,否则就选择非受检异常(RuntimeException)。一般来讲,如果没有特殊的要求,我们建议使用RuntimeException异常。

43、throw 和 throws 的区别是什么?

  • throw关键字用在方法内部,只能用于抛出一种异常,用来抛出方法或代码块中的异常,受查异常和非受查异常都可以被抛出。
  • throws关键字用在方法声明上,可以抛出多个异常,用来标识该方法可能抛出的异常列表。一个方法用 throws 标识了可能抛出的异常列表,调用该方法的方法中必须包含可处理异常的代码,否则也要在方法声明中用 throws 关键字声明相应的异常。

43、throw 和 throws 的区别是什么?

  • throw关键字用在方法内部,只能用于抛出一种异常,用来抛出方法或代码块中的异常,受查异常和非受查异常都可以被抛出。
  • throws关键字用在方法声明上,可以抛出多个异常,用来标识该方法可能抛出的异常列表。一个方法用 throws 标识了可能抛出的异常列表,调用该方法的方法中必须包含可处理异常的代码,否则也要在方法声明中用 throws 关键字声明相应的异常。

44、Java字符型常量和字符串常量的区别?

  • 形式上: 字符常量是单引号引起的一个字符; 字符串常量是双引号引起的 0 个或若干个字符
  • 含义上: 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置)
  • 占内存大小 字符常量只占 2 个字节; 字符串常量占若干个字节

45、isEmpty 和 isBlank 区别?

org.apache.commons.lang.StringUtils 类提供了 String 的常用操作,最为常用的判空有如下两种 isEmpty(String str)isBlank(String str)

分析

我们通过源码来分析区别:

public static boolean isEmpty(String str) {
    return str == null || str.length() == 0;
}

public static boolean isNotEmpty(String str) {
    return !isEmpty(str);
}

public static boolean isBlank(String str) {
    int strLen;
    if (str != null && (strLen = str.length()) != 0) {
        for(int i = 0; i < strLen; ++i) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return false;
            }
        }

        return true;
    } else {
        return true;
    }
}

public static boolean isNotBlank(String str) {
    return !isBlank(str);
}
  1. StringUtils.isEmpty(String str) 判断某字符串是否为空,为空的标准是 str==nullstr.length()==0
  2. StringUtils.isBlank(String str) 判断某字符串是否为空或长度为 0 或由空白符 (whitespace) 构成
  3. StringUtils.isNotEmpty(String str) 等价于 !isEmpty(String str)

46、Java 8有哪些特性

  • 函数式接口
  • 接口可以有实现方法,而且不需要实现类去实现其方法。
  • lambda表达式
  • stream流
  • 日期时间 API LocalDateTime年月日十分秒;LocalDate日期;LocalTime时间

47、把一个逗号隔开的字符串变成一个集合的,类似于(“1,2,3”)这种

  • List myList = Arrays.stream(myArray).collect(Collectors.toList()),建议使用这种方式,而不是List myList = Arrays.asList(1, 2, 3);

  • 至于原因就是Arrays.asList()将数组转换为集合后,底层其实还是数组

48、Java获取反射的三种方法

  • new 一个对象,然后对象.getClass()方法
  • 通过 Class.forName() 方法
  • 使用 类.class

49、深拷贝和浅拷贝的区别

image-20210419102942031

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蚂蚁爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值