Ps:本篇文章,主要用于记录Java基本语句中,一些异于C/C++的语法!
1.Java程序的运行机制:
Java运行机制是一种编译型和解析型组合的运行机制。简单描述下:Java通过编译先生成*.class文件(与平台无关的字节码),编译生成的*.class文件,用于被Java虚拟机Jvm解析。这样只要实现不同平台的Jvm,就可以实现Java的跨平台的特性,还可以通过Jvm实现Java的垃圾回收机制,使Java具备解析型语言具备的动态特质!
2.C++中virtual关键字:
Java中不再使用virtual关键字;解释下原因,面向过程的编程语言,在代码编译的时候已经明确了,函数调用的绝对地址,称之为前期绑定;而面向对象的语言,部分场景下如多态场景下,期望于在代码运行的时候,根据具体运行时的类型进行调用函数(既函数调用地址的查找),称之为后期绑定。C++中默认的是前期绑定,使用virtual来定义后期绑定;Java中默认为后期绑定!所以不再需要virtual关键字!
3.Java 7引入数据中的下划线:
Java 7中可以使用下划线分隔数据,如下:
double pi = 3.14_15_92_6;
4.Java中的基本类型转换:
Java变量类型分两种:基本数据类型和引用数据类型,基本数据类型包括(byte、short、int、long、char、float、double、boolean、null);引用类型主要是类实例的引用。
Java的自动类型转换原则基本与C++/C相同,都是将低精度的自动转换到高精度的,确保不存在精度损失。
举个小例子:
/*该例子用来阐述Java中的自动类型转换,及+=与+运算符的区别*/
class Test{
public static void main(String args[])
{
byte a = 1;
int b = 2;
/*a+b,会自动转换到int,char = int,损失精度报错*/
a = a + b;
/*使用+=运算符,应该等价于a = (byte)(a + b)*/
a += b;
/*原因同上*/
a = a + 5;
a += 5;
System.out.println(a);
}
}
5.Java常量池:
常量池指的就是在编译期间能被确定下来,并被保存在*.class文件中的一些常量数据。例如,String str = "Hello",Hello就是放在常量池中的常量。如下例子中,可以见s0、s1、s2在编译期间都会被确定为"Hello",并被指向常量池中的同一块内存中!
class Test{
public static void main(String args[])
{
String s0 = "hello";
String s1 = "hello";
String s2 = "hel" + "lo";
System.out.println(s0 == s1);
System.out.println(s1 == s2);
}
}
6.|和&操作符:
Java中&操作符(|操作符同理)有两个用途:
1)表示位运算,与操作
2)表示逻辑运算,与操作;与&&区别为没有短路原则
编译器区分两种运算的原则,是根据&两侧数据的类型来判断的。数据为整型,则表示位运算;数据为布尔类型,则表示逻辑运算
7.变量作用域:
1)基本类型,当退出当前代码块的时候,变量将不再可以被使用。
2)引用类型,只有当引用变量不再引用对象的时候,对象才可以准备被垃圾回收器回收。
8.位运算:
1)左移操作:低位补0
2)右移操作:正数,高位补0;负数,高位补1;注意符号位不移动
3)>>>移位操作符:无论正数负数,高位统一补0
9.Java中无sizeof关键字:
C/C++中保留sizeof关键字主要是用于系统一直,因为C/C++中的数据类型在不同的机器上,编译出来的位数可能不同,所以需要sizeof来辅助解决这个问题;但是Java中的基本数据类型在任何机器上都是固定的,已经被设计在语言中,所以无需sizeof关键字!
10.Java中的标签:
Java中虽然保留了goto关键字,但是没有使用goto关键字;但是当迭代嵌套、循环嵌套的时候,内外层依然可以使用标签及continue和break进行,内层跳转到外层的动作,类似一个goto的行为!虽然不推荐使用,但是作为笔记记录如下语法规则!
public class Test {
public static void main(String arg[]){
out:
for(int a = 0; a < 10; a++){
in:
for(int b = 0; b < 10; b++){
if(2 == b){
continue in;
}
if(3 == b){
break out;
}
}
}
}
}
Ps:
- 如果break后面不使用标签,只能退出最近的一圈循环(b圈的循环),但是标记了out后,就退出了out圈的循环(a圈的循环)!
- 标签必须紧挨着循环语句,用来指示为具体那层循环,不可用放在随意位置!
- JDK线程池ThreadPoolExecutor类中addWorker方法中有这种标签的使用方式:
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}