Thinking in java 读书笔记(P84 ~ P104)
作者:淮左白衣
写于:2018年4月10日16:42:57
目录
this 为什么可以代表调用对象
我们都知道,在一个非静态方法的内部,this 代表当前调用方法的对象 ;
其中的原因在于:当我们调用一个对象的方法的时候,编译器自己做了一些幕后工作;会把调用方法的对象的引用,作为第一个参数传给方法 ;这样,在方法内部,就可以获取到对象的引用了,java里面使用了 this 代表编译器传进来的在个参数 ;这就是this在方法内部代表调用对象的原因 ;
在构造器中,同样可以使用this ;this(xxxx) ;
这个有点特殊:构造器实质是一个静态方法;(出自Thinking in java P96)
数组
- 在java中,在定义数组的时候,引用 是 不允许指定数组大小的;
int[3] chars = null ; // error
- 下面的定义数组的两种方式,在内存空间分配上是 等价 的 ;
int[] a = new int[]{1,2,4} ;
int[] b = {1,2,4} ;
数组的默认初始化
关于数字的类型,会被默认初始化为 0 ;
字符会被默认为 u0000 ,但是我们人眼看不到这个字符,是一个空白 ;
对象引用会被默认初始化为 null ;
数组中的 length
java的所有类型的数组中都有一个固定成员 length ,它记录着数组的长度,每次我们访问数组,数组都会进行一次下标是否越界的检测 ,而检测就是根据下标与 length 的比较;
定义数组的3种方式
//方式一
int[] a = new int[]{1,2,4} ;
//方式二
int[] b = {1,2,4} ;
//方式三
int[] c = new int[3];
c[0] = 0 ;
c[1] = 1 ;
c[2] = 2 ;
可变参数列表
用于 参数个数不确定 的情况下 ,可以把它想象成一个 数组,只是这个数组的长度不定;其实,在使用的时候,我们也是把可变参数列表当做数组使用的 ;
在使用可变参数列表,编译器帮我们做了一些事
- 我们不再需要显示的写数组语法了,而是可以直接的传值进入,编译器会帮我们把值转换成数组的 ;
// 方法接受一个可变参数列表
public void test3(int... num){
''''''
}
//调用方法,可以直接传值进去
test3(2,3,5);
//假如,你闲的没事,也可以自己显示的写数组语法
test3(new int[]{2,3,5});
- 可以传0个参数进去,也就是说可以直接什么都不传
public void test3(int... num){
''''''
}
//可以什么都不传
test3();
- 支持自动装箱
public void test3(Integer... num){
''''''
}
//支持直接装箱
test3(2,3,5);
// 支持夹杂在一起的装箱
test3(2,new Integer(3),5);
涉及可变参数列表的重载
请看下面的代码:
public void test2(){
test3(1,'1');
test3('a','a'); // 编译失败
}
public void test3(float i,Character... num){
.....
}
public void test3(Character... num){
.....
}
上面的代码,在写的时候,IDE是不会报任何语法错误的,这个最为致命的 ;需要手动编译,才会报错;报错的原因是:编译器不知道该调用哪一个方法 ;
为什么编译器不知道该调用哪一个方法了呢?
你可能会认为,不应该啊,‘a’ 被自动装箱为 Character 类型,然后调用 public void test3(Character… num) 方法 ;没错啊!如果你产生这样的疑问,可以看下作者的这篇博客,关于基本类型的方法重载 ;
看完你会发现,其实这里,由于剧本数据类型的重载, ‘a’ 也会被提升到 float 类型 ,因此,编译器有两个选择,它就不知道具体调用哪一个方法了,因此报错了;
如何避免这样的问题
为每一个使用可变参数列表,都指定一个非可变参数,或者在重载的时候,只允许一个重载方法使用可变参数列表 ;
public void test2(){
test3(1,'1');
test3('a','a');
}
public void test3(float i,Character... num){
}
public void test3(char c,Character... num){
}