作符
主要操作符:+、-、*、/、=、++、--、+=、-=、==、!=、&&、||、!、&、^、~、>=、<=、>、<
…..
几乎所有的操作符只能够操作”基本数据类型”,=、==、!=可以操作所有的数据类型及对象
String类型支持+、+=连接操作
优先级问题:
此处注意:任何数据类型与String类型进行+连接都将会先将其他的数据类型转变为String在连接成String类型
而此时的+不再会做任何的计算
demo:
int i = 1;
int j = 2;
System.out.println("result:" + i + j);//result:12
System.out.println("i == j : " + i == j);// ×
System.out.println("i == j : " + (i == j));// √ |
关于赋值操作符:取右边的值(即右值),把它复制给左边(即左值)。右值可以是任何常数、变量、或者表达式(只要它能够生成一个值就行)。但左值必须是一个明确的、已命名的变量,也就是必须有一个物理空间可以存储等号右边的值
基本数据类型赋值:直接将一个地方的值复制到另外一个地方
a = b;//b的内容复制给a,若修改a或b其中的一个值,另外一个值不会受到任何影响
对象赋值:真正操作的是对象的引用,
所以将对象赋值给另外一个对象实际上是将一个对象的引用复制到另外一个地方
它们其实指向的是内存中的同一块内容
demo:ObjectRefrenceTest.java
packagejavabase.flowcontrol;
publicclassObjectRefrenceTest{
/**
*对象赋值测试
*/
publicstaticvoidmain(String[]args){
Rowidrowid=newRowid();
rowid.rowid="LIYIHUIZHANYUANYING";
TiptopERPtopprod=newTiptopERP();
TiptopERPtoptest=newTiptopERP();
topprod.seesionId=0;
topprod.DBType="Oracle";
topprod.rowid=rowid;
toptest=topprod;//对象赋值
System.out.println("Before:");
System.out.println("topprod:"+topprod.seesionId+topprod.DBType+topprod.rowid.rowid);
System.out.println("toptest:"+toptest.seesionId+toptest.DBType+toptest.rowid.rowid);
System.out.println("Afterchangetopprodobject:");
//toptest.DBType="Informix";
topprod.DBType="Informix";
topprod.rowid.rowid="5201314131413141314";//此处改变了topprod.rowid对象的成员变量
System.out.println("topprod:"+topprod.seesionId+topprod.DBType+topprod.rowid.rowid);
System.out.println("toptest:"+toptest.seesionId+toptest.DBType+toptest.rowid.rowid);
System.out.println("-----------------------------");
TiptopERPerp=newTiptopERP();
TiptopERPmrpII=newTiptopERP();
erp.seesionId=2;
erp.DBType="DB2";
erp.rowid=rowid;//此处直接将先前的rowid对象直接赋值给erp.rowid
mrpII.seesionId=erp.seesionId;//对象成员变量int单独赋值
mrpII.DBType=erp.DBType;//对象成员变量String单独赋值
mrpII.rowid=erp.rowid;
System.out.println("Before:");
System.out.println("erp:"+erp.seesionId+erp.DBType+erp.rowid.rowid);
System.out.println("mrpII:"+mrpII.seesionId+mrpII.DBType+mrpII.rowid.rowid);
System.out.println("Afterchangrowid:");
erp.rowid.rowid="LIYIHUIZHANYUANYING";//此处改变了erp.rowid对象的成员变量
System.out.println("erp:"+erp.seesionId+erp.DBType+erp.rowid.rowid);
System.out.println("mrpII:"+mrpII.seesionId+mrpII.DBType+mrpII.rowid.rowid);
System.out.println("Afterchangeerpobject:");
erp.seesionId=1;
erp.DBType="Mysql";
erp.rowid.rowid="5201314131413141314";//此处改变了erp.rowid对象的成员变量
System.out.println("erp:"+erp.seesionId+erp.DBType+erp.rowid.rowid);
System.out.println("mrpII:"+mrpII.seesionId+mrpII.DBType+mrpII.rowid.rowid);
}
}
classTiptopERP{
intseesionId;//基本数据类型
StringDBType;//String对象
Rowidrowid;//一般对象
}
classRowid{
Stringrowid;
}
/*输出结果:
Before:
topprod:0OracleLIYIHUIZHANYUANYING
toptest:0OracleLIYIHUIZHANYUANYING
Afterchangetopprodobject:
topprod:0Informix5201314131413141314//rowid值改变了
toptest:0Informix5201314131413141314//rowid值改变了
-----------------------------
Before:
erp:2DB25201314131413141314//rowid值改变了
mrpII:2DB25201314131413141314//rowid值改变了
Afterchangrowid:
erp:2DB2LIYIHUIZHANYUANYING//rowid值改变了
mrpII:2DB2LIYIHUIZHANYUANYING//rowid值改变了
Afterchangeerpobject:
erp:1Mysql5201314131413141314//rowid值改变了
mrpII:2DB25201314131413141314//rowid值改变了
*/
|
demo:PassObject.java
package javabase.flowcontrol;
class Letter{
char c;
}
public class PassObject {
/**
*对象引用
*/
static void f(Letter y){
y.c = 'z';
}
public static void main(String[] args) {
Letter x = new Letter();
x.c = 'a';
System.out.println("before:x.c = " + x.c);
f(x);
System.out.println("after:x.c = " + x.c);
}
}
/*输出结果:
before:x.c = a
after:x.c = z
*/
|
此类对于传递对象引用而引起的问题在Think In Java被称做”别名问题”
使用中应注意此类陷阱
++或--:前缀++/--先运算再生成值,后缀++/--先生成值再运算
==与equals:
比较2个实际值是否相等:对象用equals,基本数据类型用==
比较对象的地址是否相等:对象/基本数据类型都用==
demo:EqualsTest.java
package javabase.flowcontrol;
class ValueInt{
int id;
}
class ValueString{
String id;
@Override
public boolean equals(Object obj) {
boolean instanceFlag;
instanceFlag = obj instanceof ValueString;
if(!instanceFlag)
return super.equals(obj);
else{
ValueString vTemp = (ValueString)obj;
if(vTemp.id.equals(this.id)){
return true;
}
return false;
}
}
}
public class EqualsTest {
/**
* ==操作符、equals的区别
*/
public static void main(String[] args) {
//基本数据类型
int i1 = 100;
int i2 = 100;
System.out.println("i1 == i2 : " + (i1 == i2));
//对象
Integer n1 = new Integer(250);
Integer n2 = new Integer(250);
System.out.println("n1 == n2 : " + (n1 == n2));
System.out.println("n1 equals n2 : " + n1.equals(n2));
//自定义对象
ValueInt vInt1 = new ValueInt();
ValueInt vInt2 = new ValueInt();
vInt1.id = vInt2.id = 32;
System.out.println("vInt1 == vInt2 : " + (vInt1 == vInt2));
System.out.println("vInt1 equals vInt2 : " + vInt1.equals(vInt2));
ValueString vString1 = new ValueString();
ValueString vString2 = new ValueString();
vString1.id = vString2.id = "李艺辉";
System.out.println("vString1 == vString2 : " + (vString1 == vString2));
System.out.println("vString1 equals vString2 : " + vString1.equals(vString2));
//String 对象比较复杂,后面会有String对象的详细解析
}
}
/*输出结果:
i1 == i2 : true
n1 == n2 : false
n1 equals n2 : true
vInt1 == vInt2 : false
vInt1 equals vInt2 : false //这是因为equals默认行为是比较2个对象的引用
vString1 == vString2 : false
vString1 equals vString2 : true //复写该对象的equals方法后的比较
*/
|
逻辑操作符:&&、||、!
逻辑操作只可以应用于布尔值,注意逻辑操作的”短路”情况
test(1) && test(2) && test(3) //顺序判断,只要前面有一个test为假后面的判断就不需要执行了
test(1) || test(2) || test(3) //顺序判断,只要前面有一个test为真后面的判断就不需要执行了
按位操作符:位与(&)、位或(|)、位非(~)、
有符号位左移(<<):低位补0
有符号位右移(>>):若符号为正则高位补0,若符号为负则高位补1
无符号位左移(<<<):无论正负低位全部补0
无符号位右移(>>>):无论正负高位全部补0
如果对char、byte、short类型数值进行移位处理,那么在移位之前它们都将先被转换为int类型,
并且得到的结果也是int类型,且移位后的数值结果只有低5位才有用(int类型为2的5次方)
三元操作符:
boolean-exp ? value0 : value1
如果布尔表达式boolean-exp为true则计算value0,否则计算value1
控制执行流程
关键字:Java控制执行流程主要涉及的关键字if-else、while、do-while、for、return、break、continue
Java并不支持goto語句,但是在java中仍然保留了goto
条件判断:所有条件判断都利用条件表达式的真或假来决定执行流程
注意:java不允许将一个数字等非boolean值作为布尔值使用,如果要在布尔测试中使用一个非布尔值则首先必须用一个条件表达式将其转换成布尔值。
Ex:a是非boolean类型值 if(a)×à if(a!=0) √
while:先判断条件表达在执行循环体,条件为false则一次都不执行
do-while:先执行循环体,再判断条件表达式,因此至少会执行一次
for语句:for(int i = 1, j = 5;i < 5;i++,j = i+2)
for语句初始化部分实际上可以定义任意数量的变量,注意:但是这些变量都必须是同一种数据类型
for语句中可以使用一系列有逗号表达式分隔的语句
增强行的for循环:for(char c : “hello world”.toCharArray())
如果for循环有索引或是步进,则上述增强行的for循环不能够直接满足需求
Think in java 建议自写一个range()方法配合增强型的for循环
import static net.mindview.util.range.* //此包需从www.mindview.com上下载
Ex:for(int i : range(10)) //range(10)返回数组,元素为0..9
for(int i : range(5,10)) //range(5,10)返回数组,元素为5..9
for(int i : range(5,10,3)) //range(5,10,3)返回数组,元素为5..10 step 3
while(true) = for(;;)
switch .. case...break语句:
switch(integral-selector) //integral-selector:选择因子必需是int或是char那样的整数值
case integral-value1:statement:break;
//
Default:statement;
|
单一case satatement后面需有break,避免case穿透到下一case
statement
return:指定一个方法的返回值,并退出该方法。
如果一个方法声明有非void的返回值,那么必须确保每一条代码路径都将返回一个值
break:终止当前循环体
continue:停止循环体的当前迭代,然后退回循环起始处,开始下一次迭代
goto:虽然java不再使用goto语句,但是依然保留了goto作为关键字
在java中如果想实现goto一样跳转语句的功能可以使用标签编程
请看如下demo:GotoLabel.java
package javabase.flowcontrol;
public class GotoLabel {
/**
*java标签编程应用
*/
public static void main(String[] args) {
int i = 0;
outer: //此处不可以写其它的任何代码
//System.out.println("outer man!");
for(;true;){
inner: //此处不可以写其它的任何代码
//System.out.println("innter man!");
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;
}
}
}
System.out.println("hello world");
}
System.out.println("fuck in java");
}
}
/*输出结果:
i = 0
continue inner
i = 1
continue inner
i = 2
continue
i = 3
break
hello world
i = 4
continue inner
i = 5
continue inner
i = 6
continue inner
i = 7
continue outer
i = 8
break outer
fuck in java
*/
|
一般的continue会退回最内层循环的开头,并继续执行
带标签的continue会到达标签的位置,并重新进入紧接在那个标签后面的循环
一般的break会中断并跳出当前的循环体
带标签的break会中断并跳出标签所指的循环
|