java编程思想第五版《OnJava8》学习中。。。
⽂章⽬录
注:前期学习内容为第四版,正在重新学习第五版
第⼀章对象的概念
1 重要思想:将对象看作服务的提供者
2 当没有给类或变量声明访问权限时默认是default,此时只能包内访问;⽽protected不同的是⼦类可以访问。
java编程开发高清pdf3 值得强调的是,应该尽量使⽤成员对象,有的时候使⽤继承会使设计更加复杂,有经验的时候,就可以看出哪些场合必须使⽤继承
4 编译器不会产⽣传统意义上的函数调⽤。当⾯向对象发送消息是时被调⽤的代码知道运⾏时才能确定。编译器只负责确保被调⽤⽅法的存在,并对调⽤参数和返回值执⾏类型检查,但是不知道将被执⾏的确切代码
5 书中提到的Java相对于C++的优点
C++中中使⽤数组很危险,因为数组就是内存块,如果⼀个程序要访问其⾃⾝内存块之外的数组或是在初始化之前使⽤数组会有严重的后果;java则不⼀样,它确保数组会初始化,⽽且不能在他的范围之外被访问,虽然占⽤了数组的内存开销及检查下标时使⽤运⾏时的开销,但是保证了安全性
C++中创建对象之后,要⾃⼰销毁,还必须保证对象的保留时间和需要使⽤的时间⼀样长;java不同在于,创建的对象不⽤⾃⼰销毁,垃圾回收器会回收已经没⽤的对象
C++中定义的基本类型变量并没有初始默认值,⽽java中所有类中定义的基本类型的成员变量都有默认值,确保其进⾏了初始化,但是注意⽅法中定义的局部变量并没有默认值
6 UML图
第三章万物皆对象
1 javadoc注释⽂档,在平时⼏乎⽤不到,但是使⽤之后可以让他⼈快速了解我们的代码,如以下代码所⽰,在代码中添加相应的注释块import Date;
/**
* 这个类是⼀个测试类
*
*
*/
public class Test {
/**
* 主⽅法
*/
public static void main(String[] args){
System.out.println(new Date());
}
}
然后点击idea中的⼯具选项,选择⽣成javadoc⽂档,然后进⾏如下设置
然后会有如下效果,注意
只有使⽤/***/进⾏的注释才会出现在doc⽂档中
类的注释应该写在类定义之前;变量注释正好位于变量定义之后;⽅法注释位于⽅法定义前⾯
javadoc只能为public和protected修饰的成员进⾏⽂档注释
@param args array of string ar
@throws exceptions No exceptions thrown
有如下效果
2 赋值问题
对于基本的变量复制,是直接进⾏了值的传递
⽽在为对象赋值的时候,复制的是引⽤的地址
3 ==和equals
==对于基本类型⽐较的是值,⽽对于new处的对象来说⽐较的是对象的引⽤地址
equals 默认⽐较的是引⽤地址,当equals⽅法【被类重写】, 则根据重写⽅法 判断两个对象内容是否相等
4 数值类型
主要看以下代码
public class TestConstant {
public static void main(String[] args){
int ls=0177;//⼋进制
System.out.OctalString(ls));//8进制,前缀为0,运⾏结果:177
System.out.HexString(ls));//16进制,运⾏结果:7f
System.out.BinaryString(ls));//2进制,运⾏结果:1111111
System.out.String(ls));//10进制,运⾏结果:127
long l1=1;
long l2=2L;
float f1=1;
float f2=2f;
System.out.println("l1:"+l1);//运⾏结果:l1:1
System.out.println("l2:"+l2);//运⾏结果:l2:2
System.out.println(l1==1);//运⾏结果:true
System.out.println(l2==1);//运⾏结果:false
System.out.println("f1:"+f1);//运⾏结果:f1:1.0
System.out.println("f2:"+f2);//运⾏结果:f2:2.0
System.out.println(f1==1);//运⾏结果:true
System.out.println(f2==1);//运⾏结果:false
}
}
第四章操作符
1移位操作符
“有符号”右移位操作符(>>)使⽤“符号扩展”:若符号为正,则在⾼位插⼊0;若符号为负,则在⾼位插⼊1
“⽆符号”右移操作符(>>>),它使⽤“零扩展”:⽆论正负,都在⾼位插⼊0,这⼀操作C++中是没有的
如果对char、byte或者short等类型的数值进⾏移位处理,那么在移位进⾏之前,他们会被转换为int类型,并且得到的结果也是int类型
2 负数的⼆进制表⽰
负数在计算机中使⽤⼆进制补码表⽰
原码到反码是除符号位外全部取反
原码到补码是符号位外全部取反再+1
下⾯是⼀些⽐较容易弄混的负数⼆进制表⽰
-1 1111 1111
-127 1000 0001
127 0111 1111
-128 1111 1111
3 三元操作符
boolean-exp? value0 : value1
如果boolean-exp的的结果为true,就计算value0,否则计算value1,计算结果就是这个操作符最终产⽣的结果
值得注意的是,该操作符虽然更加简洁,但是可读性较差
4 字符串操作符+和+=
这两个操作符在java中可以连接不同的字符串
在C++中为了能够对类进⾏操作运算,所以有了操作符重载机制
操作符重载机制:就是对已有的运算符(C++中预定义的运算符)赋予多 重的含义,使同⼀运算符作⽤于不同类型的数据时导致不同类型的 ⾏为。
注:如果+运算中有字符串,那变量将被转化为字符串拼接,不再进⾏数值运算
public class Test53 {
public static void main(String[] args){
int a=1;
int b=2;
String s="";
System.out.println(a+s instanceof  String);//true
System.out.println(a+b+s);//3
}
}
5 类型转换操作符
类型转换(cast)分为了窄化转换(将能容纳更多信息的数据类型转换为⽆法容纳那么多信息的类型,⽐如double转为int)和扩展转换(⽐如int转为double)
注意:
(1)基本类型可以转换为别的类型,除了布尔类型
(2)如下代码所⽰,展⽰了double和float转换为int时默认执⾏截尾操作,如果得到四舍五⼊的整数需要执⾏round()函数
public class Test55 {
public static void main(String[] args){
double above=0.7,below=0.4;
float fabove=0.7f,fbelow=0.4f;
System.out.println("(int)aobve:"+(int)above);//0
System.out.println("(int)aobve:"+(int)below);//0
System.out.println("(int)aobve:"+(int)fabove);//0
System.out.println("(int)aobve:"+(int)fbelow);//0
}
}
(3)如果对基本数据类型执⾏算术运算或按位运算,只要类型⽐int的位数少,那么在运算之前,这些值就会⾃动转换为int
(4) 通常表达式中出现的最⼤数据类型决定了表达式最终结果的数据类型
6 java中没有sizeof()
C和C++中有sizeof(),它的作⽤是得出数据项分配的字节数,⽤于移植性,因为不同的数据类型在不同的机器上分配的⼤⼩可能不同,但是Java不需要,因为他的数据类型在所有的机器中分配的字节数相同
第五章控制执⾏流程
1 Foreach⽅法
如下所⽰,是foreach⽅法的使⽤展⽰
public class Test67 {
public static void main(String[] args){
Random r=new Random(47);
float[] f=new float[10];
for(int i =0; i <10; i++){
f[i]=r.nextFloat();
}
for(float x:f){
System.out.println(x);
}
}
}
优点:
相对于for循环来说,使⽤foreach来遍历数组的可读性更好,虽然他的效率会较低,但是它说明你正在努⼒做什么(例如获取数组中的每⼀个元素),⽽不是给出你正在如何做的细节(⽐如通过创建索引,来获取数组中的每⼀个元素)
2“臭名昭著”的goto
编程语⾔中存在⼀个⾮常便利的跳转语句“goto”。他是在源码级上的跳转,goto的滥⽤会导致⽆法识别程序的控制流程。如下程序展⽰了和goto同原理的标签
public class Test71 {
public static void main(String[] args){
int i=0;
outer://
for(;true;){
inner://
for(;i<10;i++){
System.out.println("i="+i);
if(i==2){
System.out.println("continue");
continue;
}
if(i==3){
System.out.println("break");
i++;
break;
}
if(i==7){
System.out.println("continue outer");
i++;
continue outer;
}
if(i==8){
System.out.println("break outer");
break outer;
}
for(int k =0; k <5; k++){
if(k==3){
System.out.println("continue outer");
continue inner;
}
}
}
}
}
}
原则如下
⼀般的continue会退回最内层循环的开头(顶部),并继续执⾏
带标签的continue回达到标签的位置,并重新进⼊紧接在那个标签后⾯的循环
⼀般的break会中断并跳出当前循环
带标签的break会中断并跳出标签所指的循环
第六章初始化与清理
1 构造函数有没有返回值?
答案是没有,仔细观察构造函数并没有定义返回类型
那么 Test t=new Test(“你好”),这是怎么回事呢
事实上,并不是构造函数有返回内容,⽽是new关键字,在为对象分配空间之后会将引⽤地址返回
2 默认构造器
如果类中没有构造器,则编译器会⾃动帮你创建默认的⽆参构造器
但是如果类中⾃⼰定义了构造器(⽆论有参还是⽆参),编译器就不会创建默认的⽆参构造器
3 垃圾回收
垃圾回收时会调⽤finalize()⽅法,注意这与C++中的析构函数是不同的
对象可能不被垃圾回收
垃圾回收并不等于析构
4 初始化顺序
1 类中所有定义的基本类型和引⽤,不论代码放置在⽅法之前还是⽅法之后,变量的初始胡都发⽣在任何函数的调⽤之前(包括构造函数)
2 静态对象只会在类进⾏⾸次加载class对象时初始化,之后再调⽤该类都不会进⾏初始化
3 静态对象初始化发⽣于⾮静态对象之前
4 每次创建对象的时候,该类所定义的⾮静态基本变量都会进⾏初始化
5 创建对象顺序
概括⼀下创建对象的过程,假设有个名为Dog 的类:
1. 即使没有显式地使⽤static 关键字,构造器实际上也是静态⽅法。所以,当⾸次创建Dog 类型的对象或是⾸次访问Dog 类的静态⽅法
或属性时,Java 解释器必须在类路径中查,以定位Dog.class。
2. 当加载完Dog.class 后(后⾯会学到,这将创建⼀个Class 对象),有关静态初始化的所有动作都会执⾏。因此,静态初始化只会在
⾸次加载Class 对象时初始化⼀次。
3. 当⽤new Dog() 创建对象时,⾸先会在堆上为Dog 对象分配⾜够的存储空间。
4. 分配的存储空间⾸先会被清零,即会将Dog 对象中的所有基本类型数据设置为默认值(数字会被置为0,布尔型和字符型也相同),
引⽤被置为null。
5. 执⾏所有出现在字段定义处的初始化动作。
6. 执⾏构造器。
6 初始化顺序
1. 在实例初始化之前会类初始化,类初始化的内容就是执⾏clinit()函数,它由静态类变量赋值和静态代码块组成(按顺序执⾏,并且只会执⾏⼀次)
2. 在创建实例的时候会进⾏实例初始化执⾏init()函数,即⾮静态的变量、引⽤、代码块,顺序如下
super()
⽗类⾮静态实例变量赋值
⽗类的⾮静态代码块
⽗类的⽆参构造
⼦类
同样的顺序
7 枚举

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。