1赋值
1当方法传入引用类型时,该引用类型对对象的改变会影响实参所指向的对象的改变(这就是方法调用中的别名问题),当方法传入的是基本类型时,该形参基本类型怎么变也不会影响到实参的值。
代码例子:
class Letter {
char c;
}
public class Test
{
static void f(Letter y) {
y.c = 'z';
}
static void t(int a){
a=6;
}
public static void main(String[] args) {
Letter x = new Letter();
x.c = 'a';
System.out.println("1: x.c: " + x.c);
f(x);
System.out.println("2: x.c: " + x.c);
int a=78;
t(a);
System.out.println(a);
}
}
运行结果:
1: x.c: a
2: x.c: z
78
2逻辑操作符
1尽管逻辑操作符"与"(&&),"或"(||),"非"(!)能根据参数的逻辑关系,生成一个布尔值,但与在C与C++中不同的是:不可将一个非布尔值当做布尔值在逻辑表达式中使用,如果在应该使用String值的地方使用了布尔值,布尔值会自动转换成适当的文本形式。
代码例子:
public class Bool {
public static void main(String[] args) {
Random rand = new Random(47);
int i = rand.nextInt(100);
int j = rand.nextInt(100);
print("i = " + i);
print("j = " + j);
print("i > j is " + (i > j));
print("i < j is " + (i < j));
print("i >= j is " + (i >= j));
print("i <= j is " + (i <= j));
print("i == j is " + (i == j));
print("i != j is " + (i != j));
//编译不通过
//! print("i && j is " + (i && j));
//! print("i || j is " + (i || j));
//! print("!i is " + !i);
print("(i < 10) && (j < 10) is "
+ ((i < 10) && (j < 10)) );
print("(i < 10) || (j < 10) is "
+ ((i < 10) || (j < 10)) );
}
}
2&&与 &,||与|这两者区别是:&&和||一旦能够明确无误的确定整个表达式的值,就不再计算表达式余下部分了,而&和|会完整计算完整个表达式。
代码例子:
public class Test
{
static boolean test1(int val) {
System.out.println("test1(" + val + ")");
System.out.println("result: " + (val < 1));
return val < 1;
}
static boolean test2(int val) {
System.out.println("test2(" + val + ")");
System.out.println("result: " + (val < 2));
return val < 2;
}
static boolean test3(int val) {
System.out.println("test3(" + val + ")");
System.out.println("result: " + (val < 3));
return val < 3;
}
public static void main(String[] args) {
boolean b = test1(0) && test2(2) && test3(2);
System.out.println("b expression is " + b);
boolean a = test1(0) ||test2(2) || test3(2);
System.out.println("a expression is " + a);
}
}
运行结果:
test1(0)
result: true
test2(2)
result: false
b expression is false
test1(0)
result: true
a expression is true
3直接常量
1如果试图将一个变量初始化成超出自身表示范围的值,编译会不通过,如果将比较小的类型传递给Integer.toBinaryString()方法返回的时补码(而不是原码),则该类型将自动被转换为int。
代码例子:
//编译错误,因其值超出了char的范围
char c=0xfffffff;
char b='a';
//输出1100001,该二进制是补码,不是原码
System.out.println(Integer.toBinaryString(b));
2科学指数计数法,只适用于浮点数,注意的时,float的末尾需要加个f或F(因为Java默认的浮点数是double)。
代码例子:
//输出结果0.0013
float f=1.3e-3f;
//编译不通过,末尾少了f
float a=1.3e-3;
//编译通过,因为Java双精度默认类型是double
double b=1.32e-4;
//编译不通过,指数计数法只适用于浮点数
int h=1e-4;
//编译通过
double c=1e-5;
3进行位移运算时,char,byte或者short类型的数值移位处理时,会先转换成int类型,然后通过转换补码的移位运算得出的二进制,再将其转换原码就能得出十进制了(计算机是以补码形式存储)。
代码例子:
public class URShift {
public static void main(String[] args) {
int i = -1;
print(Integer.toBinaryString(i));
i >>>= 10;
print(Integer.toBinaryString(i));
long l = -1;
print(Long.toBinaryString(l));
l >>>= 10;
print(Long.toBinaryString(l));
short s = -1;
print(Integer.toBinaryString(s));
s >>>= 10;
print(Integer.toBinaryString(s));
byte b = -1;
print(Integer.toBinaryString(b));
b >>>= 10;
print(Integer.toBinaryString(b)); //①
b = -1;
print(Integer.toBinaryString(b));
print(Integer.toBinaryString(b>>>10));//②
}
}
运行结果:
11111111111111111111111111111111
1111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
1111111111111111111111
其中比较可能比较困惑的是①和②输出的结果为什么不一样呢?byte=-1时,在移位之前会转换成int类型,b>>>=10;这句话会让移位后的int类型变成十进制值赋给b故在此调用Integer.toBinaryString(b)时,又转换int类型,会输出int类型值的二进制补码,而直接用 print(Integer.toBinaryString(b>>>10)),这句话就是b转换int类型向右移十位后的得到的二进制补码。
这篇博客参考资料:
thinking in java