1)基础类型带来的便利与不便
java作为纯面向对象语言,编程思维宣称一切都是对象,java的所有对象都有一个共同的父类-Object,但事情总有例外,可能是为了延续编程语言基本操作连贯性,java还是保留了基础类型(主要包括int,char,short,boolean,long等),这些类型定义的变量不是Object,
一开始每次要人手工在封装类型和基础类型之间转化,这给写程序带来小小的麻烦
后来java加入了自动封装和解封装的特性,由此带来容易犯的另一个问题
经常会碰到由于封装类型转化导致的NullPointException异常,
比如如下这段代码
public class Foo {
Integer count;
public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } public static void main(String[] args) { Foo foo = new Foo(); int i; i = foo.getCount();
}
}
如果你运行,会发生NPE异常。可能上面的代码还比较直观看出异常来,但在实际工程中,如果这些数据来自于数据库或外部参数设定,而我们又在潜意识中认为这些值不可能为空的情况,那很可能就在不知不觉中犯下这些小错误,测试时都一切正常,一旦上线,抛出NPE异常,故障随之而来。
2)java潜在已有的值对象
java为了性能考虑,会内置一些初始化的值。比如从-128到127的数字,26个字母等,程序员很少关心,实际上大多情况下也不需要关心,但有时候这会导致一些违背我们原本思维逻辑的情况,会费解。
public static void main(String[] args) {
Integer a =
1000;
Integer b =
1000;
System.
out.println(a == b);
Integer c =
100;
Integer d =
100;
System.
out.println(c == d);
}
运行上段代码会返回false,true。因为100是内置已有的值对象,c和d指向的都是同一个内置值对象。
所以不是所有的对象都是重新生成的,我们不必害怕重复生成了很多常用值会导致内存浪费。
3)到底是传值还是传引用
按照c++参数传递给我们的基本印象,一开始会认为java的参数传递是传应用,我们在方法内部修改参数的值,运行完该方法后,参数对象的内容确实被改变了,这个和c++传引用得到的效果类似,因此我相信大多数人凭直觉会认为java也是传引用的。但是java确实是传值的,而我们根据概念知道传值的话,参数对象的内容就不应该会被改变,那么如何解释这个对象被修改了呢?
事实上java传过去的是参数地址的值,而不是参数本身的内容,这就是java所谓的传值,那么后续对这个参数地址值的修改离开方法后是无效的,但通过调用参数对象的方法修改参数的值,确实是生效的。
public class Foo {
Integer
count;
public Integer getCount() {
return
count;
}
public void setCount(Integer count) {
this.
count = count;
}
public static void main(String[] args) {
Foo foo =
new Foo();
foo.setCount(
100);
Foo.
checkreference(foo);
System.
out.print(
"return parameter value:" + foo.getCount());
Foo.
checkvalue(foo);
System.
out.print(
"return parameter value:" + foo.getCount());
}
public static void checkreference(Foo foo){
foo.setCount(
101);
}
public static void checkvalue(Foo foo){
Foo tmp =
new Foo();
tmp.setCount(
99);
foo = tmp;
}
}
运行上面这个程序,输出结果是101,101。你会发现,第一个是调用参数对象的方法改变了参数的内容(从100改到101),第二个试图直接改变参数对象的值(想改为99),结果没有改动(还是101)。
这里又有个例外,就是String类型的参数怎么就不能改值呢?因为String类型是immutable类型,即它的值对象不可变,每次在方法内修改String类型的参数内容其实是生成了一个新String对像,因此离开方法后,那个String类型的参数对象还是原来的值,并没改变。
转载请注明原文地址: https://ju.6miu.com/read-1123677.html