J2SE 5.0(Tiger)の新機能 言語編 Ariel Networks 開発部 中山 淳.

Slides:



Advertisements
Similar presentations
独習JAVA Chapter 6 6.6 クラスの修飾子 6.7 変数の修飾子 結城 隆. 6.6 クラスの修飾 abstract インスタンス化できないクラス。1つまたは複数のサブクラスで 実装してはじめてインスタンス化できる。 final 継承されたくないことを明示する。これ以上機能拡張 / 変更でき.
Advertisements

6.4継承とメソッド 6.5継承とコンストラクタ 11月28日 時田 陽一
2006年11月22日 植田龍男 Webサービス II (第9回) 年11月22日 植田龍男.
東京工科大学 コンピュータサイエンス学部 亀田弘之
~手続き指向からオブジェクト指向へ(Ⅰ)~
プログラミング基礎I(再) 山元進.
WebサービスII (第10回) 2007年11月28日 植田龍男.
Javaのための暗黙的に型定義される構造体
アルゴリズムとデータ構造1 2007年6月12日
アルゴリズムとプログラミング (Algorithms and Programming)
Myoungkyu Song and Eli Tilevich 発表者: 石尾 隆(大阪大学)
Javaのインタフェース についての補足 2006年5月17日 海谷 治彦.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
アルゴリズムとデータ構造 2011年6月13日
構造体.
社会人学習講座 「Javaプログラミング概論」
第20章 Flyweight ~同じものを共有して無駄をなくす~
インタフェース プログラミング 第14回 インタフェース プログラミング第14回.
アルゴリズムとデータ構造 2011年6月20日
コンパイラの解析 (2) GCJのデータ構造 - 1.
~手続き指向からオブジェクト指向へ[Ⅱ]~
第12回 2007年7月13日 応用Java (Java/XML).
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
11.6 ランダムアクセスファイル 11.7 StreamTokenizerクラス
プログラミング言語入門 手続き型言語としてのJava
アルゴリズムとデータ構造 2012年6月28日
アルゴリズムとデータ構造 2011年6月27日
アルゴリズムとプログラミング (Algorithms and Programming)
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
オブジェクト指向 プログラミング 第八回 知能情報学部 新田直也.
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
第7回独習Javaゼミ セクション 1~4 発表者 直江 宗紀.
第11回 2007年7月6日 応用Java (Java/XML).
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
暗黙的に型付けされる構造体の Java言語への導入
第3回 2007年4月27日 応用Java (Java/XML).
WebサービスII (第7回) 2007年11月7日 植田龍男.
理学部 情報科学科 指導教官 千葉 滋 助教授 学籍番号 03_03686 内河 綾
Windows PowerShell Cmdlet
関数の定義.
アルゴリズムとプログラミング (Algorithms and Programming)
オブジェクト指向 プログラミング 第七回 知能情報学部 新田直也.
10-1 SAXの概要 10-2 Saxプログラミングの基礎 10-3 saxのプログラム例
7.4 intanceof 演算子 7.5~7.9パッケージ 2003/11/28 紺野憲一
Java8について 2014/03/07.
一時的な型 長谷川啓
パッケージ,アクセス修飾子 2008年4月27日 海谷 治彦.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
アルゴリズムとプログラミング (Algorithms and Programming)
参照されないリテラル 長谷川啓
プログラミング 3 2 次元配列.
プログラミング言語論 第十三回 理工学部 情報システム工学科 新田直也.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
C#プログラミング実習 第3回.
アルゴリズムとデータ構造 2012年6月11日
JAVA入門③ 配列とコレクション.
コレクション・フレームワーク J2EE I (データベース論) 第6回 /
Annotation EJB 3.0 コース 第3回 2006年8月4日.
サブゼミ第7回 実装編① オブジェクト型とキャスト.
アルゴリズムとデータ構造 2013年7月1日
JAVA入門⑥ クラスとインスタンス.
アルゴリズムとデータ構造 2012年6月21日
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
プログラミング演習I 2003年6月11日(第9回) 木村巌.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第10回 2002年12月19日(木) メソッドの再定義と動的結合 クイズ メソッドの再定義 (オーバーライド)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
Presentation transcript:

