程序流程控制

移位运算符

移位运算符面向的运算对象是二进制的位,可单独用它们处理整数类型。左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补0)。“有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。Java也添加了一种“无符号”右移位运算符(>>>),它使用“零扩展”:无论正负,都在高位插入0。若对char, byte或者short进行移位处理,那么在移位进行之前,它们会自动转换成一个int。只用右侧的5个低位才会用到。这样可防止我们在一个int数里移动一个不切实际的位数。若对一个long值进行移位,最后得到的结果也是long型。此时只会用到右侧6个低位,防止移动超过long值现成的位数。但在进行“无符号”右移位时,也可能遇到一个问题,若对byte和short值进行又移位运算,得到的可能不是正确的结果。它们会自动转换成int类型,并进行右移位。但“零扩展”不会发生,所以在那些情况下会得到-1的结果。

移位可与等号(<<=或>>=或>>>=)组合使用。此时,运算符左边的值会移动由右边的值指定的位数,再将得到的结果赋值回左边的值。

public class Test {
public static void main(String[] args) {
int i = 8;
i >>= 2;
System.out.println(i);
i <<= 1;
System.out.println(i);
i <<= 1;
System.out.println(i);
i >>>= 1;
System.out.println(i);
i >>>= 1;
System.out.println(i);
}
}
// output
/*
2 4 8 4 2
*/

三元运算符

布尔表达式 ? 值0 : 值1

public class Test {
public static void main(String[] args) {
int i = 10;
System.out.println(i < 10 ? 5 : 11);
System.out.println(i == 10 ? i / 2 : 0);
}
}
// output
/*
11 5
*/

表达式运算符优先级

一元运算符 > 算术(移位)运算符 > 关系运算符 > 逻辑(按位)运算符 > 条件运算符 > 赋值

  • 一元运算符:++、--
  • 算术(移位)运算符:*、/、%、+、-、<<、>>
  • 关系运算符:>、<、>=、<=、==、!=
  • 逻辑(按位)运算符:&&、||、&、|、^
  • 条件(三元):A>B?X:Y
  • 赋值:= (以及复合赋值,如*=)

Java中goto标签的使用

尽管goto的滥用会导致程序的不可读,但是在一些情况下,goto是组织控制流程的最佳手段,因此很多的语言中仍然或多或少地保留了其一些用法,对Java来说,唯一用到标签的地方就是在循环语句之前。

public class Test {
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 inner");
continue inner;
}
}
}
} }
}
// output
/*
i = 0
continue inner
i = 1
continue inner
i = 2
continue
i = 3
break
i = 4
continue inner
i = 5
continue inner
i = 6
continue inner
i = 7
continue outer
i = 8
break outer
*/

需要注意的是当你使用switch...case语句时,遇到满足的一个case之后,如果之后没有break,将会继续执行接下来的语句而不会管符不符合之后条件,直到遇到break语句或者程序片段执行完毕。一般应该在switch...case语句之中,最后放置一个default条件,以执行没有备选条件下的任务。

public class Test {
public static void main(String[] args) {
int i = 5;
switch (i){
case 3:
System.out.println("case3: " + i);
case 5:
System.out.println("case5: " + i);
case 7:
System.out.println("case7: " + i);
default:
System.out.println("default: " + i);
}
}
}
// output
/*
case5: 5
case7: 5
default: 5
*/
public class Test {
public static void main(String[] args) {
int i = 5;
switch (i){
case 3:
System.out.println("case3: " + i); break;
case 5:
System.out.println("case5: " + i); break;
case 7:
System.out.println("case7: " + i); break;
default:
System.out.println("default: " + i); break;
}
}
}
// output
/*
case5: 5
*/

需要注意的是switch要求的选择因子必须是int或char的整数值。而假如将一个字符串或者浮点数作为选择因子使用,那么它们在switch语句中是不会工作的。

Math.random()会产生0-1之间的值,其范围为[0, 1)。

当我们使用构造器的时候,如果我们自己并没有在类中进行任何定义,则系统会替我们创建一个默认的无参构造器,而当我们定义了任何一个构造器时,无论有没有参数,系统都不会再继续帮我们进行创建无参构造器。

注:尽管我们可以在非静态方法中访问静态方法和静态变量,但是反过来却是不行的。因为静态数据的构造要优先于非静态方法。

Java中使用垃圾收集器回收由不再使用的对象占据的内存。但是垃圾收集器只知道释放那些由new分配的内存,所以不知道如何释放对象的“特殊”内存。为解决这一问题,Java提供了一个名为finalize()的方法,可为我们的类定义它。在理想情况下,它的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),不过只有在下一次垃圾收集过程中,才会真正回收对象的内存。所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作。

垃圾收集只跟内存有关,也就是说垃圾收集器存在的唯一原因就是为了回收程序不再使用的内存。

finalize()最有用的地方之一就是观察垃圾收集的过程。

在一个类里,初始化顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间,那些变量仍会在调用任何方法之前得到初始化(甚至在构建器调用之前)。

Thinking in Java学习杂记(5-6)

