この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
毎度お世話になっております。クラスメソッドの稲毛です。
今回は先日リリースされた「Java SE 7」について、新たに追加された言語拡張についてまとめておきたいと思います。
リファレンスはオラクル社の下記サイトとなります。
http://download.oracle.com/javase/7/docs/technotes/guides/language/enhancements.html#javase7
Javaプログラミング言語の拡張
- Binary Literals
- Underscores in Numeric Literals
- Strings in switch Statements
- Type Inference for Generic Instance Creation
- Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods
- The try-with-resources Statement
- Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
Binary Literals
バイナリのリテラル表現
バイナリ値の接頭辞に「0b」または「0B」を追加することで、整数型(byte, short, int, long)の値をリテラルで表現できるようになりました。
// An 8-bit 'byte' value:
byte aByte = (byte)0b00100001;
// A 16-bit 'short' value:
short aShort = (short)0b1010000101000101;
// Some 32-bit 'int' values:
int anInt1 = 0b10100001010001011010000101000101;
int anInt2 = 0b101;
int anInt3 = 0B101; // The B can be upper or lower case.
// A 64-bit 'long' value. Note the "L" suffix:
long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;
http://download.oracle.com/javase/7/docs/technotes/guides/language/binary-literals.html
Underscores in Numeric Literals
アンダースコアを含んだ数値リテラル
数値リテラルにアンダースコア「_」を含める事ができるようになりました。数値リテラルの可読性向上等に利用することができます。
long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;
ただし、アンダースコアを挿入する位置に注意する必要があります。
float pi1 = 3_.1415F; // Invalid; cannot put underscores adjacent to a decimal point
float pi2 = 3._1415F; // Invalid; cannot put underscores adjacent to a decimal point
long socialSecurityNumber1
= 999_99_9999_L; // Invalid; cannot put underscores prior to an L suffix
int x1 = _52; // This is an identifier, not a numeric literal
int x2 = 5_2; // OK (decimal literal)
int x3 = 52_; // Invalid; cannot put underscores at the end of a literal
int x4 = 5_______2; // OK (decimal literal)
int x5 = 0_x52; // Invalid; cannot put underscores in the 0x radix prefix
int x6 = 0x_52; // Invalid; cannot put underscores at the beginning of a number
int x7 = 0x5_2; // OK (hexadecimal literal)
int x8 = 0x52_; // Invalid; cannot put underscores at the end of a number
int x9 = 0_52; // OK (octal literal)
int x10 = 05_2; // OK (octal literal)
int x11 = 052_; // Invalid; cannot put underscores at the end of a number
http://download.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html
Strings in switch Statements
switch文で文字列を
switch文の条件式でStringオブジェクトが使用できるようになりました。Javaコンパイラは一般的に、「if-then-else文よりもStringオブジェクトを用いるswitch文のほうが効率的なバイトコードを生成する。」とされています。
public String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {
String typeOfDay;
switch (dayOfWeekArg) {
case "Monday":
typeOfDay = "Start of work week";
break;
case "Tuesday":
case "Wednesday":
case "Thursday":
typeOfDay = "Midweek";
break;
case "Friday":
typeOfDay = "End of work week";
break;
case "Saturday":
case "Sunday":
typeOfDay = "Weekend";
break;
default:
throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);
}
return typeOfDay;
}
http://download.oracle.com/javase/7/docs/technotes/guides/language/strings-switch.html
Type Inference for Generic Instance Creation
ジェネリックインスタンス生成時の型推論
従来、このように記述していたものを
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
このように記述することができるようになりました。
Map<String, List<String>> myMap = new HashMap<>();
「<>」を付与しないと警告が出力されますのでご注意ください。
Map<String, List<String>> myMap = new HashMap(); // unchecked conversion warning
http://download.oracle.com/javase/7/docs/technotes/guides/language/type-inference-generic-instance-creation.html
Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods
型パラメータを可変長引数で使用時のコンパイラ警告およびエラーの改善
ジェネリクスにより型の安全性が保証されているのにも関わらず、保証されていない型のオブジェクトが扱われてしまうようなケースが「ヒープ汚染」と呼ばれます。
List l = new ArrayList<Number>();
List<String> ls = l; // unchecked warning
l.add(0, new Integer(42)); // another unchecked warning
String s = ls.get(0); // ClassCastException is thrown
Java SE 7ではコンパイル時にヒープ汚染が起こる可能性がある場合、警告を出力するようになりました。
warning: [varargs] Possible heap pollution from parameterized vararg type T
この警告を出力しないようにするには、以下の方法があります。
- staticおよび非コンストラクタメソッドの宣言に次のアノテーションを追加します。
- @SafeVarargs
- メソッドの宣言に次のアノテーションを追加します。
- @SuppressWarnings({"unchecked", "varargs"})
- メソッド呼び出し側で生成される警告は抑制できません。
- コンパイラオプションに -Xlint:varargs を指定します。
http://download.oracle.com/javase/7/docs/technotes/guides/language/non-reifiable-varargs.html
The try-with-resources Statement
リソースを含めたtry文
プログラムが終了した際にクローズされていなければならないリソースをtry文に含めることができるようになりました。これらのリソースはステートメント終了時にクローズされることが保証されます。
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
http://download.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html
Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
複数例外型キャッチと型チェックの改善による例外の再スロー
複数例外型をキャッチすることが可能となりました。このようなケースが
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (SQLException ex) {
logger.log(ex);
throw ex;
}
このように記述できます。
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
キャッチした例外を再度スローする際、メソッド宣言のthrow節に、より特定の例外型を指定することができるようになりました。従来は、メソッド宣言のthrow節に「FirstException」と「SecondException」を指定することができませんでしたが(双方の親クラスである「Exception」を指定していた。)
static class FirstException extends Exception { }
static class SecondException extends Exception { }
public void rethrowException(String exceptionName) throws Exception {
try {
if (exceptionName.equals("First")) {
throw new FirstException();
} else {
throw new SecondException();
}
} catch (Exception e) {
throw e;
}
}
throw節に「FirstException」および「SecondeException」を指定することができます。
public void rethrowException(String exceptionName)
throws FirstException, SecondException {
try {
// ...
}
catch (Exception e) {
throw e;
}
}
http://download.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
まとめ
Java SE 7では、言語拡張以外にも様々な改良が施されています。
http://download.oracle.com/javase/7/docs/
OracleによるSunの買収や、「Javaの父」ことジェームズ・ゴスリン氏のGoogle移籍など、Javaプラットフォームを取り巻く環境は大きく変化しましたが、「Scala」や「Groovy」などのJVM言語や心機一転したJavaFX 2.0など面白そうな話題もまだまだあるので、今後もチェックを続けていこうと思います。