J2SE 5.0(Tiger)の新機能 言語編 Ariel Networks 開発部 中山 淳

J2SE 5.0(Tiger)の新機能 より単純に、より安全に Generics 拡張for文 Autoboxing Static import 可変長引数 Enumerations Annotation

Generics 型安全なプログラミング

所々でtype-castが必要になるため、 型に関して安全とは言えない 今までのJava List list = new ArrayList(); list.add(new Integer(0)); Integer i0 = (Integer)list.get(0); // type-castが必要 list.add(new Long(0)); Integer i1 = (Integer)list.get(1); // ClassCastExceptionが発生 所々でtype-castが必要になるため、 型に関して安全とは言えない

compilerが型を知っているのでtype-castが不要になる Tigerなら List<Integer> list = new ArrayList<Integer>(); // 新しい構文 list.add(new Integer(0)); Integer i = list.get(0); // type-castが不要 list.add(new Long(0)); // Integerしか入れられないので、compile error! compilerが型を知っているのでtype-castが不要になる

compilerに型を教える新構文 List<Integer> list = new ArrayList<Integer>(); Genericsをサポートしているclass/interfaceに対して 「型名<型パラメータ>」の形で使う ArrayList<Integer>は、Integer型の要素からなるArrayList型 (class) Map<String, Date>は、String型のkeyとDate型のvalueからなるMap型 (interface) Set<Map<String, Date>>は、String型のkeyとDate型のvalueからなるMapのSet

自分でGenericなclass/interfaceを書くこともできる 例えば、任意の型の変数の組を 保持するclass Pairを書いてみる

