Javaのよくある質問(1) - 表現パズル
奇数の分析1
static boolean isOdd(int i) {
//错误解法,如果是负数则不是1
//return i % 2 == 1;
return i % 2 != 0;
}
浮動小数点の2正確な表現
//1 使用大整数
//2 使用BigDecimal,并使用基于String的构造函数
static void money() {
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.10")));
}
3長除法
static void longDivision() {
//乘数必须有个long类型,否则结果是用int计算,再转成了long,可能溢出
long a = 24L * 60 * 60 * 1000 * 1000;
long b = 24L * 60 * 60 * 1000;
System.out.println(a);
System.out.println(b);
System.out.println(a / b);
}
4 LおよびL
//初级问题,注意l与1的区别,long字面值应该只使用L
static void elementary() {
System.out.println(12345 + 5432l);
}
5ヘクス(わずかに)
6つの複数のコンバージョンタイプ
static void multicast() {
System.out.println(Integer.SIZE);
System.out.println(Character.SIZE);
System.out.println(Byte.SIZE);
System.out.println("-----");
System.out.println((byte)-1); //0xff
System.out.println(0xff);
System.out.println((char) (byte) -1); //0xffff 有符号扩展
System.out.println(0xffff);
System.out.println((int) (char) (byte) -1); //0x0000ffff char类型执行无符号扩展
System.out.println(0x0000ffff);
}
7変数の交換
C言語では、XOR演算子の利用特性を持つ(x ^ y ^ x) == y
中間変数を使用せずに変数の交換を達成するための方法を、
x = x ^ y;
y = y ^ x;
x = y ^ x;
C言語、計算式はx^=expr
、exprの値は、最初のxの値を計算し、抽出したであろう。しかし、Javaは仕事をしないで、次のコードは、x、yの変数の交換を達成することはできません
static void cleverSwap() {
int x = 1894; //0x7c0
int y = 2001; //0x7d1
x ^= y ^= x ^= y;
System.out.println(x); //x=0
System.out.println(y); //y=1894
}
左から右へのJavaオペランドオペレータでの発現に、評価されたx^=expr
exprを抽出したxの値を計算する前に、評価されたとき。上記のコードではx ^= y ^= x ^= y;
、値の2倍抽出をX、両方の時間が割り当て前に起こります。上記のコードは、と等価です
int tmp1 = x; //tmp1表示x的初始值
int tmp2 = y; //tmp2表示y的初始值
int tmp3 = x ^ y; //计算x ^ y,记为tmp1^tmp2
x = tmp3; //最右边赋值,x = tmp1^tmp2
y = tmp2 ^ tmp3; //中间赋值,y = tmp2 ^ tmp1 ^ tmp2,即 y = tmp1
x = tmp1 ^ y; //最左边赋值,x = tmp1 ^ tmp1,即 x = 0;
推奨アプローチはしている単一の式で二度同じ変数を割り当てません
8条件式
条件の式の結果の種類を決定します。
- 同じタイプの第二及び第三のオペランドの場合、それは表現型です。
- オペランドの型がTである場合、Tは、バイト、ショート、またはチャーを表し、そして他のオペランドがタイプintの定数式であり、その値はタイプTで表すことができ、次いで、条件式の型がTであります。
- それ以外の場合は、バイナリ・デジタル・アップグレードを使用して型をオペランドますが、式の型は、第2及び第3のオペランドがタイプ上げた後。
static void dosEquis() {
char x = 'X';
int i = 0;
System.out.println(true ? x : 0); //输出X,运用规则2
System.out.println(false ? i : x); //输出88,运用规则3,x被提升为int,即88
}
お勧め、同じタイプを使用して、第二及び第三のオペランドの条件式
化合物割り当て9(1)
x+=i
常に等価ではありませんx = x+i
:
彼らは彼らの左遷移型の変数を行う複合代入式を自動的に計算結果
short x = 0;
int a = 123456;
x += a; //包含了隐式类型转换,但编译器不会提示
System.out.println(x); //int 123456被隐式转换为了short -7646
x = x + a; //如果不使用复合赋值,编译器会提示incompatible types
勧告:化合物代入式を使用する場合は、暗黙の型変換に注意を払うが発生する可能性があります
化合物の割り当て10(2)(Java8 NA)
x+=i
等価ではありません常にへx = x+i
:
複合代入演算子の周りに必要とオペランドの基本的な型や梱包タイプに対応します。しかし、のために+=
左のオペランドが文字列である場合と、右側には、任意のタイプ+=
の文字列スプライシング操作を実行します。
そして、単純な代入演算子は、左のオペランドは任意のタイプであってもよいです。
Object x = "Buy ";
String y = "Effective Java";
x += y; //非法的
System.out.println(x);
x = x + y; //合法的
注:これらは、「Javaの疑問、」書籍、本の中で使用されるJavaのバージョンはJava5がJava8 Iにある問題を、解決するために使用されているはずであり、内容は、上記のx+=y
法的です