自增和自减(++和–)
前递增和前递减(如++A或–A),会先执行运算,再生成值.而对于后递增和后递减(如A++或A–),会先生成值,再执行运算.
==和equals()
在java中,双等符号比较的就是对象的句柄而不是对象的内容,equals在默认情况下也是比较的是句柄而不是内容.Integer等类型是可以使用equals方法的,并且是重写了equals方法,在这里比较的是内容而不是句柄,所以当内容相等时即为true.
关于句柄的解释
关于java中的引用,在think in java这本书中解释为"句柄"(handle).
java中就是用"句柄"来操纵对象的
在java中,任何东西都可以看做是对象,因此,我们可以采用一种统一的语法,任何地方均可照搬不误.但要注意,尽管将一切都"看作"对象,但操纵的标识符实际是指向一个对象的"句柄"(handle).在其他java参考书中,还可看到有的人将其称作一个"引用",甚至一个"指针".可将这一情形想象成用遥控板(句柄)操纵电视机(对象).只要握住这个遥控板,就相当于掌握了与电视机连接的通道.但一旦需要"换频道"或者"关小声音",我们实际操纵的是遥控板(句柄),再由遥控板自己操纵电视机(对象).如果要在房间里四处走走,并想保持对电视机的控制,那么手上拿着的是遥控板,而非电视机.
此外,即使没有电视机,遥控板亦可独立存在.也就是说,只是由于拥有一个句柄,并不表示必须有一个对象同它连接.
短路(&& ||)
操作逻辑运算符时,遇到一种短路的情况,这意味着只有明确得出整个表达式真或假的结论,才会对表达式进行逻辑求职.因此,一个逻辑表达式的所有部分都有可能不进行求值.
如果一个逻辑表达式的所有部分都不必执行下去,那么潜在的性能提升将是相当可观的.
按位运算符
按位运算符允许我们操作一个整数主数据类型中的单个"比特",即二进制位.按位运算符会对两个自变量中对应的位执行布尔代数,并最终生成一个结果.
AND(&)与,OR(|)或,XOR(^)异或,NOT(~)非.我们将boolean类型当作一种"单位"或"单比特"值对待,所以它多少有些独特的地方.我们可执行按位AND,OR和XOR,但不能执行NOT.对于布尔值,按位运算符具有与逻辑运算符相同的效果,只是它们不会中途"短路".此外,针对布尔值进行的按位运算为我们新增了一个XOR逻辑运算符,它并未包括在"逻辑"运算符的列表中.
移位运算符
移位运算符面相的运算对象也是二进制的"位".可单独用它们处理整数类型(主类型的一种).左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧的位数(在低位补0).“有符号"右移位运算符(>>)则将运算符左边的运算对象向右移动运算符右侧指定的位数.“有符号"右移运算符使用了"符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1.java也添加了一种"无符号"右移位运算符(>>>),它使用了"零扩展”:无论正负,都在高位插入0.若对char,byte或者short进行移位处理,那么在移位进行之前,它们会自动转换成一个int.只有右侧的5个低位才会用到.这样可防止我们在一个int数里移动不切实际的位数.若对一个long值进行处理,最后得到的结果也是long.此时只会用到右侧的6个低位,防止移动超过long值里现成的位数.
移位可与符号(<<=或>>=或>>>=)组合使用.此时,运算符左边的值会移动由右边的值指定的位数,再将得到的结果赋回左边的值.
逗号运算符
java里需要用到逗号的唯一场所就是for循环.
while(x=y){}
在java里,这个x=y这个表达式的结果并不是布尔值,而编译器期望的是一个布尔值,而且不会从一个int数值中转换得来.所以在编译时,系统就会提示出现错误,有效地阻止我们进一步运行程序.所以这个缺点字java里永远不会造成更严重的后果.唯一不会得到编译错误的时候是x和y都为布尔值.在这种情况下,x=y属于合法表达式.
关于1.39e-47f的含义
e在科学与工程学领域,表示的是自然对数的基数,约为2.718.
但是上述表达式,在java中,真正含义是"1.39X10的-47次方";与自然对数的基数无关.
关于标签
java中只在使用循环的时候支持使用标签.
例如:
int i=0;
outer:
while(){
continue outer;
}
这个示例代码指,调回到outer处开始继续进行循环.值得注意的是,单层循环使用标签用处不大,标签主要使用在双重循环时,当内层循环执行中想要跳出两层循环可以使用标签.
这里可以简单提下goto,goto是java的保留字,在c中goto可以理解为跳转,因为goto的滥用,而且goto是在源码的级别跳转的,所以招致了不好的声誉.后来goto就使用的少了.
java中的goto作为保留字,目前没有具体功能.java中循环中用到的标签有点类似于goto.在java里唯一需要用到的标签的地方就是拥有嵌套循环,而且想中断或继续多个嵌套级别的时候.
转型
将一个float或double值转型成整数值后,总是将小数部分"砍掉",不作任何进位处理.
关于this关键字
如果两个同类型的对象,分别叫做a和b,当这两个对象同是调用一个方法f()时,并不知道如何为两个对象同时调用这一个方法.
class Banana { void f(int i) { /* … */ } }
Banana a = new Banana(), b = new Banana();
a.f(1);
b.f(2);
若只有一个名叫f()的方法,它怎样才能知道自己是为a还是为b调用的呢?
为了能用简便的,面向对象的语法来书写代码–亦即"将消息发给对象",编译器为我们完成了一些幕后工作.其中的秘密就是第一个自变量传递给方法f(),而且那个自变量是准备操作的那个对象的句柄.所以前述的两个方法调用就变成了下面这样的形式:
Banana.f(a,1);
Banana.f(b,2);
这是内部的表达式,我们并不能这样书写表达式,并试图让编译器接受它.
假定我们在一个方法的内部,并希望获得当前对象的句柄.由于那个句柄是由编译器"秘密"传递的,所以没有标识符可用.然而,针对这一目的有个专用的关键字:this.this关键字(注意只能在方法内部使用)可为已调用了其方法的那个对象生成相应的句柄.可像对待其他任何对象句柄一样对待这个句柄.但要注意,假若准备从自己某个类的另一个方法内部调用一个类方法,就不必使用this.只需简单地调用那个方法即可.当前的this句柄自动应用其他方法.
this关键字只能用于那些特殊的类–需明确使用当前对象的句柄.例如,假若您希望将句柄返回给当前对象,那么它经常在return语句中使用.
public class Leaf {
private int i = 0;
Leaf increment() {
i++;
return this;
}
…
由于increment()通过this关键字返回当前对象的句柄,所以可以方便地对同一个对象执行多项操作.
在构建起里调用构建器(构造方法)
若为一个类写了多个构建器,那么经常都需要在一个构建器里调用另一个构建器,以避免写重复的代码.可用this关键字做到这一点.
尽管可用this调用一个构建器,但不可调用两个.构建器调用必须是第一件事情.
static的含义
它意味着一个特定的方法没有this.我们不可从一个static方法内部发出对非static方法的调用,尽管反过来说是可以的.而且在没有任何对象的前提下,我们可针对类本身发出一个static方法的调用.事实上,那正是static方法最基本的意义.它就好像我们创建一个全局函数的等价物(在c中).除了全局函数不允许在java中使用以外,若将一个static方法置入一个类的内部,它就可以访问其他static方法以及static字段.
有可能发生在static方法内部发出对非static方法的调用的一种情况是我们将一个对象句柄传到static方法内部.随后,通过句柄(此时实际是this),我们可调用非static方法,并访问static字段.但一般地,如果真的想要这样做,只要制作一个普通的,非static方法即可.
垃圾回收
一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存.所以如果使用dinalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作.
(下面的说法需具体看jvm的不同)
到程序结束的时候,并非所有收尾模块都会得到调用.为强制进行收尾工作,可先调用system.gc(),再调用system.runFinalization().这样可清除到目前为止没有使用的所有对象.这样做一个稍显奇怪的地方是在调用runFinalization()之前调用gc(),这看起来似乎与sun公司的文档说明有些抵触,它宣城首先运行收尾模块,再释放存储空间.然而,若在这里首先调用runFinalization(),再调用gc(),收尾模块根本不会执行.
gc在java中有gc线程进行控制,gc线程的死亡与主线程一致.