Java基础,庞大而繁杂,这里记录一下常见的误区。
目录
2、String str = "i"与 String str = new String("i")是一样吗?
4、项目中的PO,VO,DAO,BO,POJO,DTO的区别
1、字符串中的空串、Null串是一回事吗?
搞清楚 空串 与 Null串 的区别,先通过代码测试一下:
public class Test {
public static void main(String[] args) {
String str1 = ""; // 空串
String str2 = null; // Null串
System.out.println("空串测试--->" + str1.length()); // 0
System.out.println("空串测试--->" + str1.equals("")); // true
System.out.println("空串测试--->" + (str1 == "")); // true
System.out.println("空串测试--->" + str1.equals(null)); // false
System.out.println("Null串测试--->" + (str2 == null)); // true
System.out.println("Null串测试--->" + (str2 == "")); // false
System.out.println("Null串测试--->" + str2.equals(null)); // java.lang.NullPointerException
System.out.println("Null串测试--->" + str2.length()); // java.lang.NullPointerException
}
}
从测试结果可以看出,二者不是一回事,区别如下:
- 空串是一个有长度(为0)和内容(为"")的Java对象,可以用 == 和 equals() 比较;
- Null串是一个用 null 表示值的变量,但无任何Java对象与该变量进行关联,不能用equals()比较,也不能用length()方法测量长度。
因此,实际中判断一个字符串变量str既不能为空串,也不能为null的推荐写法如下:
if (str != null && str.length() != 0) {
// TODO
}
2、String str = "i"与 String str = new String("i")是一样吗?
探讨这个问题之前要明确以下几个问题:
- String类重写了equals()方法,进行equals比较时,比较的是两个对象的内容,而 == 则比较的是两个对象的地址;
- 在Java虚拟机的内存管理中的运行时数据区域划分中,堆区域通常存储的是Java对象,方法区(看作非堆)有一个常量池,顾名思义存储了Java中定义的常量,而Java虚拟机栈(简称栈)上则会存储堆中对象的引用。
有了这些基础之后,就简单了,还是代码先测试一下:
public class Test {
public static void main(String[] args) {
String str1 = "i";
String str2 = new String("i");
System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // true
}
}
分析:str1 和 str2 作为引用变量均存放在栈上,str1 指向方法区常量池的常量i,而 str2 也有一个指向方法区常量池的常量i,由于已经存在了常量i,str2 不会再去创建该常量了,但接下来会通过new的方式在堆中开辟一段内存空间存储对象,str2 指向该对象,画个图就能理解了。因此,str1 和 str2的内容是一样的,但内存地址不一样。
3、声明数组:int[] a,b[],该怎么理解这种声明?
分析:将a和b分开书写的话就是:int[] a; int[] b[]; ,也就是说a是一个一维数组,b是一个二维数组,能够通过编译的赋值如下:
public class Test {
public static void main(String[] args) {
int[] a = new int[0];
int[] b[] = new int[0][];
b[0] = a; // 表示数组
b[0][0] = a[0]; // 表示数组元素
}
}
4、项目中的PO,VO,DAO,BO,POJO,DTO的区别
问题:
每个Java项目都会存在类似entity的包,里面存放了许多的实体类,那么以PO,VO,DAO,BO,POJO,DTO等结尾的类表示什么含义呢,有什么区别?
区别:
- PO:persistant object (持久化对象),可以看成是与数据库中的表相映射的java对象。最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合。PO中应该不包含任何对数据库的操作。
- VO:value object (值对象)。通常用于业务层之间的数据传递,和PO一样也是仅仅包含数据而已。但应是抽象出的业务对象,可以和表对应,也可以不,这根据业务的需要.个人觉得同DTO(数据传输对象),在web上传递。
- DAO:data access object (数据访问对象),此对象用于访问数据库。通常和PO结合使用,DAO中包含了各种数据库的操作方法。通过它的方法结合PO对数据库进行相关的操作。
- BO:business object (业务对象),封装业务逻辑的java对象,通过调用DAO方法,结合PO、VO进行业务操作。
- POJO:plain old java object (简单无规则java对象),我个人觉得它和其他不是一个层面上的东西,VO和PO应该都属于它。
- DTO:Data Transfer Object(数据传输对象),主要用于远程调用等需要大量传输对象的地方。
5、Sting字符串最长有多长?
在 String 类内部,是使用一个字符数组(char[])来维护字符序列的,String 的最大长度也就是字符数组的最大长度,理论上最大长度为 int 类型的最大值(0x7ffffff),即 2147483647个字节。在实际中,受硬件影响,一般可获取的最大值小于理论最大值,在我的电脑上得出的最大值是2147483548。
通过以下代码测试下:
public class Test {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
int len = Integer.MAX_VALUE - i;
try {
System.out.println("len: " + len + " OK");
} catch (Error e) {
System.out.println("len: " + len + " " + e);
}
}
}
}
持续整理中......