大量培训机构课程资源,需要加V:【blwxzy_188】
1、final关键字
- 修饰变量:只能赋一次值,且值不能被改变(基本数据类型),引用数据类型(地址不能被改变) 【栈中的值不能变】
- 类变量/常量,在定义时就需要被初始化
- 成员变量:在声明时或者在构造方法中就需要将其初始化
- 局部变量:在局部变量的生存周期中,值不能被改变
- 修饰类:类不能被继承
- 修饰方法:方法不能被重写
2、static关键字
修饰属性:
- 只能修饰成员变量,不能修饰局部变量
- 修饰成员变量,就变成了静态成员变量,那么它是在类加载时就进行初始化,不需要在实例化对象时进行初始化,静态的变量在整个内存中只有一份,被所有对象共享
修饰方法:
- 静态方法,不需要实例化对象就可以被调用,通过类名.的方式就可以调用,不依附于任何对象(不需要通过创建对象来调用)
- 静态方法不能调用非静态方法和非静态变量,非静态的方法可以调用静态方法和静态变量
- 静态的方法或静态变量在JVM加载类时,就已经存在内存中,不会被虚拟机GC回收掉
- 静态方法不能被重写
修饰代码块:
- 用于优化程序,可以将代码中只需要初始化一次的操作,放入代码块中,在类加载时就直接被初始化
3、重写和重载的区别
重写(override):
- 发生在具有继承关系的父子类中,子类重写父类的方法,除了方法体不一样之外,其他的要和父类一模一样,子类的权限修饰符要大于等于父类,不能小于父类,不能比父类抛出更大的异常,抛出的异常类型要小于等于父类。
重载(overload):
- 发生在同一个类中,方法名要相同,参数不同(参数个数,参数类型,参数顺序),其他不做要求,返回值类型,权限修饰符,抛出的异常也不做要求。
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关键词主要用于方法上
- 一个native方法就是一个Java调用非Java代码的接口。一个native方法是指该方法的实现由非Java语言实现,比如用C或C++实现。
- 在定义一个native方法时,并不提供实现体(比较像定义一个Java Interface),因为其实现体是由非Java语言在外面实现的,主要是因为JAVA无法对操作系统底层进行操作,但是可以通过jni(java native interface)调用其他语言来实现底层的访问。
hashCode方法:
- 两个对象堆中的内容相等,则两个对象的哈希值相同。
- 反过来说:两个对象的哈希值不同,则两个对象不一定相同,哈希值的计算是随机的,为了确保等价的两个对象有相同的哈希值,所以一般重写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 等)。它能够创建和编译程序。
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 的区别是什么?
- 可变性
StringBuilder
与 StringBuffer
都继承⾃ AbstractStringBuilder
类,在 AbstractStringBuilder
中也是使⽤字符数组保存字符串 char[]value
但是没有⽤ final
关键字修饰,所以这两种对象都是可变的。
StringBuilder
与 StringBuffer
的构造⽅法都是调⽤⽗类构造⽅法也就是 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% 左右的性能提升,但却要冒多线程不安全的⻛险。
- 总结
- 操作少量的数据: 适⽤
String
- 单线程操作字符串缓冲区下操作⼤量数据: 适⽤
StringBuilder
- 多线程操作字符串缓冲区下操作⼤量数据: 适⽤
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、接口和抽象类的区别是什么?
- 接口的方法默认是
public
,所有方法在接口中不能有实现(Java 8 开始接⼝⽅法可以有默认实现),而抽象类可以有非抽象的方法。 - 接⼝中除了
static 、 final
变量【常量】,不能有其他变量,而抽象类中则不⼀定。 - ⼀个类可以实现多个接⼝,但只能继承⼀个抽象类。接口自己本身可以通过
extends
关键字扩展多个接⼝。 - 接口方法默认修饰符是
public
,抽象⽅法可以有public 、 protected 和 default
这些修饰符(抽象⽅法就是为了被重写所以不能使⽤ private 关键字修饰!)。 - 从设计层⾯来说,抽象是对类的抽象,是⼀种模板设计,⽽接口是对行为的抽象,是⼀种行为的规范。
在 JDK8 中,接⼝也可以定义静态方法,可以直接⽤接⼝名调⽤。实现类和实现是不可以调⽤的。如果同时实现两个接⼝,接⼝中定义了⼀样的默认方法,则必须重写,不然会报错。
关于抽象类
- JDK 1.8以前,抽象类的方法默认访问权限为protected
- JDK 1.8时,抽象类的方法默认访问权限变为default
关于接口
- JDK 1.8以前,接口中的方法必须是public的
- JDK 1.8时,接口中的方法可以是public的,也可以是default的
- JDK 1.9时,接口中的方法可以是private的
15、成员变量与局部变量的区别有哪些?
-
从语法形式上看:
- 成员变量是属于类的,而局部变量是在⽅法中定义的变量或是⽅法的参数;
- 成员变量可以被 public , private , static 等修饰符所修饰,而局部变量不能被访问控制修饰符及
static
所修饰;但是成员变量和局部变量都能被final
所修饰。
-
从变量在内存中的存储方式来看:
- 如果成员变量是使⽤
static
修饰的,那么这个成员变量是属于类的,如果没有使⽤static
修饰,这个成员变量是属于实例的。对象存于堆内存。 - 如果局部变量类型为基本数据类型,那么存储在栈内存,如果为引⽤数据类型,那存放的是指向堆内存对象的引⽤或者是指向常量池中的地址。
- 如果成员变量是使⽤
-
从变量在内存中的生存时间上看:
- 成员变量是对象的⼀部分,它随着对象的创建而存在,而局部变量随着⽅法的调⽤而自动消失。
-
成员变量如果没有被赋初值:
- 则会⾃动以类型的默认值而赋值(⼀种情况例外:被
final
修饰的成员变量也必须显式地赋值),而局部变量则不会⾃动赋值。
- 则会⾃动以类型的默认值而赋值(⼀种情况例外:被
16、访问修饰符public,private,protected,以及不写时的区别?
17、hashCode 与 equals(你重写过 hashcode 和 equals 么,为什么重写 equals 时必须重写hashCode ⽅法?)
-
hashCode()介绍:
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回⼀个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。 hashCode() 定义在 JDK 的 Object 类中,这就意味着 Java 中的任何类都包含有hashCode() 函数。另外需要注意的是: Object 的 hashcode ⽅法是本地方法,也就是⽤ c 语⾔或 c++ 实现的,该方法通常用来将对象的内存地址转换为整数之后返回。
public native int hashCode();
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利⽤到了散列码!(可以快速找到所需要的对象)。
-
为什么要有 hashCode?
以“
HashSet
如何检查重复”为例⼦来说明为什么要有hashCode
?当你把对象加入
HashSet
时,HashSet
会先计算对象的hashcode
值来判断对象加入的位置,同时也会与其他已经加⼊的对象的hashcode
值作比较,如果没有相符的hashcode
,HashSet
会假设对象没有重复出现。但是如果发现有相同hashcode
值的对象,这时会调⽤equals()
⽅法来检查hashcode
相等的对象是否真的相同。如果两者相同,HashSet
就不会让其加⼊操作成功。如果不同的话,就会重新散列到其他位置。这样我们就⼤⼤减少了equals
的次数,相应就大大提高了执行速度。 -
为什么重写 equals 时必须重写 hashCode 方法?
如果两个对象相等,则
hashcode
⼀定也是相同的。两个对象相等,对两个对象分别调⽤equals
方法都返回true
。但是,两个对象有相同的hashcode
值,它们也不⼀定是相等的 。 因此,equals
方法被覆盖过,则hashCode
方法也必须被覆盖。hashCode()
的默认行为是对堆上的对象产⽣独特值。如果没有重写hashCode()
,则该class 的两个对象⽆论如何都不会相等(即使这两个对象指向相同的数据) -
为什么两个对象有相同的 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= 来修改上限值:
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、八种基本类型及其字节数
32、i++和++i的异同之处
共同点:
-
i++和++i都是变量自增1,都等价于i=i+1
-
如果i++,++i是一条单独的语句,两者没有任何区别
-
i++和++i的使用仅仅针对变量。 5++和++5会报错,因为5不是变量。
不同点:
-
如果i++,++i不是一条单独的语句,他们就有区别
i++ //先赋值后自增 ++i //先自增再赋值
33、自动类型转换原则
小类型可以转为大类型,大类型转小类型需要进行强制类型转换
34、this和super关键字的作用
- this是对象内部指代自身的引用,同时也是解决成员变量和局部变量同名问题;this可以调用成员变量,不能调用局部变量。
- this也可以调用成员方法,但是在普通方法中可以省略this,在构造方法中不允许省略,必须是构造方法的第
一条语句。而且在静态方法当中不允许出现this关键字。 - super代表对当前对象的直接父类对象的引用,super可以调用直接父类的成员变量(注意权限修饰符的影响,比如不能访问private成员)。
- super可以调用直接父类的成员方法(注意权限修饰符的影响,比如不能访问private成员)。
- super可以调用直接父类的构造方法,只限构造方法中使用,且必须是第一条语句。
35、不通过构造函数也能创建对象吗?
- 用
new
语句创建对象。 - 运用反射手段。
- 调用对象的clone()方法。
- 运用反序列化手段,调用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 中的异常处理
异常结构图
在
Java
中,所有的异常都有⼀个共同的祖先 java.lang 包中的Throwable
类。
Throwable
类有两个重要的⼦类Exception (异常)
和Error (错误)
。Exception
能被程序本身处理( trycatch )
。Error
是⽆法处理的(只能尽量避免)。
Exception
和Error
⼆者都是 Java 异常处理的重要⼦类,各⾃都包含⼤量⼦类。Exception
:程序本身可以处理的异常,可以通过 catch 来进⾏捕获。Exception
⼜可以分
为 受检查异常(必须处理) 和 不受检查异常(可以不处理)。Error
:Error
属于程序⽆法处理的错误 ,我们没办法通过 catch 来进⾏捕获 。例如,Java 虚拟机运⾏错误( Virtual MachineError )、虚拟机内存不够错误( OutOfMemoryError )、类定义错误( NoClassDefFoundError )等 。这些异常发⽣时, Java虚拟机(JVM)⼀般会选择线程终⽌。
受检查异常
- 受检查异常没有被 catch / throw 处理的话,就没办法通过编译
- 除了
RuntimeException
及其⼦类以外,其他的 Exception 类及其⼦类都属于检查异常 。常⻅的受
检查异常有:IO 相关的异常
、ClassNotFoundException
、SQLException
…。
不受检查异常
- 即使不处理不受检查异常也可以正常通过编译。
RuntimeException
及其⼦类都统称为⾮受检查异常,例如:NullPointExecrption
、NumberFormatException
(字符串转换为数字)、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);
}
StringUtils.isEmpty(String str)
判断某字符串是否为空,为空的标准是str==null
或str.length()==0
StringUtils.isBlank(String str)
判断某字符串是否为空或长度为 0 或由空白符 (whitespace) 构成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