程序员人生 网站导航

java编程思想总结(二)

栏目:php教程时间:2016-09-25 09:05:41

java编程思想总结(2)

java编程思想总结是1个延续更新的系列,是本人对自己多年工作中使用到java的1个经验性总结,也是温故而知新吧,由于很多基础的东西过了这么多年,平时工作中用不到也会遗忘掉,所以看看书,上上网,查查资料,也算是记录下自己的笔记吧,过1段时间以后再来看看也是蛮不错的,也希望能帮助到正在学习的人们,本系列将要总结1下几点:

  • 面向对象的编程思想
  • java的基本语法
  • 1些有趣的框架解析
  • 实战项目的整体思路
  • 代码的优化和性能调优的几种方案
  • 整体项目的计划和视角
  • 其它遗漏的东西和补充

java的基本语法

结合上1节,我们也从最基本的类开始,首先是经典的hello word案例:

package com.klsstt.helloword; public class HelloWord{ public static void main(String [] args){ System.out.println("Hello Word !"); } }

这个案例输出了“Hello Word !”,其中,关键字class,用来创建类,public则是访问修饰符,代表这个类的访问权限,HelloWord则是这个类的名称,1般类的命名都是首字母大写的驼峰命名法。package是包的声明,表明当前类的包路径,static关键字代表该方法是静态方法,main则是方法名称,main方法是java程序默许生成的可履行的方法。

大小写敏感性

Java 是1种大小写敏感的语言,这就意味着 Hello 和 hello 在 Java 中代表不同的意思。
Java 关键字总是小写的
避免使用只有大小写不同的变量名。

类的命名

所有类的名称首字母必须大写。
始终确保在您的代码和Java文件名相匹配的类名。
如果类名称中包括几个单词,那末每一个单词的首字母都要大写。
例如类 HelloWord

Java 标识符

标识符就是用于给 Java 程序中变量、类、方法等命名的符号。
使用标识符时,需要遵照几条规则:

  1. 标识符可以由字母、数字、下划线(_)、美元符($)组成,但不能包括 @、%、空格等其它特殊字符,不能以数字开头。如:123name

  2. 标识符不能是 Java 关键字和保存字( Java 预留的关键字,以后的升级版本中有可能作为关键字),但可以包括关键字和保存字。如:不可使用 void 作为标识符,但是 Myvoid 可以。

  3. 标识符是严格辨别大小写的。 1定要分清楚Hello 和 hello 是两个不同的标识符哦!
  4. 标识符的命名最好能反应出其作用,做到见名知意。

Java 修饰符

访问修饰符:default, public , protected, private
非访问修饰符:final, abstract, strictfp

Java 关键字列表

访问控制
private 私有的
protected 受保护的
public 公共的

类、方法和变量修饰符
abstract 声明抽象
class 类
extends 扩允,继承
final 终极,不可改变的
implements 实现
interface 接口
native 本地
new 创建
static 静态
strictfp 严格,精准
synchronized 线程,同步
transient 短暂
volatile 易失

程序控制语句
break 跳出循环
continue 继续
return 返回
do 运行
while 循环
if 如果
else 反之
for 循环
instanceof 实例
switch 开关
case 返回开关里的结果
default 默许

毛病处理
try 捕获异常
catch 处理异常
finally 有无异常都履行
throw 抛出1个异常对象
throws 声明1个异常可能被抛出
assert 断言

包相干
import 引入
package 包

基本类型
boolean 布尔型
byte 字节型
char 字符型
double 双精度,
float 浮点
int 整型
long 长整型
short 短整型
null 空
true 真
false 假
enum 枚举

变量援用
super 父类,超类
this 本类
void 无返回值

关键字(51)+保存字(const,goto)共53个

Java 变量和常量

在程序中存在大量的数据来代表程序的状态,其中有些数据在程序的运行进程中值会产生改变,有些数据在程序运行进程中值不能产生改变,这些数据在程序中分别被叫做变量和常量。
在实际的程序中,可以根据数据在程序运行中是不是产生改变,来选择应当是使用变量代表还是常量代表。

变量
变量代表程序的状态。程序通过改变变量的值来改变全部程序的状态,或说得更大1些,也就是实现程序的功能逻辑。
为了方便的援用变量的值,在程序中需要为变量设定1个名称,这就是变量名。
例如在2D游戏程序中,需要代表人物的位置,则需要2个变量,1个是x坐标,1个是y坐标,在程序运行进程中,这两个变量的值会产生改变。

