Java编程思想
个人对于这本书的解读,首先说明这本书非常不错, 不过专有名词太多了,内容来说不是很容易理解,不过很不错, 感兴趣的可以购买自行阅读
毕竟我也是一枚萌新,讲是不太会,不过还是多看/敲吧,里面大部分还是直接干代码,不定期更新,感兴趣一起讨论
前言
关于书里简单的常识,可能一笔带过,涉及的大部分都是比较有意思的,毕竟开始看书的,一般都是想夯实一下基本,理解细节,本书的引用都是java编程思想的原话,希望可以帮到阅读起来困难的’你’,一起加油吧。
一、对象导论
1.暂时不跟新
二、一切都是对象
1.暂时不跟新
三、操作符
1.暂时不跟新(小点)
2.赋值
“=”:简单来说就是把右边的值赋值给左面的值 比如:int a=9;
把9赋值给自变量a,类型简单常用就不提了好玩的是对象
对象的赋值:
对一个对象操作的时,我们真正操作的是对对象的引用。所以倘若"对一个对象赋值给另一个对象",实际上是将’引用’从一个地方赋值到另一个地方。
----操作符(赋值)
对象的赋值直接上代码:
public class Client02 {
public static void main(String[] args) {
//空间位置两个
Tank tank01 = new Tank();
Tank tank02 = new Tank();
tank01.level = 9;
tank02.level = 27;
System.out.println("tank01.level: " + tank01.level);//tank01.level: 9
System.out.println("tank02.level: " + tank02.level);//tank02.level: 27
System.out.println("=======================================");//=======================================
//两个空间位置指向同一个引用
tank01 = tank02;
//tank01.level = tank02.level;
System.out.println("tank01.level: " + tank01.level);//tank01.level: 27
System.out.println("tank02.level: " + tank02.level);//tank02.level: 27
System.out.println("========================================");//========================================
//无论操作任何一个都会改变另一个
tank02.level = 9;
System.out.println("tank01.level: " + tank01.level);//tank01.level: 9
System.out.println("tank02.level: " + tank02.level);//tank02.level: 9
}
}
class Tank {
int level;
}
此处你无论是tank02/tank01都会修改原来的值
赋值操作的是一个对象的引用,所以修改t1的同时也改变了t2!这是由于t1和t2包含的引用,他们指向相同的对象 ----本书对于上面的解释
debug一下打断点在t1那行,F7,单步调试到第一次的赋值结束:
得到如下的图:
开辟两个对象不同空间没有问题,继续 赋值的时候:
对象引用相同了,无论你操作t1/t2都会修改相应的值,到这应该差不多了,
这种特殊的现象通常称作’别名现象’,对应的解决方式就是别我注释的那行 tank01.level = tank02.level;这样边可以保持两个对象彼此独立,而不是将t1和t2绑定到相同的对象。但你很快意识到,直接操作对象内的域
荣容易导致混乱,并且,违背了良好的面向对象程序设计的原则。----引用
看一下debug的测试:
引用没有发生改变,值发生改变所以可以,书里面还说了一个方法调用中的别名问题
public class Client03 {
//满足关系式,传递一个引用,覆盖值
//Letter y=Letter letter;
static void f(Letter y) {
y.c = 'z';
}
public static void main(String[] args) {
Letter letter = new Letter();
letter.c = 'a';
System.out.println("1: letter.c: " + letter.c);//1: letter.c: a
System.out.println("=============================");
f(letter);
System.out.println("2: letter.c: " + letter.c);//2: letter.c: z
System.out.println("=============================");
System.out.println("3: letter.c: " + letter.c);//3: letter.c: z
}
}
class Letter {
public Letter() {
}
char c;
}
方法调用中的别名问题其实和上面的一样,在方法传递的时候经历了引用赋值://Letter y=Letter letter;也就是y=lettr,所以我测试了第三次调用依旧是z,也就是引用只有一个且指向y(不过地址没有改变,两个对象使用同一个引用)猜测不过应该差不多,可以留言讨论。
到此,结束祝君:前程似锦
3.自动自增和递减
对于前缀递增和前缀递减(++a/–a),会先执行运算,再生成值。
而对于后缀递增和后缀递减(a++/–a),会先生成值,在执行运算。 ---- java编程思想
直接上书上面的源代码:
int i = 1;
System.out.println("i :" + i); //1
System.out.println("++i :" + ++i); //2
System.out.println("i++ :" + i++); //2
System.out.println("i :" + i); //3
System.out.println("--i :" + --i); //2
System.out.println("i-- :" + i--); //2
System.out.println("i :" + i); //1
这一段代码结合上面一段话的可能比较容易理解(但还是比较模糊),分解一下:
i++:源文件
int i = 2;
System.out.println(i++); //2
System.out.println(i); //3
i++:在下一次操作数值才会更变,关于它的值得变化:查看target下生成的class文件
i++:编译后的文件
//.class里面编译后的文件
int i = 2;
byte var10001 = i; //类似一个i++的过渡值
int i = i + 1; //重新声明一个变量i
System.out.println(var10001); //var10001 = 2
System.out.println(i); //i = 2 + 1 ;
它会自己重新声明一个新的变量,并使用,覆盖刚开始的i值
++i:直接上代码
int i = 2;
System.out.println(++i); //3
System.out.println(i); //3
++i:的class编译后的文件:
int i = 2;
int i = i + 1;
System.out.println(i); //不需要使用一个类似过渡值的变量
System.out.println(i); //直接使用新创建变量
不需要使用一个类似i++的过渡值的变量,而是直接使用新创建变量
再来一段有趣的代码:
刚开始学的时候应该会听到 ++i == i+=1为什么?
int i = 1;
System.out.println(i += 1); //2
查看一下编译后的.class文件:
int i = 1;
int i = i + 1;
System.out.println(i);
有点意思,一模一样(除了我上面写的初始值是2),所以++i本身就是对i+=1的简化
再来看一下刚开始的那段代码的.class文件:
int i = 1;
System.out.println("i :" + i); //i =1
PrintStream var10000 = System.out;
StringBuilder var10001 = (new StringBuilder()).append("++i :");
int i = i + 1;
var10000.println(var10001.append(i).toString());//++i =2
System.out.println("i++ :" + i++); //i++ =2
System.out.println("i :" + i); //i =3
是不是有所悟了,之后i++进行上面的操作,自己可以动手实践一下,不然可能不过深刻,然后你可能发现有趣的事情
改变前java源文件:
int i = 2; //下一步后的值
System.out.println(i++);//2 --3
System.out.println(i++);//3 --4
改变前.class编译后的文件
int i = 2;
int var2 = i + 1;
System.out.println(i);
System.out.println(var2++);
目前和上面一样,没有神奇的地方
改变后java源文件:
int i = 2;
System.out.println(i++);//2
System.out.println(i++);//3
System.out.println(++i);//5
改变后.class编译后的文件
int i = 2;
int i = i + 1;
System.out.println(i); //2 第一个i
System.out.println(i++);//3 第二个i
++i;
System.out.println(i); //5
变量名直接一样,有点难看出来i指向的值了,你可以这样理解
int i = 2;
System.out.println(i); //2
int i = i + 1;
System.out.println(i++); //3
++i;
System.out.println(i); //5
至于,再底层的东西选择当前class编译后的文件----右击----open in terminal 命令javap -c 当前编译后的.class文件名,自行阅读
到此,结束祝君:前程似锦