做网站的需求文档格式,flash优秀网站,黑马程序员学费,国家和城乡建设部网站首页原文#xff1a;docs.oracle.com/javase/tutorial/reallybigindex.html 运算符 原文#xff1a;docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html 现在你已经学会了如何声明和初始化变量#xff0c;你可能想知道如何对其进行操作。学习 Java 编程语言的运… 原文docs.oracle.com/javase/tutorial/reallybigindex.html 运算符 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html 现在你已经学会了如何声明和初始化变量你可能想知道如何对其进行操作。学习 Java 编程语言的运算符是一个很好的开始。运算符是执行特定操作的特殊符号作用于一个、两个或三个操作数然后返回一个结果。
当我们探索 Java 编程语言的运算符时提前了解哪些运算符具有最高优先级可能会对您有所帮助。下表中的运算符按照优先级顺序列出。出现在表格顶部的运算符优先级较高。优先级较高的运算符在相对较低优先级的运算符之前进行评估。同一行上的运算符具有相同的优先级。当具有相同优先级的运算符出现在同一表达式中时必须有规则来决定哪个首先进行评估。除了赋值运算符之外的所有二元运算符都是从左到右进行评估赋值运算符是从右到左进行评估。
运算符优先级
运算符优先级后缀*expr* *expr*--一元*expr* --*expr* *expr* -*expr* ~ !乘法* / %加法 -移位 关系 instanceof相等 !按位与按位异或^按位或#124;逻辑与逻辑或#124;#124;三元? :赋值 - * / % ^ #124;
在通用编程中某些运算符比其他运算符更频繁地出现例如赋值运算符“比无符号右移运算符”更常见。因此以下讨论首先关注您最有可能经常使用的运算符最后关注那些不太常见的运算符。每个讨论都附有您可以编译和运行的示例代码。研究其输出将有助于巩固您刚刚学到的知识。
赋值、算术和一元运算符 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/op1.html 简单赋值运算符
您将遇到的最常见运算符之一是简单赋值运算符。您在自行车类中看到了这个运算符它将右侧的值分配给左侧的操作数 int cadence 0;int speed 0;int gear 1;
这个运算符也可以用于对象上分配对象引用如创建对象中所讨论的。
算术运算符
Java 编程语言提供了执行加法、减法、乘法和除法的运算符。您很可能会通过基本数学中的对应物来认识它们。唯一可能看起来新的符号是%它将一个操作数除以另一个操作数并返回余数作为其结果。
运算符描述加法运算符也用于字符串连接-减法运算符*乘法运算符/除法运算符%取余运算符
下面的程序ArithmeticDemo测试了算术运算符。 class ArithmeticDemo {public static void main (String[] args) {int result 1 2;// result is now 3System.out.println(1 2 result);int original_result result;result result - 1;// result is now 2System.out.println(original_result - 1 result);original_result result;result result * 2;// result is now 4System.out.println(original_result * 2 result);original_result result;result result / 2;// result is now 2System.out.println(original_result / 2 result);original_result result;result result 8;// result is now 10System.out.println(original_result 8 result);original_result result;result result % 7;// result is now 3System.out.println(original_result % 7 result);}
}
该程序打印如下内容
1 2 3
3 - 1 2
2 * 2 4
4 / 2 2
2 8 10
10 % 7 3
您还可以将算术运算符与简单赋值运算符结合使用创建复合赋值。例如x1; 和 xx1; 都会将 x 的值增加 1。 运算符也可以用于连接拼接两个字符串如下所示的ConcatDemo程序 class ConcatDemo {public static void main(String[] args){String firstString This is;String secondString a concatenated string.;String thirdString firstStringsecondString;System.out.println(thirdString);}
}
到程序结束时变量 thirdString 包含这是一个连接的字符串。并将其打印到标准输出。
一元运算符
一元运算符只需要一个操作数它们执行各种操作如将值增加/减少一否定表达式或反转布尔值的值。
运算符描述一元加号运算符表示正值数字没有这个也是正的-一元减号运算符否定表达式递增运算符将值增加 1--递减运算符将值减少 1!逻辑补运算符反转布尔值的值
下面的程序UnaryDemo测试了一元运算符 class UnaryDemo {public static void main(String[] args) {int result 1;// result is now 1System.out.println(result);result--;// result is now 0System.out.println(result);result;// result is now 1System.out.println(result);result -result;// result is now -1System.out.println(result);boolean success false;// falseSystem.out.println(success);// trueSystem.out.println(!success);}
}
递增/递减运算符可以在操作数之前前缀或之后后缀应用。代码 result; 和 result; 都会使 result 增加一。唯一的区别在于前缀版本result会计算为递增后的值而后缀版本result会计算为原始值。如果只是进行简单的递增/递减选择哪个版本并不重要。但如果在较大表达式的一部分中使用此运算符则您选择的版本可能会产生重大差异。
以下程序PrePostDemo演示了前缀/后缀一元递增运算符 class PrePostDemo {public static void main(String[] args){int i 3;i;// prints 4System.out.println(i);i; // prints 5System.out.println(i);// prints 6System.out.println(i);// prints 6System.out.println(i);// prints 7System.out.println(i);}
}
相等、关系和条件运算符 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html 相等和关系运算符
相等和关系运算符确定一个操作数是否大于、小于、等于或不等于另一个操作数。这些运算符中的大多数可能对您来说看起来很熟悉。请记住在测试两个原始值是否相等时必须使用“而不是”。 equal to
! not equal togreater thangreater than or equal toless thanless than or equal to
以下程序ComparisonDemo测试比较运算符 class ComparisonDemo {public static void main(String[] args){int value1 1;int value2 2;if(value1 value2)System.out.println(value1 value2);if(value1 ! value2)System.out.println(value1 ! value2);if(value1 value2)System.out.println(value1 value2);if(value1 value2)System.out.println(value1 value2);if(value1 value2)System.out.println(value1 value2);}
}
输出
value1 ! value2
value1 value2
value1 value2
条件运算符
和||运算符对两个布尔表达式执行条件-AND和条件-OR操作。这些运算符表现出“短路”行为这意味着只有在需要时才会评估第二个操作数。 Conditional-AND
|| Conditional-OR
以下程序ConditionalDemo1测试了这些运算符 class ConditionalDemo1 {public static void main(String[] args){int value1 1;int value2 2;if((value1 1) (value2 2))System.out.println(value1 is 1 AND value2 is 2);if((value1 1) || (value2 1))System.out.println(value1 is 1 OR value2 is 1);}
}
另一个条件运算符是?:可以被视为if-then-else语句的简写在本课程的控制流语句部分讨论。这个运算符也被称为三元运算符因为它使用三个操作数。在下面的例子中这个运算符应该被理解为“如果someCondition为true则将value1的值赋给result。否则将value2的值赋给result。”
以下程序ConditionalDemo2测试了?:运算符 class ConditionalDemo2 {public static void main(String[] args){int value1 1;int value2 2;int result;boolean someCondition true;result someCondition ? value1 : value2;System.out.println(result);}
}
因为someCondition为真这个程序将1打印到屏幕上。如果使用?:运算符而不是if-then-else语句可以使您的代码更易读例如当表达式紧凑且没有副作用如赋值时。
类型比较运算符 instanceof
instanceof运算符将对象与指定类型进行比较。您可以使用它来测试对象是否是类的实例子类的实例或者实现特定接口的类的实例。
以下程序InstanceofDemo定义了一个父类名为Parent一个简单接口名为MyInterface以及一个继承自父类并实现接口的子类名为Child。 class InstanceofDemo {public static void main(String[] args) {Parent obj1 new Parent();Parent obj2 new Child();System.out.println(obj1 instanceof Parent: (obj1 instanceof Parent));System.out.println(obj1 instanceof Child: (obj1 instanceof Child));System.out.println(obj1 instanceof MyInterface: (obj1 instanceof MyInterface));System.out.println(obj2 instanceof Parent: (obj2 instanceof Parent));System.out.println(obj2 instanceof Child: (obj2 instanceof Child));System.out.println(obj2 instanceof MyInterface: (obj2 instanceof MyInterface));}
}class Parent {}
class Child extends Parent implements MyInterface {}
interface MyInterface {}
输出
obj1 instanceof Parent: true
obj1 instanceof Child: false
obj1 instanceof MyInterface: false
obj2 instanceof Parent: true
obj2 instanceof Child: true
obj2 instanceof MyInterface: true
当使用instanceof运算符时请记住null不是任何东西的实例。
位与位移操作符 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html Java 编程语言还提供对整数类型执行位和位移操作的运算符。本节讨论的运算符很少使用。因此它们的覆盖范围很简短目的只是让您知道这些运算符存在。
一元位取反运算符~“反转位模式它可以应用于任何整数类型使每个0变为1”每个1变为0。例如一个byte包含 8 位将此运算符应用于位模式为00000000的值将使其模式变为11111111。
有符号左移位运算符“将位模式向左移动有符号右移位运算符”“将位模式向右移动。位模式由左操作数给出要移动的位置数由右操作数给出。无符号右移位运算符”将零移入最左侧位置而后的最左侧位置取决于符号扩展。
位运算符执行位按位与操作。
位运算符^执行位按位异或操作。
位运算符|执行位按位包含或操作。
以下程序BitDemo使用位与运算符将数字2打印到标准输出。 class BitDemo {public static void main(String[] args) {int bitmask 0x000F;int val 0x2222;// prints 2System.out.println(val bitmask);}
}
运算符概要 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/opsummary.html 以下快速参考总结了 Java 编程语言支持的运算符。
简单赋值运算符 Simple assignment operator
算术运算符 Additive operator (also usedfor String concatenation)
- Subtraction operator
* Multiplication operator
/ Division operator
% Remainder operator
一元运算符 Unary plus operator; indicatespositive value (numbers are positive without this, however)
- Unary minus operator; negatesan expressionIncrement operator; incrementsa value by 1
-- Decrement operator; decrementsa value by 1
! Logical complement operator;inverts the value of a boolean
相等性和关系运算符 Equal to
! Not equal toGreater thanGreater than or equal toLess thanLess than or equal to
条件运算符 Conditional-AND
|| Conditional-OR
?: Ternary (shorthand for if-then-else statement)
类型比较运算符
instanceof Compares an object to a specified type
位运算符和位移运算符
~ Unary bitwise complementSigned left shiftSigned right shiftUnsigned right shiftBitwise AND
^ Bitwise exclusive OR
| Bitwise inclusive OR
问题和练习运算符 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/QandE/questions_operators.html 问题 考虑以下代码片段。 arrayOfInts[j] arrayOfInts[j1] 代码包含哪些运算符 考虑以下代码片段。 int i 10;
int n i%5; 在代码执行后i和n的值是多少 如果不使用后缀递增运算符i而是使用前缀版本ii和n的最终值是多少 要反转boolean的值你会使用哪个运算符 用于比较两个值的运算符是还是 解释以下代码示例result someCondition ? value1 : value2;
练习 修改以下程序以使用复合赋值 class ArithmeticDemo {public static void main (String[] args){int result 1 2; // result is now 3System.out.println(result);result result - 1; // result is now 2System.out.println(result);result result * 2; // result is now 4System.out.println(result);result result / 2; // result is now 2System.out.println(result);result result 8; // result is now 10result result % 7; // result is now 3System.out.println(result);}
} 在以下程序中解释为什么值“6”连续打印两次 class PrePostDemo {public static void main(String[] args){int i 3;i;System.out.println(i); // 4i; System.out.println(i); // 5System.out.println(i); // 6System.out.println(i); // 6System.out.println(i); // 7}
}
检查你的答案
表达式、语句和块 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/expressions.html 现在你已经了解了变量和运算符是时候学习 表达式、语句 和 块 了。运算符可以用于构建计算值的表达式表达式是语句的核心组件语句可以分组成块。
表达式
一个 表达式 是由变量、运算符和方法调用构成的构造根据语言的语法构造计算为单个值。你已经看到了表达式的示例如下所示
int **cadence 0**;
**anArray[0] 100**;
System.out.println(**Element 1 at index 0: anArray[0]**);int **result 1 2**; // result is now 3
if (**value1 value2**) System.out.println(**value1 value2**);
表达式返回的值的数据类型取决于表达式中使用的元素。表达式 cadence 0 返回一个 int因为赋值运算符返回与其左操作数相同数据类型的值在这种情况下cadence 是一个 int。从其他表达式中可以看到表达式也可以返回其他类型的值比如 boolean 或 String。
Java 编程语言允许你从各种较小的表达式构建复合表达式只要表达式的一部分所需的数据类型与另一部分的数据类型匹配。以下是一个复合表达式的示例 1 * 2 * 3
在这个特定的例子中表达式的计算顺序并不重要因为乘法的结果与顺序无关无论你如何应用乘法结果始终相同。然而并非所有表达式都是如此。例如下面的表达式根据你是先执行加法还是除法操作而得出不同的结果
x y / 100 // ambiguous
你可以使用平衡的括号( 和 )来明确指定表达式的计算方式。例如为了使前面的表达式不含糊你可以写成以下形式 (x y) / 100 // unambiguous, recommended
如果你不明确指定操作的执行顺序操作的顺序将由表达式中使用的运算符分配的优先级决定。具有更高优先级的运算符首先计算。例如除法运算符的优先级高于加法运算符。因此以下两个语句是等价的
x y / 100 x (y / 100) // unambiguous, recommended
在编写复合表达式时要明确指出哪些运算符应该首先计算并用括号表示。这种做法使代码更易于阅读和维护。
语句
语句大致相当于自然语言中的句子。语句 形成一个完整的执行单元。以下类型的表达式可以通过在表达式末尾加上分号 (;) 来转换为语句。 赋值表达式 任何使用 或 -- 的情况 方法调用 对象创建表达式
这些语句被称为 表达语句。以下是一些表达语句的例子。
// assignment statement
aValue 8933.234;
// increment statement
aValue;
// method invocation statement
System.out.println(Hello World!);
// object creation statement
Bicycle myBike new Bicycle();
除了表达语句外还有另外两种语句声明语句 和 控制流语句。声明语句 用于声明一个变量。你已经看过很多声明语句的例子了
// declaration statement
double aValue 8933.234;
最后控制流语句 调节语句执行的顺序。你将在下一节学习有关控制流语句的内容控制流语句。
块
一个 块 是在平衡大括号之间的零个或多个语句组成的组可以在允许单个语句的任何地方使用。下面的例子BlockDemo演示了块的使用
class BlockDemo {public static void main(String[] args) {boolean condition true;if (condition) { // begin block 1System.out.println(Condition is true.);} // end block oneelse { // begin block 2System.out.println(Condition is false.);} // end block 2}
}
问题和练习表达式、语句和块 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/QandE/questions_expressions.html 问题 运算符可用于构建 ___计算值。 表达式是 ___ 的核心组件。 语句可以分组为 ___。 以下代码片段是 ___ 表达式的示例。 1 * 2 * 3 语句在自然语言中大致相当于句子但语句以 ___ 结尾而不是句号。 块是在平衡 ___ 之间的零个或多个语句组成的组可以在允许单个语句的任何地方使用。
练习
识别以下种类的表达语句 aValue 8933.234; aValue; System.out.println(Hello World!); Bicycle myBike new Bicycle();
检查你的答案
控制流语句 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/flow.html 源文件中的语句通常按照它们出现的顺序从上到下执行。然而控制流语句通过使用决策、循环和分支打破执行流程使您的程序能够有条件地执行特定的代码块。本节描述了 Java 编程语言支持的决策语句if-then、if-then-else、switch、循环语句for、while、do-while和分支语句break、continue、return。
if-then 和 if-then-else 语句 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/if.html if-then 语句
if-then 语句是所有控制流语句中最基本的。它告诉你的程序仅当特定测试评估为 true 时才执行某个代码段。例如Bicycle 类可以允许刹车减少自行车的速度仅当自行车已经在运动中时。applyBrakes 方法的一个可能的实现如下
void applyBrakes() {// the if clause: bicycle must be movingif (isMoving){ // the then clause: decrease current speedcurrentSpeed--;}
}
如果这个测试评估为 false意味着自行车没有在运动中控制跳转到 if-then 语句的末尾。
此外如果“then”子句只包含一个语句则开头和结尾的大括号是可选的
void applyBrakes() {// same as above, but without braces if (isMoving)currentSpeed--;
}
决定何时省略大括号是个人品味的问题。省略它们可能会使代码更脆弱。如果稍后向“then”子句添加第二个语句一个常见的错误是忘记添加新需要的大括号。编译器无法捕捉到这种错误你只会得到错误的结果。
if-then-else 语句
if-then-else 语句在“if”子句评估为 false 时提供了执行的第二路径。你可以在 applyBrakes 方法中使用 if-then-else 语句如果自行车在静止状态下刹车就采取一些行动。在这种情况下行动就是简单地打印一个错误消息说明自行车已经停止了。
void applyBrakes() {if (isMoving) {currentSpeed--;} else {System.err.println(The bicycle has already stopped!);}
}
以下程序IfElseDemo根据测试分数的值分配等级90% 或以上为 A80% 或以上为 B依此类推。 class IfElseDemo {public static void main(String[] args) {int testscore 76;char grade;if (testscore 90) {grade A;} else if (testscore 80) {grade B;} else if (testscore 70) {grade C;} else if (testscore 60) {grade D;} else {grade F;}System.out.println(Grade grade);}
}
程序的输出是 Grade C
你可能已经注意到 testscore 的值可以满足复合语句中的多个表达式76 70 和 76 60。然而一旦条件满足适当的语句就会被执行grade C;剩余的条件就不会被评估。
switch 语句 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html 与 if-then 和 if-then-else 语句不同switch 语句可以有多个可能的执行路径。switch 适用于 byte、short、char 和 int 原始数据类型。它还适用于枚举类型在 枚举类型 中讨论、String 类以及包装某些原始类型的几个特殊类Character、Byte、Short 和 Integer在 数字和字符串 中讨论。
以下代码示例SwitchDemo声明了一个名为 month 的 int其值表示一个月份。该代码根据 month 的值使用 switch 语句显示月份的名称。 public class SwitchDemo {public static void main(String[] args) {int month 8;String monthString;switch (month) {case 1: monthString January;break;case 2: monthString February;break;case 3: monthString March;break;case 4: monthString April;break;case 5: monthString May;break;case 6: monthString June;break;case 7: monthString July;break;case 8: monthString August;break;case 9: monthString September;break;case 10: monthString October;break;case 11: monthString November;break;case 12: monthString December;break;default: monthString Invalid month;break;}System.out.println(monthString);}
}
在这种情况下August 被打印到标准输出。
switch 语句的主体称为switch 块。switch 块中的语句可以带有一个或多个 case 或 default 标签。switch 语句评估其表达式然后执行所有匹配 case 标签后的语句。
你也可以使用 if-then-else 语句显示月份的名称
int month 8;
if (month 1) {System.out.println(January);
} else if (month 2) {System.out.println(February);
}
... // and so on
决定是使用 if-then-else 语句还是 switch 语句取决于可读性和语句测试的表达式。if-then-else 语句可以测试基于值范围或条件的表达式而 switch 语句仅基于单个整数、枚举值或 String 对象测试表达式。
break 语句是另一个有趣的点。每个 break 语句终止包含的 switch 语句。控制流继续执行 switch 块后的第一条语句。break 语句是必要的因为没有它们switch 块中的语句会穿透匹配的 case 标签后的所有语句会按顺序执行而不管后续 case 标签的表达式如何直到遇到 break 语句。程序 SwitchDemoFallThrough 展示了在 switch 块中穿透的语句。该程序显示了对应整数 month 的月份以及该年后续的月份 public class SwitchDemoFallThrough {public static void main(String[] args) {java.util.ArrayListString futureMonths new java.util.ArrayListString();int month 8;switch (month) {case 1: futureMonths.add(January);case 2: futureMonths.add(February);case 3: futureMonths.add(March);case 4: futureMonths.add(April);case 5: futureMonths.add(May);case 6: futureMonths.add(June);case 7: futureMonths.add(July);case 8: futureMonths.add(August);case 9: futureMonths.add(September);case 10: futureMonths.add(October);case 11: futureMonths.add(November);case 12: futureMonths.add(December);break;default: break;}if (futureMonths.isEmpty()) {System.out.println(Invalid month number);} else {for (String monthName : futureMonths) {System.out.println(monthName);}}}
}
这是代码的输出
August
September
October
November
December
从技术上讲最后的break并不是必需的因为流程会跳出switch语句。建议使用break这样修改代码会更容易也更少出错。default部分处理了所有未被case部分显式处理的值。
以下代码示例SwitchDemo2展示了一个语句可以有多个case标签。该代码示例计算了特定月份的天数 class SwitchDemo2 {public static void main(String[] args) {int month 2;int year 2000;int numDays 0;switch (month) {case 1: case 3: case 5:case 7: case 8: case 10:case 12:numDays 31;break;case 4: case 6:case 9: case 11:numDays 30;break;case 2:if (((year % 4 0) !(year % 100 0))|| (year % 400 0))numDays 29;elsenumDays 28;break;default:System.out.println(Invalid month.);break;}System.out.println(Number of Days numDays);}
}
这是代码的输出
Number of Days 29
在switch语句中使用字符串。
在 Java SE 7 及更高版本中可以在switch语句的表达式中使用String对象。以下代码示例StringSwitchDemo根据名为month的String的值显示月份的数字 public class StringSwitchDemo {public static int getMonthNumber(String month) {int monthNumber 0;if (month null) {return monthNumber;}switch (month.toLowerCase()) {case january:monthNumber 1;break;case february:monthNumber 2;break;case march:monthNumber 3;break;case april:monthNumber 4;break;case may:monthNumber 5;break;case june:monthNumber 6;break;case july:monthNumber 7;break;case august:monthNumber 8;break;case september:monthNumber 9;break;case october:monthNumber 10;break;case november:monthNumber 11;break;case december:monthNumber 12;break;default: monthNumber 0;break;}return monthNumber;}public static void main(String[] args) {String month August;int returnedMonthNumber StringSwitchDemo.getMonthNumber(month);if (returnedMonthNumber 0) {System.out.println(Invalid month);} else {System.out.println(returnedMonthNumber);}}
}
这段代码的输出是8。
switch表达式中的String与与每个case标签关联的表达式进行比较就好像使用了String.equals方法一样。为了使StringSwitchDemo示例接受任何大小写的月份month被转换为小写使用toLowerCase方法并且所有与case标签关联的字符串都是小写的。
注意此示例检查switch语句中的表达式是否为null。确保任何switch语句中的表达式不为 null以防止抛出NullPointerException。
while 和 do-while 语句 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html while语句在特定条件为true时持续执行一组语句。其语法可以表示为
while (expression) {statement(s)
}
while语句评估表达式该表达式必须返回一个boolean值。如果表达式评估为truewhile语句执行while块中的语句。while语句继续测试表达式并执行其块直到表达式评估为false。使用while语句打印从 1 到 10 的值可以通过以下WhileDemo程序实现 class WhileDemo {public static void main(String[] args){int count 1;while (count 11) {System.out.println(Count is: count);count;}}
}
您可以使用while语句实现无限循环如下所示
while (true){// your code goes here
}
Java 编程语言还提供了do-while语句可以表示如下
do {statement(s)
} while (expression);
do-while和while之间的区别在于do-while在循环底部评估其表达式而不是在顶部。因此do块内的语句始终至少执行一次如下所示的DoWhileDemo程序中所示 class DoWhileDemo {public static void main(String[] args){int count 1;do {System.out.println(Count is: count);count;} while (count 11);}
}
for 语句 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html for语句提供了一种紧凑的方式来遍历一系列值。程序员通常将其称为for 循环因为它会重复循环直到满足特定条件为止。for语句的一般形式可以表示如下
for (*initialization*; *termination*;*increment*) {*statement(s)*
}
使用这个版本的for语句时请记住 初始化表达式初始化循环它在循环开始时执行一次。 当终止表达式评估为false时循环终止。 增量表达式在每次循环迭代之后被调用这个表达式完全可以递增或递减一个值。
以下程序ForDemo使用for语句的一般形式将数字 1 到 10 打印到标准输出 class ForDemo {public static void main(String[] args){for(int i1; i11; i){System.out.println(Count is: i);}}
}
该程序的输出是
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10
请注意代码如何在初始化表达式中声明一个变量。该变量的作用域从其声明延伸到由for语句控制的块的末尾因此它也可以在终止和增量表达式中使用。如果控制for语句的变量在循环外不需要则最好在初始化表达式中声明该变量。通常使用i、j和k这些名称来控制for循环在初始化表达式中声明它们会限制它们的生命周期并减少错误。
for循环的三个表达式是可选的可以创建一个无限循环如下所示
// infinite loop
for ( ; ; ) {// your code goes here
}
for语句还有另一种形式专为遍历集合和数组设计。这种形式有时被称为增强型 for语句可使您的循环更加简洁和易读。为了演示考虑以下数组其中包含 1 到 10 的数字
int[] numbers {1,2,3,4,5,6,7,8,9,10};
以下程序EnhancedForDemo使用增强型for循环遍历数组 class EnhancedForDemo {public static void main(String[] args){int[] numbers {1,2,3,4,5,6,7,8,9,10};for (int item : numbers) {System.out.println(Count is: item);}}
}
在这个例子中变量item保存来自数字数组的当前值。该程序的输出与之前相同
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10
我们建议尽可能使用这种形式的for语句而不是一般形式。
分支语句 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html break 语句
break 语句有两种形式带标签和未标记。在前面讨论 switch 语句时看到了未标记形式。您还可以使用未标记的 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类似于前一个程序但使用嵌套的 for 循环在二维数组中搜索一个值。当找到该值时带标签的 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遍历一个 String计算字母 “p” 的出现次数。如果当前字符不是 p则 continue 语句跳过循环的其余部分并继续下一个字符。如果是 “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 psif (searchMe.charAt(i) ! p)continue;// process psnumPs;}System.out.println(Found numPs ps in the string.);}
}
这是该程序的输出
Found 9 ps in the string.
要更清楚地看到这种效果请尝试删除 continue 语句并重新编译。再次运行程序时计数将出错显示找到了 35 个 p而不是 9 个。
带标签的 continue 语句跳过带有给定标签的外部循环的当前迭代。下面的示例程序ContinueWithLabelDemo使用嵌套循环在另一个字符串中搜索子字符串。需要两个嵌套循环一个用于迭代子字符串一个用于迭代被搜索的字符串。下面的程序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 : Didnt find it);}
}
这是该程序的输出。
Found it
return 语句
分支语句中的最后一个是return语句。return语句退出当前方法控制流返回到调用方法的位置。return语句有两种形式一种返回一个值另一种不返回。要返回一个值只需在return关键字后面放置该值或计算该值的表达式。
return count;
返回值的数据类型必须与方法声明的返回值类型匹配。当方法声明为void时使用不返回值的return形式。
return;
类和对象课程将涵盖你需要了解的关于编写方法的一切。
控制流语句总结 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/flowsummary.html if-then语句是所有控制流语句中最基本的。它告诉你的程序只有在特定测试评估为true时才执行某个代码段。if-then-else语句在“if”子句评估为false时提供了一个备用执行路径。与if-then和if-then-else不同switch语句允许任意数量的执行路径。while和do-while语句在特定条件为true时持续执行一系列语句。do-while和while之间的区别在于do-while在循环底部评估其表达式而不是顶部。因此do块内的语句至少会执行一次。for语句提供了一种紧凑的方式来迭代一系列值。它有两种形式其中一种设计用于循环遍历集合和数组。
问题和练习控制流语句 原文docs.oracle.com/javase/tutorial/java/nutsandbolts/QandE/questions_flow.html 问题 Java 编程语言支持的最基本的控制流语句是 ___ 语句。 ___ 语句允许任意数量的可能执行路径。 ___ 语句类似于while语句但在循环的 ___ 处评估其表达式。 如何使用for语句编写一个无限循环 如何使用while语句编写一个无限循环
练习 考虑以下代码片段。 if (aNumber 0)if (aNumber 0)System.out.println(first string);
else System.out.println(second string);
System.out.println(third string); 如果aNumber为 3你认为代码会产生什么输出 编写一个包含上述代码片段的测试程序将aNumber设为 3。程序的输出是什么是否符合你的预期解释输出为何是这样的换句话说代码片段的控制流是什么 仅使用空格和换行符重新格式化代码片段使控制流更易于理解。 使用大括号{ 和 }进一步澄清代码。
检查你的答案
课程类和对象 原文docs.oracle.com/javase/tutorial/java/javaOO/index.html 有了你现在对 Java 编程语言基础知识的了解你可以学会编写自己的类。在本课程中您将找到有关定义自己的类的信息包括声明成员变量、方法和构造函数。
您将学会使用您的类来创建对象以及如何使用您创建的对象。
本课程还涵盖了将类嵌套在其他类中以及枚举的内容
类
本节展示了类的结构以及如何声明字段、方法和构造函数。
对象
本节介绍了创建和使用对象。您将学习如何实例化对象以及一旦实例化如何使用点运算符访问对象的实例变量和方法。
更多关于类
本节涵盖了更多依赖于在前一节中学到的对象引用和点运算符的类的方面从方法返回值this关键字类与实例成员以及访问控制。
嵌套类
静态嵌套类、内部类、匿名内部类、局部类和 lambda 表达式都有涵盖。还讨论了何时使用哪种方法。
枚举类型
本节介绍了枚举这是一种特殊的类允许您定义和使用一组常量。
类 原文docs.oracle.com/javase/tutorial/java/javaOO/classes.html 在标题为面向对象编程概念的课程中介绍了面向对象概念以自行车类为例其中赛车、山地车和双人车为子类。以下是一个可能实现Bicycle类的示例代码让你了解类声明的概述。本课程的后续部分将逐步支持和解释类声明。暂时不要担心细节。
public class Bicycle {// the Bicycle class has// three *fields*public int cadence;public int gear;public int speed;// the Bicycle class has// one *constructor*public Bicycle(int startCadence, int startSpeed, int startGear) {gear startGear;cadence startCadence;speed startSpeed;}// the Bicycle class has// four *methods*public void setCadence(int newValue) {cadence newValue;}public void setGear(int newValue) {gear newValue;}public void applyBrake(int decrement) {speed - decrement;}public void speedUp(int increment) {speed increment;}}
MountainBike类的类声明作为Bicycle的子类可能如下所示
public class MountainBike extends Bicycle {// the MountainBike subclass has// one *field*public int seatHeight;// the MountainBike subclass has// one *constructor*public MountainBike(int startHeight, int startCadence,int startSpeed, int startGear) {super(startCadence, startSpeed, startGear);seatHeight startHeight;} // the MountainBike subclass has// one *method*public void setHeight(int newValue) {seatHeight newValue;} }
MountainBike继承了Bicycle的所有字段和方法并添加了seatHeight字段以及一个设置它的方法山地车的座位可以根据地形要求上下移动。
声明类 原文docs.oracle.com/javase/tutorial/java/javaOO/classdecl.html 你已经看到以下方式定义的类
class *MyClass* {// field, constructor, and // method declarations
}
这是一个类声明。类体大括号之间的区域包含了为从类创建的对象的生命周期提供支持的所有代码用于初始化新对象的构造函数提供类及其对象状态的字段声明以及实现类及其对象行为的方法。
前面的类声明是一个最小的类声明。它只包含了类声明中所需的组件。你可以在类声明的开头提供关于类的更多信息比如其超类的名称是否实现了任何接口等。例如
class *MyClass extends MySuperClass implements YourInterface* {// field, constructor, and// method declarations
}
意味着MyClass是MySuperClass的子类并且实现了YourInterface接口。
你也可以在最开始添加像public或private这样的修饰符—所以你可以看到类声明的开头行可能会变得相当复杂。决定其他类能否访问MyClass的修饰符public和private将在本课程的后面讨论。关于接口和继承的课程将解释在类声明中为什么以及如何使用extends和implements关键字。目前你不需要担心这些额外的复杂性。
一般来说类声明可以按顺序包括这些组件 修饰符比如public、private以及你以后会遇到的其他一些修饰符。但是请注意private修饰符只能应用于嵌套类。 类名按照约定首字母大写。 类的父类超类的名称如果有的话前面带有关键字extends。一个类只能扩展子类化一个父类。 一个逗号分隔的接口列表如果有的话前面带有关键字implements。一个类可以实现多个接口。 类体用大括号{}括起来。
声明成员变量 原文docs.oracle.com/javase/tutorial/java/javaOO/variables.html 有几种类型的变量 类中的成员变量—这些被称为字段。 方法或代码块中的变量—这些被称为局部变量。 方法声明中的变量—这些被称为参数。
Bicycle 类使用以下代码行来定义其字段
public int cadence;
public int gear;
public int speed;
字段声明由三个组件组成顺序为 零个或多个修饰符比如public或private。 字段的类型。 字段的名称。
Bicycle 的字段名为cadence、gear和speed都是整数类型int。public关键字将这些字段标识为公共成员可被任何可以访问该类的对象访问。
访问修饰符
使用的第一个最左边的修饰符让你控制其他类对成员字段的访问权限。目前只考虑public和private。其他访问修饰符将在后面讨论。 public修饰符—该字段可从所有类访问。 private修饰符—该字段只能在其自身类中访问。
符合封装原则通常会将字段设为私有。这意味着它们只能从Bicycle类直接访问。然而我们仍然需要访问这些值。这可以通过添加获取字段值的公共方法间接完成
public class Bicycle {private int cadence;private int gear;private int speed;public Bicycle(int startCadence, int startSpeed, int startGear) {gear startGear;cadence startCadence;speed startSpeed;}public int getCadence() {return cadence;}public void setCadence(int newValue) {cadence newValue;}public int getGear() {return gear;}public void setGear(int newValue) {gear newValue;}public int getSpeed() {return speed;}public void applyBrake(int decrement) {speed - decrement;}public void speedUp(int increment) {speed increment;}
}
类型
所有变量必须有一个类型。你可以使用原始类型如int、float、boolean等。或者你可以使用引用类型比如字符串、数组或对象。
变量名
所有变量无论是字段、局部变量还是参数都遵循在语言基础课程中介绍的相同的命名规则和约定变量—命名。
在这节课中请注意方法和类名使用相同的命名规则和约定除了 类名的第一个字母应大写而 方法名的第一个或唯一单词应该是动词。
定义方法 原文docs.oracle.com/javase/tutorial/java/javaOO/methods.html 这是一个典型方法声明的示例
public double calculateAnswer(double wingSpan, int numberOfEngines,double length, double grossTons) {//do the calculation here
}
方法声明的唯一必需元素是方法的返回类型、名称、一对括号()以及大括号{}之间的方法体。
更一般地方法声明有六个组成部分顺序如下 修饰符—例如public、private等以及其他你将在后面学习的内容。 返回类型—方法返回的值的数据类型或者如果方法不返回值则为void。 方法名称—字段名称的规则也适用于方法名称但约定略有不同。 括号中的参数列表—以逗号分隔的输入参数列表前面是它们的数据类型用括号()括起来。如果没有参数必须使用空括号。 一个异常列表—稍后讨论。 方法体用大括号括起来—方法的代码包括局部变量的声明在这里。
修饰符、返回类型和参数将在本课程的后续部分讨论。异常将在后续课程中讨论。 定义 方法声明的两个组成部分构成了方法签名—方法的名称和参数类型。 上面声明的方法的签名是
calculateAnswer(double, int, double, double)
命名方法
尽管方法名称可以是任何合法标识符但代码约定限制了方法名称。按照约定方法名称应该是小写的动词或以小写动词开头的多词名称后面跟着形容词、名词等。在多词名称中第二个及后续单词的第一个字母应大写。以下是一些示例
run
runFast
getBackground
getFinalData
compareTo
setX
isEmpty
通常一个方法在其类中具有唯一的名称。但是由于方法重载一个方法可能与其他方法具有相同的名称。
方法重载
Java 编程语言支持方法重载并且 Java 可以区分具有不同方法签名的方法。这意味着类中的方法如果具有不同的参数列表则可以具有相同的名称对此有一些限制将在标题为“接口和继承”的课程中讨论。
假设你有一个可以使用书法来绘制各种类型数据字符串、整数等的类并且包含一个用于绘制每种数据类型的方法。为每个方法使用新名称很麻烦—例如drawString、drawInteger、drawFloat等。在 Java 编程语言中你可以为所有绘制方法使用相同的名称但对每个方法传递不同的参数列表。因此数据绘制类可能声明四个名为draw的方法每个方法都有不同的参数列表。
public class DataArtist {...public void draw(String s) {...}public void draw(int i) {...}public void draw(double f) {...}public void draw(int i, double f) {...}
}
过载方法通过传入方法的参数的数量和类型来区分。在代码示例中draw(String s) 和 draw(int i) 是不同且独特的方法因为它们需要不同的参数类型。
你不能声明多个具有相同名称和相同数量及类型参数的方法因为编译器无法区分它们。
编译器在区分方法时不考虑返回类型因此即使它们具有不同的返回类型也不能声明具有相同签名的两个方法。 注意 过载方法应该谨慎使用因为它们会使代码变得难以阅读。 为你的类提供构造函数 原文docs.oracle.com/javase/tutorial/java/javaOO/constructors.html 一个类包含用于从类蓝图创建对象的构造函数。构造函数声明看起来像方法声明只是它们使用类的名称并且没有返回类型。例如Bicycle有一个构造函数
public Bicycle(int startCadence, int startSpeed, int startGear) {gear startGear;cadence startCadence;speed startSpeed;
}
要创建一个名为myBike的新Bicycle对象需要通过new运算符调用构造函数
Bicycle myBike new Bicycle(30, 0, 8);
new Bicycle(30, 0, 8)在内存中为对象创建空间并初始化其字段。
尽管Bicycle只有一个构造函数但它可以有其他构造函数包括无参数构造函数
public Bicycle() {gear 1;cadence 10;speed 0;
}
Bicycle yourBike new Bicycle();调用无参数构造函数以创建一个名为yourBike的新Bicycle对象。
由于它们具有不同的参数列表两个构造函数都可以在Bicycle中声明。与方法一样Java 平台根据参数列表中参数的数量和类型区分构造函数。你不能为同一个类编写具有相同数量和类型参数的两个构造函数因为平台无法区分它们。这样做会导致编译时错误。
你不必为你的类提供任何构造函数但在这样做时必须小心。编译器会自动为没有构造函数的任何类提供一个无参数默认构造函数。这个默认构造函数将调用超类的无参数构造函数。在这种情况下如果超类没有无参数构造函数编译器会报错因此你必须验证它是否有。如果你的类没有显式的超类那么它有一个隐式的超类Object它有一个无参数构造函数。
你可以自己使用超类构造函数。本课程开头的MountainBike类就是这样做的。这将在后面关于接口和继承的课程中讨论。
你可以在构造函数的声明中使用访问修饰符来控制哪些其他类可以调用该构造函数。 **注意**如果另一个类无法调用MyClass构造函数则无法直接创建MyClass对象。 向方法或构造函数传递信息 原文docs.oracle.com/javase/tutorial/java/javaOO/arguments.html 方法或构造函数的声明声明了该方法或构造函数的参数的数量和类型。例如以下是一个计算房屋贷款月供的方法基于贷款金额、利率、贷款期限期数和贷款的未来价值
public double computePayment(double loanAmt,double rate,double futureValue,int numPeriods) {double interest rate / 100.0;double partial1 Math.pow((1 interest), - numPeriods);double denominator (1 - partial1) / interest;double answer (-loanAmt / denominator)- ((futureValue * partial1) / denominator);return answer;
}
该方法有四个参数贷款金额、利率、未来价值和期数。前三个是双精度浮点数第四个是整数。这些参数在方法体中被使用并在运行时将采用传递的参数的值。 注意 参数指的是方法声明中的变量列表。参数是在调用方法时传递的实际值。当您调用方法时使用的参数必须与声明的参数在类型和顺序上匹配。 参数类型
您可以为方法或构造函数的参数使用任何数据类型。这包括原始数据类型如双精度、浮点数和整数就像您在computePayment方法中看到的那样以及引用数据类型如对象和数组。
这是一个接受数组作为参数的方法的示例。在这个示例中该方法创建一个新的Polygon对象并从一个Point对象数组中初始化它假设Point是表示 x、y 坐标的类
public Polygon polygonFrom(Point[] corners) {// method body goes here
} **注意**如果您想将一个方法传递给另一个方法那么请使用 lambda 表达式或方法引用。 任意数量的参数
您可以使用称为varargs的构造来传递任意数量的值给方法。当您不知道将传递给方法的特定类型的参数有多少时可以使用 varargs。这是一种快捷方式可以手动创建数组前一个方法可以使用 varargs 而不是数组。
要使用 varargs您需要在最后一个参数的类型后面加上省略号三个点…然后是一个空格和参数名。然后该方法可以使用任意数量的该参数调用包括零个。
public Polygon polygonFrom(Point... corners) {int numberOfSides corners.length;double squareOfSide1, lengthOfSide1;squareOfSide1 (corners[1].x - corners[0].x)* (corners[1].x - corners[0].x) (corners[1].y - corners[0].y)* (corners[1].y - corners[0].y);lengthOfSide1 Math.sqrt(squareOfSide1);// more method body code follows that creates and returns a // polygon connecting the Points
}
您可以看到在方法内部corners被视为数组。该方法可以使用数组或一系列参数调用。方法体中的代码将在任何情况下将参数视为数组。
您最常见地会在打印方法中看到 varargs例如这个printf方法
public PrintStream printf(String format, Object... args)
允许您打印任意数量的对象。可以这样调用
System.out.printf(%s: %d, %s%n, name, idnum, address);
或者像这样
System.out.printf(%s: %d, %s, %s, %s%n, name, idnum, address, phone, email);
或者使用不同数量的参数。
参数名称
当您向方法或构造函数声明参数时为该参数提供一个名称。此名称在方法体内用于引用传入的参数。
参数的名称在其作用域内必须是唯一的。它不能与同一方法或构造函数的另一个参数的名称相同也不能与方法或构造函数内的局部变量的名称相同。
参数可以与类的字段之一具有相同的名称。如果是这种情况则说参数遮蔽了字段。字段遮蔽可能会使您的代码难以阅读并且通常仅在设置特定字段的构造函数和方法中使用。例如考虑以下 Circle 类及其 setOrigin 方法
public class Circle {private int x, y, radius;public void setOrigin(int x, int y) {...}
}
Circle 类有三个字段x、y 和 radius。setOrigin 方法有两个参数每个参数的名称与一个字段的名称相同。每个方法参数都会遮蔽与其名称相同的字段。因此在方法体内使用简单名称 x 或 y 指的是参数而不是字段。要访问字段必须使用限定名称。这将在本课程的后面部分“使用 this 关键字”中讨论。
传递原始数据类型参数
原始参数如 int 或 double是通过值传递给方法的。这意味着对参数值的任何更改仅存在于方法的范围内。当方法返回时参数消失对它们的任何更改都将丢失。以下是一个例子
public class PassPrimitiveByValue {public static void main(String[] args) {int x 3;// invoke passMethod() with // x as argumentpassMethod(x);// print x to see if its // value has changedSystem.out.println(After invoking passMethod, x x);}// change parameter in passMethod()public static void passMethod(int p) {p 10;}
}
运行此程序时输出为
After invoking passMethod, x 3
传递引用数据类型参数
引用数据类型参数如对象也是通过值传递给方法的。这意味着当方法返回时传入的引用仍然引用与之前相同的对象。但是如果对象的字段值具有适当的访问级别则可以在方法中更改对象的字段值。
例如考虑一个在任意类中移动 Circle 对象的方法
public void moveCircle(Circle circle, int deltaX, int deltaY) {// code to move origin of circle to xdeltaX, ydeltaYcircle.setX(circle.getX() deltaX);circle.setY(circle.getY() deltaY);// code to assign a new reference to circlecircle new Circle(0, 0);
}
让方法使用这些参数被调用
moveCircle(myCircle, 23, 56)
在方法内部circle 最初指向 myCircle。该方法更改了 circle 引用的对象即 myCircle的 x 和 y 坐标分别为 23 和 56。这些更改将在方法返回时保留。然后 circle 被赋予一个新的 Circle 对象的引用其中 x y 0。然而这种重新赋值并不具有永久性因为引用是通过值传递的不能更改。在方法内部circle 指向的对象已经改变但是当方法返回时myCircle 仍然引用与调用方法之前相同的 Circle 对象。