由于Java语言是1种强类型的语言,所以变量在使用之前必须首先声明,在程序中声明变量的语法格式以下:
数据类型 变量名称;
例如:int x;
在该语法格式中,数据类型可以是Java语言中任意的类型,包括前面介绍到的基本数据类型和后续将要介绍的复合数据类型。变量名称是该变量的标识符,需要符合标识符的命名规则,在实际使用中,该名称1般和变量的用处对应,这样便于程序的浏览。数据类型和变量名称之间使用空格进行间隔,空格的个数不限,但是最少需要1个。语句使用“;”作为结束。
也能够在声明变量的同时,设定该变量的值,语法格式以下:
数据类型 变量名称 = 值;
例如:int x = 10;
在该语法格式中,前面的语法和上面介绍的内容1致,后续的“=”代表赋值,其中的“值”代表具体的数据,注意区分“==”代表为判断是不是相等。在该语法格式中,要求值的类型需要和声明变量的数据类型1致。
在程序中,变量的值代表程序的状态,在程序中可以通过变量名称来援用变量中存储的值,也能够为变量重新赋值。例如:
int n = 5;
n = 10;
在实际开发进程中,需要声明甚么类型的变量,需要声明多少个变量,需要为变量赋甚么数值,都根据程序逻辑决定,这里罗列的只是表达的格式而已。

常量

常量代表程序运行进程中不能改变的值。
常量在程序运行进程中主要有2个作用:
1. 代表常数,便于程序的修改(例如:圆周率的值)
2. 增强程序的可读性(例如:常量UP、DOWN、LEFT和RIGHT分辨代表上下左右,其数值分别是1、2、3和4)
常量的语法格式和变量类型,只需要在变量的语法格式前面添加关键字final便可。在Java编码规范中,要求常量名必须大写。
则常量的语法格式以下:
final 数据类型 常量名称 = 值;
final 数据类型 常量名称1 = 值1, 常量名称2 = 值2,……常量名称n = 值n;
例如:
final double PI = 3.14;
final char MALE=‘M’,FEMALE=‘F’;
在Java语法中,常量也能够首先声明,然后再进行赋值,但是只能赋值1次,示例代码以下:
final int UP;
UP = 1;

关于final详解