Java编程思想学习杂记(1-4章)的更多相关文章

  1. [Java编程思想-学习笔记]第3章 操作符

    3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...

  2. Java编程思想学习(五)----第5章:初始化与清理

    随着计算机革命的发展,“不安全”的编程方式已逐渐成为编程代价高昂的主因之一. C++引入了构造嚣(constructor)的概念,这是一个在创建对象时被自动调用的特殊方法.Java中也采用了构造器,并 ...

  3. [Java编程思想-学习笔记]第1章 对象导论

    1.1  抽象过程 Java是一门面向对象的语言,它的一个优点在于只针对待解问题抽象,而不用为具体的计算机结构而烦心,这使得Java有完美的移植性,也即Java的口号"Write Once, ...

  4. [Java编程思想-学习笔记]第2章 一切都是对象

    2.1  创建新的数据类型:类 通过第一章掌握了面向对象的理论后,我们知道每个对象必定属于一个类型,那么Java如何创建新的数据类型?如下程序所示: class Circle { // 属性 // 方 ...

  5. [Java编程思想-学习笔记]第4章 控制执行流程

    4.1  return 关键字return有两方面的用途:一方面指定一个方法结束时返回一个值:一方面强行在return位置结束整个方法,如下所示: char test(int score) { if ...

  6. Java编程思想学习(四)----第四章:控制执行流程

    在Java中,涉及的关键字包括if-else.while.do-while.for.return.break 以及选择语句switch.然而,Java并不支持goto语句(该语句引起许多反对意见,但它 ...

  7. Java编程思想学习(三)----第三章:操作符

    3.2使用Java操作符 操作符接受一个或多个参数,并生成一个新值. 操作符作用于操作数,生成一个新值.有些操作符可以改变操作数自身的值.几乎所以的操作符都只能操作“基本类型”.例外的操作符有“=”, ...

  8. Java编程思想学习(八) 内部类

    可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类的定义是简单的,但是它的语法确实很是复杂,让人不是很好理解.下面就内部类做一个小结. 一.内部类的分类 总的来讲内部类分为普通内部类,匿 ...

  9. java编程思想--学习心得

    学习Java编程思想,需要了解语言特性,对于各种名词,能够借助项目代码,解释其含义,不借助搜索工具,明白其在什么样场景下使用,会带来什么样的问题,能否避免这类问题. 学习的过程,与软件开发相同,一样是 ...

随机推荐

  1. 什么是AWVS

    什么是AWVS Acunetix Web Vulnerability Scanner(简称AWVS)是一款知名的网络漏洞扫描工具,它通过网络爬虫测试你的网站安全,检测流行安全漏洞,现已更新到10.(下 ...

  2. Android 绘制中国地图

    最近的版本有这样一个需求: 有 3 个要素: 中国地图 高亮省区 中心显示数字 面对这样一个需求,该如何实现呢? 高德地图 因为项目是基于高德地图来做的,所以很自然而然的想到了高德.但是当查阅高德地图 ...

  3. yii批量数据插入

    yii框架批量插入数据有两种方法,第一种是循环多次插入和一次批量插入,第一种方法要注意插入数据中间有一次数据插入失败要注意回滚事务 循环插入数据 第一种方法 $model = new User(); ...

  4. Git的安装与TortoiseGit的安装和汉化

    下载Git 进入https://git-scm.com/downloads 可以看到如下界面 因为我是windows系统,选择windows即可. 有的朋友因为网络慢的一些原因不能很快下载下来,可以进 ...

  5. 从0开发3D引擎(十):使用领域驱动设计,从最小3D程序中提炼引擎(上)

    目录 上一篇博文 下一篇博文 前置知识 回顾上文 最小3D程序完整代码地址 通用语言 将会在本文解决的不足之处 本文流程 解释本文使用的领域驱动设计的一些概念 本文的领域驱动设计选型 设计 引擎名 识 ...

  6. 并查集(不相交集)的Union操作

    在并查集(不相交集)中附加操作\(Deunion\),它实现的功能是取消最后一次\(Union\)的操作. 实现思想 初始化一个空栈,将每一次的\(Union\)操作的两个集合的根和其值\(Push\ ...

  7. d3.js ---画坐标轴

    画坐标轴 //使用d3的svg的axis()方法生成坐标轴 var x_axis = d3.svg.axis().scale(scale_x), y_axis = d3.svg.axis().scal ...

  8. 在Shadow DOM使用原生模板

    原生模板的优势 延迟了资源加载 延迟了加载和处理模板所引用的资源的时机,这样,用户就能够在模板中使用任意多的资源,却不阻碍页面的渲染. 延迟了渲染内容 无论模板在什么位置,浏览器不会把模板中的内容直接 ...

  9. zookeeper伪集群搭建

    zookeeper伪集群搭建 1. 下载zookeeper: https://zookeeper.apache.org/ 2. 解压: tar -zxvf zookeeper-3.4.14.tar.g ...

  10. 【WPF学习】第五十七章 使用代码创建故事板

    在“[WPF学习]第五十章 故事板”中讨论了如何使用代码创建简单动画,以及如何使用XAML标记构建更复杂的故事板——具有多个动画以及播放控制功能.但有时采用更复杂的故事板例程,并在代码中实现全部复杂功 ...