今までのJava class Pair { private Object first; private Object second; public Pair(Object first, Object second) { this.first = first; this.second = second; } public Object getFirst() {return first;} public Object getSecond() {return second;} public static void main() { Pair pair = new Pair("now", new Date()); String key = (String)pair.getFirst() Date value = (Date)pair.getSecond()

Tiger class Pair<F, S> { private F first; private S second; public Pair(F first, S second) { this.first = first; this.second = second; } public F getFirst() {return first;} public S getSecond() {return second;} public static void main() { Pair<String, Date> pair = new Pair<String, Date>("now", new Date()); String key = pair.getFirst() Date value = pair.getSecond()

Genericsで何が嬉しいか 実行時エラー(ClassCastException)が減る コードの見通しがよくなる IDE(Eclipse等)による自動補完の精度が上がる

Genericsの原理 型パラメータはコンパイル時にのみ使われ、byte codeには残らない Pair<String, Date> pair = new Pair<String, Date>("now", new Date()); String key = pair.getFirst() Date value = pair.getSecond() は、次のコードと等価になるよう、コンパイルされる。 Pair pair = new Pair("now", new Date()); String key = (String)pair.getFirst() Date value = (Date)pair.getSecond() コンパイル時のtype-checkによって、type-castの正しさが 保証されるところがミソ。

既存のコードとの相互運用性 原理から分かるように、型パラメータを取るclass/interfaceは void foo(List list) {/* etc. */} void bar(Pair pair) {/* etc. */} Genericsを使ったコード void baz() { List<Integer> list = new ArrayList<Integer>(); foo(list); // 正しいコード (warningは出る) Pair<String, Date> pair = new Pair<String, Date>("now", new Date()); bar(pair); // Pair<F, S>はPair classとしてコンパイルされるので、これも可 }

Genericsの制限 1. 型パラメータに組込型を指定できない List<int>と書くことはできない (List<Integer>は可) 2. 型パラメータで指定された型をnewできない (配列も含む) public S getSecond() {return new S();} や public S[] getSecond() {return new S[1];}は不可 3. byte codeになったときにmethodの型が同じになるようなmethodは記述できない void set(F first) と void set(Object o) を同じclass/interfaceに書くのは不可 4. 型パラメータをstatic memberに適用できない static List<F> commons = new List<F>(); といった記述はできない

オブジェクトを列挙するforループを同一の構文で書ける

今までのJava int[] intArray = new int[]{4004, 8008, 8080, 80, 6502, 6809}; for (int i = 0; i < intArray.length; i++) { int elem = intArray[i]; } List<Integer> intList = new ArrayList<Integer>(); // etc. for (Iterator i = intList.iterator(); i.hashNext(); ) { Integer elem = i.next();

Tiger int[] intArray = new int[]{4004, 8008, 8080, 80, 6502, 6809}; for (int elem : intArray) { } List<Integer> intList = new ArrayList<Integer>(); // etc. for (Integer elem : intList) {

拡張for文に渡せるコンテナ 配列 java.lang.Iterableをimplementsしたclassのオブジェクト (Java.util.Collection等)

拡張for文の実装 byte codeには、普通のfor文と同じようにコンパイルされる for (int elem : intArray) { } は、 for (int #i = 0; i < intArray.length; #i++) { int elem = intArray[#i]; とコンパイルされる Iterableなものに関しても、同じようにiteratorを変数として コンパイルされる

int等の基本型とInteger等の wrapper型の自動変換を行い、 記述を単純にする Autoboxing/unboxing int等の基本型とInteger等の wrapper型の自動変換を行い、 記述を単純にする

Autoboxing/unboxingを使わないと void handleInt(int i); void handleInteger(Integer i); List<Integer> list = new ArrayList<Integer>(); list.add(new Integer(1)); // Integer objectを生成 handleInteger(new Integer(1)); int i = list.get(0).intValue(); // Integer objectを取り出して、intValue() methodを呼び出す handleInt(list.get(0).intValue());

Autoboxing/unboxingを使うと void handleInt(int i); void handleInteger(Integer i); List<Integer> list = new ArrayList<Integer>(); list.add(1); // 自動的にInteger objectを生成 (boxing) handleInt(list.get(0)); // method呼び出しにも適用できる int i = list.get(0); // Integer objectを取り出して、自動的に // intValue() methodを呼び出す (unboxing) handleInteger(1); // method呼び出しにも適用できる

class/interfaceのstaticメンバを 直接importする

1.4までのJavaでは、import できるのはパッケージだけ class/interfaceのstaticメンバを参照するときは、TypeName.MemberNameの形式で記述する必要があった

import java.util.Arrays; Arrays.sort(fooArray);

Tiger import static java.util.Arrays.sort; sort(fooArray); // static importによってArraysを // 省略できる

定数interface idiomからの脱却 今までは、interfaceにstatic finalで定数を書き、それをimplementsすることで定数を手軽に使えるようにする手法がよく使われていた static importによって不要に

今までのJava package foo; public interface Barable { static final int BarConstant = 0; } public Bar implements foo.Barable { public static void main() { System.out.println(BarConstant);

Tiger package foo; public class BarUtil { public static final int BarConstant = 0; } import static foo.BarUtil.*; public Bar { public static void main() { System.out.println(BarConstant);

可変長引数 printf()が使えるようになった

使用例 System.out.printf("%d = %s", 256, "0x100"); 宣言 System.out.printf(String formt, Object ... args); 使用例 System.out.printf("%d = %s", 256, "0x100");

可変長引数を取るmethodの例 void foo(Object ... vargs) { for (Object o : vargs) { System.out.println(o.toString()); } static void main() { foo(1, "abc", new Date()); foo("abc", new Date(), "def", 89);

可変長引数の実装 void foo(Object ... vargs) は、byte code上は → 1. foo(new Object[]{1, “abc”, new Date()}) と foo(1, “abc”, new Date())は同じbyte codeになる 2. void foo(Object ... vargs) と void foo(Object[] vargs) のoverloadingはできない

配列を可変長引数methodの 一引数として渡すには? 引数の型(foo()の場合はObject)にtype-castする foo("this array ", (Object)(new Object[]{1, "abc", new Date()}), "is one of parameters");

C/C++でおなじみの列挙型 型安全な定数を手軽に使えるように なった (type safe enum idiomが不要に) Enumerations C/C++でおなじみの列挙型 型安全な定数を手軽に使えるように なった (type safe enum idiomが不要に)

今までのJava package foo; public class DayOfWeek { static final int SUNDAY = 0; static final int MONDAY = 1; /* 略 */ static final int SATURDAY = 6; } void foo(int dayOfWeek) { switch (dayOfWeek) { case DayOfWeek.SUNDAY: /* 略 */ break; case DayOfWeek.MONDAY: default: assert false; }

Tiger public enum DayOfWeek { SUNDAY = 0, MONDAY = 1, /* 略 */ SATURDAY = 6, } void bar(DayOfWeek dayOfWeek) { if (dayOfWeek == DayOfWeek.SUNDAY) { // 通常の記法 void foo(DayOfWeek dayOfWeek) { switch (dayOfWeek) { case SUNDAY:// switch文の特例 /* 略 */ break; case SUNDAY: default: assert false; }

enumの実装 定義 byte code public enum DayOfWeek { SUNDAY, MONDAY, /* 略 */ , SATURDAY, } byte code public final class DayOfWeek extends java.lang.Enum { public static final DayOfWeek SUNDAY = new DayOfWeek(); public static final DayOfWeek MONDAY = new DayOfWeek(); /* 略 */ public static final DayOfWeek SATURDAY = new DayOfWeek(); public static final DayOfWeek[] values(); public static final DayOfWeek valueOf(String name); static {

enum定数のinstanceは一つであることが保証されている (==演算子や!=演算子で比較できる) → そのためにいくつかの制限が発生 enum型にfinalやabstractといった宣言を行えない enum型のinstanceをnewで生成できない Reflection APIを使ってenum型のinstanceを 生成できない

便利なmethod String name() enum定数の名前を文字列で得る static T Enum.valueOf(String name) 文字列で渡された名前をenum定数に変換する static T[] Enum.values() enum定数を列挙する

コードの動的な振る舞いに 影響しないmeta dataを付加する Annotation コードの動的な振る舞いに 影響しないmeta dataを付加する

標準のannotation @Override methodに対して付与し、そのmethodがsuper classのmethodをoverrideしていることを宣言する 現状の実装ではjavacが処理を行い、overrideされていないケースで警告を出す 例) @Override public void foo(String name) { /* 略 */} @Deprecated method/classに対して付与し、そのmethod/classが非推奨であることを宣言する 現状の実装ではjavacが処理を行い、deprecatedされたmethodが使用された箇所で警告を出す 例) @Deprecated public void bar(String name) { /* 略 */}

独自annotationの使用例 Spring Framework 2.0 代表的なDI(Dependence Injection) コンテナ 2.0ではannotationでbeanを定義できる JUnit 4 単体テストのフレームワーク テストメソッドの指定などにannotationを使用できる Aspect J 1.5.x JavaでAOP(Aspect Oriented Programming)を行うための言語 無設定Struts Annotationと命名規約によって、Strutsの定義ファイルを不要にする

J2SE1.4のJVMでTigerの機能を使うには 今までの説明から分かるとおり、Tigerのbyte codeは1.4とほぼ同じ しかし、Tigerのclassファイルは1.4では実行できない → WebSphere 6.0 (1.4ベース) で困る

Tigerのclassファイルを1.4で実行できる形式に変換するツールがある Retroweaver Retrotranslator ArielではRetrotranslatorを使って実際に運用しているが、今まで問題が出たことはない