final 用于声明属性(常量),方法和类,分别表示属性1旦被分配内存空间就必须初始化(不会有默许初始化,局部变量也是如此,默许初始化只有普通的非final成员属性,对static(无final修饰)类变量,类连接时候有默许初始化,对像private int a;在类实例化时,构造函数默许初始为0,总之,变量必须初始化后方可用,这是java的安全之1。
final这个关键字的含义是“这是没法改变的”或“终态的”。
那末为何要禁止改变呢?
java语言的发明者可能由于两个目的而禁止改变:
1. 效力问题:
jdk中的某些类的某些方法,是不允许被用户覆盖的,设计者可能认为,所用方法已是最好的方法,用户私自覆盖,或是由于忽视而覆盖,就会影响JVM或是系统的系能;
2. 设计所需:
尽人皆知,有些情况必须使用final关键字,比如方法中的匿名内部类的参数传递
【修饰变量】:
final成员变量表示常量,只能被赋值1次,赋值后值不再改变。
【修饰方法】:
final方法不能被子类方法覆盖,但可以被继承。
【修饰类】:
final类不能被继承,没有子类,final类中所有方法都是final的。(如String类)

被final修饰而没有被static修饰的类的属性变量只能在两种情况下初始化(必须初始化):
a.在它被声明的时候赋值
b.在构造函数里初始化
解释: 当这个属性被修饰为final,而非static的时候,它属于类的实例对象的资源(实例常量),当类被加载进内存的时候这个属性并没有给其分配内存空间,而只是 定义了1个变量a,只有当类被实例化的时候这个属性才被分配内存空间,而实例化的时候同时履行了构造函数,所以属性被初始化了,也就符合了当它被分配内存 空间的时候就需要初始化,以后不再改变的条件.

被static修饰而没有被final修饰的类的属性变量只能在两种情况下初始化(可以不初始化):
a.在它被声明的时候赋值
b.在静态或非静态快里初始化
解释:
当类的属性被同时被修饰为static时候,他属于类的资源(类变量),在类加载后,进行连接时候,分3步: 先验证;然后准备,准备时,先分配内存,接着默许初始化;可以进行解析。最后,进行类初始化,类初始化前,必须保证它的父类已初始化了,所以最早初始化的是超类,对接口,没必要初始其父接口。类初始化时,它把类变量初始化语句及静态初始化语句放到类初始化方法中,所以,如果无此两种语句,也就没类初始化方法,而构造函数是在当类 被实例化的时候才会履行,所以用构造函数,这时候候这个属性没有被初始化.程序就会报错.而static块是类被加载的时候履行,且只履行这1次,所以在 static块中可以被初始化.

同时被final和static修饰的类的属性变量只能在两种情况下初始化(必须初始化):
a.在它被定义的时候
b.在类的静态块里初始化
c.特别对初始化时候调用抛出异常的构造函数,初始时候注意,特别是在实现单例模式时(只能这么初始化)
如:

class A{ private final static A a; static{ try{ a=new A(); }catch(Exception e){ throws new RuntimeException(e); //必须有,不然不能完成常量的正确初始化 } } private A() throws Exception{} }

解释:
当类的属性被同时被修饰为static和final的时候,他属于类的资源(类常量),那末就是类在被加载进内存的时候(也就是利用程 序启动的时候)就要已为此属性分配了内存,所以此时属性已存在,它又被final修饰,所以必须在属性定义了以后就给其初始化值.而构造函数是在当类 被实例化的时候才会履行,所以用构造函数,这时候候这个属性没有被初始化.程序就会报错.而static块是类被加载的时候履行,且只履行这1次,所以在 static块中可以被初始化.

java中的 final变量==常量
【final变量的变与不变】:final表示变量的值或援用不变
有人说final变量在赋值后就不可变,此变量可以是基本数据类型+String或是对象
那末这个不变到底指的是甚么呢?
这个不变指的是援用,是地址,而所援用的对象的内容依然是可变的。
注:如果为对象,注意此时类初始化条件
就是说,这个final变量永久指向某个对象,是1个常量指针,而不是指向常量的指针。
【final关键字的具体利用】:
【final+变量】:
在实际利用中,这类情势是非常少见的。
比如logger是可以的,但是貌似其实不是非常实用,也许用户依然希望通过setter来改变logger变量。
【static+final+变量】:
常量,常常使用。
【final+方法】:
JDK中经常使用,但是自己并未经常使用。
【final+类】:
helper类常常使用。
【final用于匿名内部类的参数传递】:
在多线程测试时,常常使用。
【final用于方法的参数】:
其实不经常使用。

Java 数组

数组时贮存有多重相同变量类型的对象。但是,数字本身也是堆中的1个对象。我们将要学习如何声明,建立,初始化数组。
定义数组
1. (推荐,更能表明数组类型)
type[] 变量名 = new type[数组中元素的个数];
比如:
int[] a = new int[10];
数组名,也即援用a,指向数组元素的首地址。
2. (同C语言)
type变量名[] = new type[数组中元素的个数];
如:
int a[] = new int[10];
3. 定义时直接初始化
type[] 变量名 = new type[]{逗号分隔的初始化值};
其中红色部份可省略,所以又有两种:
int[] a = {1,2,3,4};
int[] a = new int[]{1,2,3,4};
其中int[] a = new int[]{1,2,3,4};的第2个方括号中不能加上数组长度,由于元素个数是由后面花括号的内容决定的。

数组应用基础
数组长度
Java中的每一个数组都有1个名为length的属性,表示数组的长度。
length属性是public final int的,即length是只读的。数组长度1旦肯定,就不能改变大小。
2维数组
2维数组是数组的数组。
基本的定义方式有两种情势,如:
type[][] i = new type[2][3];(推荐)
type i[][] = new type[2][3];
变长的2维数组
2维数组的每一个元素都是1个1维数组,这些数组不1定都是等长的。
声明2维数组的时候可以只指定第1维大小,空缺出第2维大小,以后再指定不同长度的数组。但是注意,第1维大小不能空缺(不能只指定列数不指定行数)。
2维数组也能够在定义的时候初始化,使用花括号的嵌套完成,这时候候不指定两个维数的大小,并且根据初始化值的个数不同,可以生成不同长度的数组元素。

Java 集合

集合类说明及区分
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap

  • Collection接口

Collection是最基本的集合接口,1个Collection代表1组Object,即Collection的元素(Elements)。1些 Collection允许相同的元素而另外一些不行,1些能排序而另外一些不行。

Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建1个空的Collection,有1个 Collection参数的构造函数用于创建1个新的Collection,这个新的Collection与传入的Collection有相同的元素。后 1个构造函数允许用户复制1个Collection。

如何遍历Collection中的每个元素?不论Collection的实际类型如何,它都支持1个iterator()的方法,该方法返回1个迭代子,使用该迭代子便可逐1访问Collection中每个元素。典型的用法以下:
    Iterator it = collection.iterator(); // 取得1个迭代子
    while(it.hasNext()) {
      Object obj = it.next(); // 得到下1个元素
    }
由Collection接口派生的两个接口是List和Set。

  • List接口

List是有序的Collection,使用此接口能够精确的控制每一个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。
和下面要提到的Set不同,List允许有相同的元素。

除具有Collection接口必备的iterator()方法外,List还提供1个listIterator()方法,返回1个 ListIterator接口,和标准的Iterator接口相比,ListIterator多了1些add()之类的方法,允许添加,删除,设定元素, 还能向前或向后遍历。

实现List接口的经常使用类有LinkedList,ArrayList,Vector和Stack。

  • LinkedList类

LinkedList实现了List接口,允许null元素。另外LinkedList提供额外的get,remove,insert方法在 LinkedList的首部或尾部。
这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
注意LinkedList没有同步方法。如果多个线程同时访问1个List,则必须自己实现访问同步。1种解决方法>是在创建List时构造1个同步的List:
List list = Collections.synchronizedList(new LinkedList(…));

  • ArrayList类

ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
size,isEmpty,get,set方法运行时间为常数。但是add方法开消为分摊的常数,
添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
每一个ArrayList实例都有1个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断>添加新元素而自动增加,但是增长算法 并没有定义。当需要插入大量元素时,在插入前可以调用>ensureCapacity方法来增加ArrayList的容量以提高插入效力。
和LinkedList1样,ArrayList也是非同步的(unsynchronized)。

  • Vector类

Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和 ArrayList创建的Iterator是同1接口,但是,由于Vector是同步的,当1个Iterator被创建而且正在被使用,另外一个线程改变了 Vector的状态(例如,添加或删除1些元素),这时候调用Iterator的方法时将抛出 ConcurrentModificationException,因此必须捕获该异常。
- Stack 类
Stack继承自Vector,实现1个落后先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是不是为空,search方法检测1个元素在堆栈中的位置。Stack刚创建后是空栈。

  • Set接口

Set是1种不包括重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有1个null元素。
  很明显,Set的构造函数有1个束缚条件,传入的Collection参数不能包括重复的元素。
  请注意:必须谨慎操作可变对象(Mutable Object)。如果1个Set中的可变元素改变了本身状态致使Object.equals(Object)=true将致使1些问题。
- Map接口

请注意,Map没有继承Collection接口,Map提供key到value的映照。1个Map中不能包括相同的key,每一个key只能映照1个 value。Map接口提供3种集合的视图,Map的内容可以被当作1组key集合,1组value集合,或1组key-value映照。

  • Hashtable类

Hashtable继承Map接口,实现1个key-value映照的哈希表。
通常缺省的load factor 0.75较好地实现了时间和空间的均衡。
增大load factor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作。
使用Hashtable的简单示例以下,将1,2,3放到Hashtable中,他们的key分是”one”,”two”,”three”:

 Hashtable numbers = new Hashtable();     numbers.put(“one”, new Integer(1));     numbers.put(“two”, new Integer(2));     numbers.put(“three”, new Integer(3));

要取出1个数,比如2,用相应的key:

Integer n = (Integer)numbers.get(“two”);     System.out.println(“two = ” + n);

由于作为key的对象将通过计算其散列函数来肯定与之对应的value的位置,因此任何作为key的对象都必须实现hashCode和equals方 法。
hashCode和equals方法继承自根类Object,如果你用自定义的类当作key的话,要相当谨慎,依照散列函数的定义,如果两个对象相 同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不1定不同,如 果两个不同对象的hashCode相同,这类现象称为冲突,冲突会致使操作哈希表的时间开消增大,所以尽可能定义好的hashCode()方法,能加快哈希 表的操作。
如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这类问题,只需要牢记1条:要同时复写equals方法和hashCode方法,而不要只写其中1个。
Hashtable是同步的。

  • HashMap类

HashMap和Hashtable类似,不同的地方在于HashMap是非同步的,并且允许null,即null value和null key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开消和HashMap 的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得太高,或load factor太低。

  • WeakHashMap类

WeakHashMap是1种改进的HashMap,它对key实行“弱援用”,如果1个key不再被外部所援用,那末该key可以被GC回收。

总结

如果触及到堆栈,队列等操作,应当斟酌用List,对需要快速插入,删除元素,应当使用LinkedList,如果需要快速随机访问元素,应当使用ArrayList。
如果程序在单线程环境中,或访问仅仅在1个线程中进行,斟酌非同步的类,其效力较高,如果多个线程可能同时操作1个类,应当使用同步的类。
要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
尽可能返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。

同步性

Vector是同步的。这个类中的1些方法保证了Vector中的对象是线程安全的。而ArrayList则是异步的,因此ArrayList中的对象并 不是线程安全的。由于同步的要求会影响履行的效力,所以如果你不需要线程安全的集合那末使用ArrayList是1个很好的选择,这样可以免由于同步带 来的没必要要的性能开消。
数据增长
从内部实现机制来说ArrayList和Vector都是使用数组(Array)来控制集合中的对象。当你向这两种类型中增加元素的时候,如果元素的数目 超越了内部数组目前的长度它们都需要扩大内部数组的长度,Vector缺省情况下自动增长原来1倍的数组长度,ArrayList是原来的50%,所以最 后你取得的这个集合所占的空间总是比你实际需要的要大。所以如果你要在集合中保存大量的数据那末使用Vector有1些优势,由于你可以通过设置集合的初 始化大小来避免没必要要的资源开消。
使用模式
在ArrayList和Vector中,从1个指定的位置(通过索引)查找数据或是在集合的末尾增加、移除1个元素所花费的时间是1样的,这个时间我们用 O(1)表示。但是,如果在集合的其他位置增加或移除元素那末花费的时间会呈线形增长:O(n-i),其中n代表集合中元素的个数,i代表元素增加或移除 元素的索引位置。
为何会这样呢?以为在进行上述操作的时候集合中第i和第i个元素以后的所有元素都要履行位移的操作。
这1切意味着甚么呢?
这意味着,你只是查找特定位置的元素或只在集合的末端增加、移除元素,那末使用Vector或ArrayList都可以。如果是其他操作,你最好选择其他 的集合操作类。比如,LinkList集合类在增加或移除集合中任何位置的元素所花费的时间都是1样的?O(1),但它在索引1个元素的使用缺比较慢 -O(i),其中i是索引的位置.使用ArrayList也很容易,由于你可以简单的使用索引来代替创建iterator对象的操作。LinkList也 会为每一个插入的元素创建对象,所有你要明白它也会带来额外的开消。
最后,在《Practical Java》1书中Peter Haggar建议使用1个简单的数组(Array)来代替Vector或ArrayList。特别是对履行效力要求高的程序更应如此。由于使用数组 (Array)避免了同步、额外的方法调用和没必要要的重新分配空间的操作。

Java 枚举值

枚举是在 Java5.0 版本中被引进的。枚举限制了变量要有1些预先定义的值。枚举列表中的值称为枚举值。
应用枚举值可以大大减少你的代码中的漏洞。
举例来讲,如果我们想为1家鲜榨果汁店编个程序,就能够将杯子的尺寸限制为小中和大。这样就能够确保人们不会定大中小尺寸以外

class FreshJuice { enum FreshJuiceSize{ SMALL, MEDIUM, LARGE } FreshJuiceSize size; } public class FreshJuiceTest { public static void main(String args[]){ FreshJuice juice = new FreshJuice(); juice.size = FreshJuice. FreshJuiceSize.MEDIUM ; System.out.println("Size: " + juice.size); } }

输出以下结果:Size: MEDIUM

注:枚举可以自己声明也能够在类中声明。方法变量和构造器也能够在枚举值中定义。

Java 中的注释

Java支持单行或多行注释,所有注释中的字母都会被 Java 编译器疏忽。
行注释:
//开始

块注释:
/*开始
* /结束

javadoc注释:生成javadoc时,这样的注释会被生成标准的javaapi注释,该注释可以跨多行

/**
 *
 */

Java 中的分支语句

  • break语句
    break语句有两种情势:标签和非标签。在前面的switch语句,看到的break语句就是非标签情势。可使用非标签break,结束for,while,do-while循环,以下面的BreakDemo程序:
class BreakDemo { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; int searchfor = 12; int i; boolean foundIt = false; for (i = 0; i < arrayOfInts.length; i++) { if (arrayOfInts[i] == searchfor) { foundIt = true; break; } } if (foundIt) { System.out.println("Found " + searchfor + " at index " + i); } else { System.out.println(searchfor + " not in the array"); } } }

这个程序在数组终查找数字12。break语句,如上的粗体,当找到只时,结束for循环。控制流就跳转到for循环后面的语句。程序输出是:

Found 12 at index 4
无标签break语句结束最里面的switch,for,while,do-while语句。而标签break结束最外面的语句。接下来的程序,BreakWithLabelDemo,类似前面的程序,但使用嵌套循环在2维数组里寻觅1个值。但值找到后,标签break语句结束最外面的for循环(标签为”search”):

class BreakWithLabelDemo { public static void main(String[] args) { int[][] arrayOfInts = { { 32, 87, 3, 589 }, { 12, 1076, 2000, 8 }, { 622, 127, 77, 955 } }; int searchfor = 12; int i; int j = 0; boolean foundIt = false; search: for (i = 0; i < arrayOfInts.length; i++) { for (j = 0; j < arrayOfInts[i].length; j++) { if (arrayOfInts[i][j] == searchfor) { foundIt = true; break search; } } } if (foundIt) { System.out.println("Found " + searchfor + " at " + i + ", " + j); } else { System.out.println(searchfor + " not in the array"); } } }

程序输出是:

Found 12 at 1, 0
break语句结束标签语句,它不是传送控制流到标签处。控制流传送到紧随标记(终止)声明。

  • continue语句

continue语句疏忽for,while,do-while确当前迭代。非标签模式,疏忽最里面的循环体,然后计算循环控制的boolean表达式。接下来的程序,ContinueDemo,通过1个字符串的步骤,计算字母“p”出现的次数。如果当前字符不是p,continue语句跳过循环的其他代码,然后处理下1个字符。如果当前字符是p,程序自增字符数。

class ContinueDemo { public static void main(String[] args) { String searchMe = "peter piper picked a " + "peck of pickled peppers"; int max = searchMe.length(); int numPs = 0; for (int i = 0; i < max; i++) { // interested only in p's if (searchMe.charAt(i) != 'p') continue; // process p's numPs++; } System.out.println("Found " + numPs + " p's in the string."); } }

这里是程序输出:Found 9 p’s in the string.
为了更清晰看效果,尝试去掉continue语句,重新编译。再跑程序,count将是毛病的,输出是35,而不是9.

标签continue语句疏忽标签标记的外层循环确当前迭代。下面的程序例子,ContinueWithLabelDemo,使用嵌套循环在字符传的字串中搜索字串。需要两个嵌套循环:1个迭代字串,1个迭代正在被搜索的字串。下面的程序ContinueWithLabelDemo,使用continue的标签情势,疏忽最外层的循环。

class ContinueWithLabelDemo { public static void main(String[] args) { String searchMe = "Look for a substring in me"; String substring = "sub"; boolean foundIt = false; int max = searchMe.length() - substring.length(); test: for (int i = 0; i <= max; i++) { int n = substring.length(); int j = i; int k = 0; while (n-- != 0) { if (searchMe.charAt(j++) != substring.charAt(k++)) { continue test; } } foundIt = true; break test; } System.out.println(foundIt ? "Found it" : "Didn't find it"); } }

这里是程序输出:Found it

  • return语句

最后的分支语句是return语句。return语句从当前方法退出,控制流返回到方法调用途。
return语句有两种情势:1个是返回值,1个是不返回值。
为了返回1个值,简单在return关键字后面把值放进去(或放1个表达式计算)
return ++count;
return的值的数据类型,必须和方法声明的返回值的类型符合。
当方法声明为void,使用下面情势的return不需要返回值。
return;

脚注

转载请注明出处,该博客同步更新在我的个人博客网站。1.


  1. 我的博客网站:www.klsstt.com. ↩

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