一、Java数组中toString()
问题描述:我定义了一个类,类名是Job,当我输出Job.toString()是可以按我重载的toString方法输出的,但是如果输出jobs[]这个数组时,只会输出[Lmodel.Job;@45e228。那么这是为什么呢?怎么输出数组内容呢?
解决方法:使用Arrays.toString(jobs)来输出。,
分析:java里,所有的类,不管是java库里面的类,或者是你自己创建的类,全部是从object这个类继承的。object里有一个方法就是toString(),那么所有的类创建的时候,都有一个toString的方法。这个方法是干什么的呢?
首先我们得了解,java输出用的函数print();是不接受对象直接输出的,只接受字符串或者数字之类的输出。
当print检测到输出的是一个对象而不是字符或者数字时,那么它会去调用这个对象类里面的toString 方法,输出结果为[类型@哈希值]。Object类中的toString()方法的源代码如下:
/** * Returns astringrepresentationoftheobject. In general,the* toString
method returns astringthat*"textually represents"this object. Theresultshould * be a concisebutinformative representationthatiseasyfora * persontoread. * Itisrecommendedthatall subclasses override this method. *
* The toString
methodforclassObject
* returns astringconsistingofthenameoftheclassofwhichthe* objectisan instance,theat-signcharacter`@
',and*theunsigned hexadecimal representationofthehash codeofthe* object. In otherwords, this method returns astringequaltothe* valueof: *
* * @returnastringrepresentationoftheobject. */public String toString() {returngetClass().getName() +"@"+ Integer.toHexString(hashCode());}*
* getClass().getName() + '@' + Integer.toHexString(hashCode()) *
而数组类中并没有对此方法重写(override),仅仅是重载(overload)为类的静态方法(参见java.util.Arrays)。所以,数组直接使用toString()的结果也是[类型@哈希值]。所以数组转为字符串应写成:Arrays.toString(a) 。
这种方法的toString()是带格式的,也就是说输出的是[a, b, c],如果仅仅想输出abc则需用以下两种方法:
方法1:直接在构造String时转换。
char[] data = {'a','b','c'};Stringstr =newString(data);
方法2:调用String类的方法转换。
String.valueOf(char[] ch)
二、Java中数组为null 和数组长度为0的区别
A、两者如果在一句代码中,则要先判断是否为空,否则可能会出现空指针异常。
eg:
if(array == null || 0 == array.length) {...} // 这种写法正确,因为执行到 “0 == array.length”则说明数组不为空,不会产生空指针异常。
if (0 == array.length || array == null) {...} // 这种写法可能会产生空指针异常。
例:
int[] n; //只声明了一数组变量;
int[] nil = null; //声明一数组变量,并赋值 null,nil是一个数组类型的空引用,不指向任何对象;
int[] zero = new int[0]; //声明并创建一数组对象,长度是0;
B、Java语言支持两种数据类型,分别是基本数据类型和引用数据类型,而 null 是一种特殊的引用数据类型。
Student stu = new Student(); // 语句1
Student stu2; // 语句2
stu2 = new Student(); // 语句3
语句 1 先声明一个 Student 类型的变量 stu,然后利用 new 关键字为其创建实例。一步到位,定义了一个实例变量并同时赋值。
语句 2 是声明一个 Student 类型的变量 stu2,虽然从表述习惯上讲 stu2 是实例变量,但实际上此时 stu2 并未成为一个真正的实例,它仅仅只是一个变量名字。
语句 3 中的 stu2 才成为了一个 Student 实例,它指向了内存中的某块地址空间。
为了明确表示那些仅有名字而没有内存空间的变量的具体内容,Java 引入了关键字 null。 null 表示“空”的意思,是绝对意义上的空,这个空指的是不存在。
一个引用变量(当变量指向一个对象时,这个变量就被称为引用变量)没有通过 new 分配内存空间,这个对象就是空对象,Java 使用关键字 null 表示空对象。示例代码如下:
String str1= null;
str1 = "C语言中文网";
注意:null 是关键字,是大小写敏感的,不能将 null 写成 Null 或 NULL。
引用变量的默认值是 null。当试图调用一个空对象的属性或方法时,会抛出空指针异常(NullPointerException),如下代码所示:
String str1; // 相当于 String str1= null;
// 输出null字符串
System.out.println(str1);
// 调用length()方法
int len = str1.length();
第 5 行代码不会发生编译错误,但是当代码运行到第 5 行时,系统会抛出空指针异常。这是因为调用 length() 方法时,str1 是空对象。程序员应该避免调用空对象的属性和方法。
判断一个对象是否为 null,可以用if (obj == null) { }来判断。代码如下:
// 判断对象是否为null
if (str1 != null) {
int len = str1.length();
}
如果把上面代码改成如下代码:
String str2 = "";
int num = str2.length();
System.out.println(num); // 输出结果为0
运行以上代码时没有抛出异常,因为 str2 是一个值为""的字符串对象。""表示的是一个长度为 0 的空字符串,它在内存中会被分配一个空间,str2 是直接指向""内存空间的实例化对象。
产生空对象主要有以下两种可能性:
程序员自己忘记了实例化,所以程序员必须防止这种情况发生,应该仔细检查自己的代码,为自己创建的所有对象进行实例化并初始化。
空对象是其它地方传递过来的,需要通过判断对象是否为 null 进行避免。