Go to Contents Go to Java Page

JavaOne 2002 in SF Report

 
 

6/12 第 3日

 
 

今日は General Session がなくて、朝から Technical Session です。

個人的には今日は Tiger Day なのです。Generics, Metadata, Simple Formated I/O などのセッションに参加してきました。1 日 "虎の穴" 体験ツアーみたいなもんです。虎の穴といっても、若い人には分からないとは思いますけど... そして、Tiger Day であると同時に、Joshua Bloch Day でもあるわけですが... ^^;;

それでは、本日のレポートです。

 

 
 

Technical Session

 
 

今日、聴講したのは次の 4 セッションです。

  • TS-1400 PDA Optional Package for the Java 2 Platform, Micro Ediion (J2ME) (JSR-75): API Overview
  • TS-3116 Java 2 Platform, Micro Edition (J2ME) Architecture Technical Overview
  • TS-3063 Adding Generics to the Java Programming Language
  • TS-3072 Forthcoming Java Programming Language Featurers

今日ははずれがなくて、全部紹介したいぐらいなのですが、なにぶんにも時間がないので。とりあえず、できるところまで書いてみます。

TS-3063 Adding Generics to the Java Programming Language

Genrics は C++ のテンプレートのようなものです。あくまでも、"ようなもの" であって、テンプレートではありません。

このセッションでは簡単に Generics の使い方などを説明して、その後、既存のものとどのようにマイグレートしていくかを説明しました。

マイグレートの方は省略します。なにぶんにも時間が足りないので。本当は大事だということは分かっているのですが。

Genrics の特徴として

  • 型の抽象化
  • Class/Interface/Method のパラメータ化

そして、Genrics は

  • NOT テンプレート
  • C++ と違い、Generics は型のチェックを行う
  • Generics は 1 度だけコンパイルされる (JVM の変更もしくはバイトコードの仕様を変更する必要はない)
  • 必要とすることを最小限にしている

Generics の使用法はそれほど難しくありません。

    List<Integer> xs = new LinkedList<Integer>();
 
    xs.add(new Integer(0));
    Integer x = xs.get(0);
    Integer y = xs.iterator().next();

見ればお分かりだ思いますが、キャストがありません。キャストが失敗したのが分かるのは、コンパイル時ではなく、ランタイム時です。Genrics を使用すればキャストがなく、コンパイル時に型チェックをするので安全です。

Generics を使ったクラスの定義の例です。

    class LinkedList<E> implements List<E>
        proteced class Node {
            E elt;
            Node next;
 
            Node(E e) { elt = e; next = null; }
 
        protected Node h;
        protected Node t;

        public LinkedList() {
            h = new Node(null);
        }

        public add(E e) {
            t.next = new Node(e);
            t = t.next;
        }

                  .
                  .
                  .

こんな書き方もできます。派生クラスが書けるということもそうなのですが、Collection クラスの containsAll メソッドのように、そのメソッドだけ Generics を使うこともできまさす。そのときは、public などの後に <T> のように記述します。

    class Collections {
        public static <S, T extends S> void copy(List<S> dest,
                                                 List<T> src) {
            ...
        }
    }
 
    class Collection<E> {
        public <T> boolean containsAll(Collection<T> c) {
            ...
        }
 
        public <T extends E> boolean addAll(Collection<T> c) {
            ...
        }
    }

ワイルドカードも使用することができます。でも、* ではありません。? です。

    class Collections {
        public static <S> void copy(List<S> dest,
                                       List<? extends S> src) {
            ...
        }
    }
 
    class Collection<E> {
        public boolean containsAll(Collection<?> c) {
            ...
        }
 
        public boolean addAll(Collection<? extends E> c) {
            ...
        }
    }

スーパクラスを指定して派生クラスをワイルドカードというのもなんとなく分かりますが、<T extends ?> のような書き方も可能です。

なんとなくでも分かりました??

 

TS-3072 Forthcoming Java Programming Language Featurers

Tiger における言語仕様の変更に関する部分を説明するセッションです。スピーカは Joshua Bloch です。

言語の仕様変化は次のような原則に則って行われたそうです。

  • 表現力を拡大する
  • 安全性も向上させる
  • 非コンパチビリティは最小限にする
    • VM の変更はなし
    • バイナリはすべて、ソースもほとんどのものがそのまま動作するようにする
    • 新しいキーワードは最小限にする

変更は 7 個所あるのですが、Generics と Metadata は他のセッションがあったので、省略します。

1. Enhance for Loop (like foreach)

コレクションを使うとき、いちいちイテレーションするのは面倒くさいですね。そこで、こんな風にかわりました。

    List list = new ArrayList();
    list.add("a");
        ...
 
    for (Object o : list) {
        System.out.println(o);
    }

list の要素は o に代入されて、要素があるだけループします。

ただ、実際に要素を使うときにはキャストをしなくてはいけないのですが、Generics を使えばもっと簡単になります。

配列もコレクションと同じように使用することができます。

2. Autoboxing/Unboxing

これも便利です。プリミティブとプリミティブのラッパークラス間の代入を = を使って行うことができるようになりました。

    int x = 5;
    Integer xx = x;
  
    int y = xx;

コレクションもこれを使えば、いちいちラッパーを使用せずに使えます。

    List<Integer> list = new ArrayList<Integer>();
    list.add(0);
        ...
 
    for (int x : list) {
        System.out.println(x);
    }

すごいすっきりしたと思いませんか?

3. Typesafe Enum

Bloch が書いた Effective Java の中に Typesafe Enum のことが書いてありますが、それは自分で Enum のためのクラスを書かなくてはなりませんでした。Tiger では、それをすぐに使うことができます。

ちなみに、通常の定数で Enum もどきを実現した場合の欠点は

  • Not Typesafe
  • No Namespace
  • 出力したときに意味がわからない

次のように使うことができます。

    enum Suit {clubs, diamonds, hearts, spades}
    enum Rank {duece, three, four, five, six, seven,
                eight, nine, jack, queen, king, ace}
 
    List<Card> deck = new ArrayList<Card>();
 
    for (Suit suit : Suit.VALUE) {
        for (Rank rank : Rank.VALUE) {
        deck.add(new Card(suit, rank);
    }
 
    Collections.shuffle(deck);

enum の VALUE が要素全体を表わすコレクションのようです。

フィールドやメソッドを持つ enum も作成できます。

    public enum Coin {
        penny(1), nickel(5), dime(10), quarter(25);
 
        Coin(int value) { this.value = value; }

        private final int value;
 
        public int value() { return value; }
    }

switch にも使用できます。また、enum の名前が名前空間になるので、同じもの (下の例では nikel が同じ) でも区別することができます。

public class CoinTest {
    public static void main(String[] args) {
        for (Coin c : Coin.VALUES) {
            System.out.println(c + ":  \t"
                               + c.value() + "¢ \t"
                               + color(c));
        }
    }

    private enum CoinColor {copper, nickel, silver}
    private static CoinColor color(Coin c) {
        switch (c) {
          case penny:
            return CoinColor.copper;
          case nickel:
            return CoinColor.nickel;
          case dime:
          case quarter:
            return CoinColor.silver;
          default:
            throw new AssertionError("Unknown coin" + c);
        }
    }
}

4. 可変長引数

今まで、Java で C のようなメソッドの可変長引数を実現するには配列を用いていましたが、これも面倒です。可変長変数を実現するために新たに ... (ピリオドが 3 つ) が導入されています。

使い方は C の場合と代わらないです。

    public void foo(int x, Object... obj);

第 1 引数には可変長のものは使用できません。

これはフォーマット付き出力を行うために導入されたようです。

5. 定数インポート

定数を使うときにはクラス名を書く必要があります。それを回避するためにインタフェースで定数を定義して、implements する方法もあります。しかし、これは本来のインタフェースの使い方ではありません。

そこで、Tiger では import 文で定数をインポートできるようになりました。

import java.awt.Math.*;
 
public void foo() {
    System.out.println(PI);  // Math.PI ではない
}

このように import 文で、クラスの定数を書くようにします。ワイルドカードはすべての定数をインポートするために使用されます。上記の例では Math クラスの定数すべてをインポートしています。

ああ、長かった。

 

 
 

Birds of a Feather (BOF) Session

 
 

今日は 4 つのセッションに参加しました。

  • BOF-2184 New I/O: Scanning and Formatting
  • BOF-3448 Project JXTA Metering Project
  • BOF-3094 A Metadata Facility for the Java Programming Language
  • BOF-3113 How Tiger Language Changes Affect Your Favorite APIs

BOF-3094 A Metadata Facility for the Java Programming Language

スピーカは再び Joshua Bloch です。

すいません、ぜんぜんわかりません。聞けば聞くほど分からなくなります。

なぜ、メタデータが必要なのかについては次のようなことを示していました。

  • Many APIs require a fair amount of boilerplate.
    • Example: JAX-RPC web service requires paired interface and implementations.
  • Wouldn't it be nice if language let you annotate code so that tool could generate boilerplate?
  • Many APIs require "side files" to be maintained.
    • Example: beans has BeanInfo class
  • Wouldn't it be nice if language let you annotate code so that tools could generate side files?

ようするに "現状では定義と実装が分かれているけど、それは面倒くさいね" ということや、"BeanInfo クラスみたいに付随するクラスがあるとメンテナンスが面倒だね" ということなのでしょう。

また、メタデータを使用することの利点は

  • Beyond eliminating boilerplate and side files...
  • Encourages a DECLARATIVE programming style
    • Tell computer what to do, not how to do it.
  • Should vastly simplify app development
    • Web services, enterprise app development
  • Many other uses, limited only by imagination
    • Parser generators, DBC, ???

セッションでは詳細な書き方よりは、例をいっぱい出してくれました。とりあえず、その例を書いておきます。

まずは JAX-RPC のサーバの例です。

Old
    import java.rmi.*;
  
    public interface PingIF extends Remote {
        public void foo() throws RemoteException;
    }
 
    public class Ping implements PingIF {
        public void foo() { }
    }
New 1
    import javax.xml.rpc.*;
 
    public class Ping {
        public @WebMethod void foo() { }
    }
New 2
    import javax.xml.rpc.*;
 
    public @WebService(namespace="http://acme.com/ping")
    class Ping {
        public @WebMethod void foo() { }
    }
New 3
    import javax.xml.rpc.*;
 
    public @WebService(namespace="http://acme.com/ping")
    class Ping {
        public @WebMethod @SoapOperation(style=RPC
            use=ENCODED, encodingStyle=SOAP_1_1)
            void foo() { }
    }

インタフェースとコンクリートクラスが一緒になったのはわかるのですが、WebMethod というのはなんなんでしょう? 基調講演とか J2SE Road Map セッションではここが @Remote だったのでなんとなく分かったのですが。

最後の New 3 にいたっては SoapOperation などというものまででてくるし...

次は EJB の生成の例です。

Old
    Context initial = new InitialContext();
    Object objref = initial.lookup("java:comp/env/ejb/SimpleFoo");
    FooHome home = (FooHome)ProtableRemoteObject.narrow(
                                       objref, FooHome.class);
    Foo myFoo = home.create();
New
    private @javax.ejb.create Foo myFoo;

その次は EJB で Environment を検索する例です。

Old (from J2EE Tutorial)
    Context inital = new InitialContext();
    Context environment = (Context)initial.lookup(
        "java:comp/env");
    Double discountLevel = (Double)environment.lookup(
        "Discount Level");
New 1
    public @env double discountLevel = 500.0;
New 2 (Longer Version)
    public @env("Supplier discount level")
                double discountLevel = 500.0;

メタデータは次のような要素から構成されています。

  • Syntax for declaring attributes
  • Syntax for annoutating fields, methods, classes, etc.
  • Two APIs for reading annotations
  • Class file representation for annotations

アトリビュートの定義の例を下にあげておきます。

    /**
     * Describes Request-For-Enhancement (RFE) that
     * led to presence of annotated API element.
     */
    public @interface RequestForEnhancement {
        int id();          // Unique ID for RFE
        String synopsis(); // Brief descriptions
        String engineer(); // Name of implementor
        String date();     // Date implemented
    }

次は Annotation の例です。

    @RequestForEnhancement {
        id       = 2868724;
        synopsis = "Enable time-travel";
        engineer = "Poindexter";
        date     = "4/1/2002";
    }

    public static void travelThroughTime(Date destination) {
        ...
    }

特殊な例としてマーカーインタフェースがあります。メソッドを持たないインタフェースで、既存のライブラリでは Clonable や Serializable などがあります。

    /**
     * Annotation with this attribute indicates that the
     * specification of the annotated API element is
     * preliminary and subject to change.
     */
    pulic @interface Preliminary{ }

    @Preliminary public class TimeTravel {
        ...
    }

アトリビュートが 1 つの場合は、指定しなくても引数 (?) がそれになります。

    /**
     * Associates a copyright notice with the annotated
     * API element
     */
    public @interface Copyright {
        String value(); // By convention
    }
 
    @Copyright("2002 Yoyodyne Propulsion Systems")
    public class OscillationOverthruster {
        ...
    }

Annotation を読み込むためにリフレクションが機能強化され、次のようなクラスも導入されました。

    public interface AnnotateElement {
        <T> boolean isAnnotationPresent(Class<T> attrType);
        <T> T getAnnoation(Class<T> attrType);
        Attribute[] getAnnotations();
        Attribute[] getDeclaredAnnotations();
    }

Annotation の読み方の例です。JavaDoc の API (Doclet) に似たような使い方をします。

    AnnotatedElement c = Foo.class;
    Copyright cr = c.getAnnotations(Copyright.class);

分かりました? 私は、これを書いていて、何となく分かってきました。でも、詳細は分からないので、帰国したら JSR-175 を見てみることにします。

 

BOF-3113 How Tiger Language Changes Affect Your Favorite APIs

Tiger では言語仕様が変化するため、既存のライブラリもずいぶん様変わりするようです。どんなクラスがどのように変化したかを解説するセッションです。スピーカは引き続き Joshua Bloch です。

一番、影響の大きいのは Generics のようです。

変更があった代表的なものは

  • Language Support
  • Reflection
  • Collections
  • Text Format
  • Use of Covariant Returns

Language Support

言語仕様に関わるようなクラスです。

  • Iteratable
  • Comparable
  • ThreadLocal
  • Reference

Iteratable は多分新しいインタフェースです。Generics を使ったイテレータを取得するメソッド iterator を定義するインタフェースです。

Reflection

リフレクションは可変長引数が使えることによる変更が多いです。例えば Method#invoke などで可変長引数が使えるようになります。

  • Class
  • Constructor
  • Method

Collections

もっとも Generics の影響が大きいのがコレクションでしょう。

  • Collection
  • Collections

Text Format

フォーマット関連のクラスは可変長引数による変更です。

  • MessageFormat

Uses o Covariant Methods

メソッドの引数が自分自身になるようなメソッドなのでしょう。詳細は分かりませんが、多分 Generics による変更があるのだと思います。

  • nio Buffer methods
  • clone()

全体を通してみると、やはり Generics ですね。今から、勉強しておかねば。

 

 
 

おまけ

 
 
Session Full

今日は満席のセッションがずいぶん多かったような気がします。私が聴講したものでも、J2ME と Generics、Forthcoming Features が満席でした。その他にも、パフォーマンスのセッションや、GC のセッションが満席のようでした。

満席になると写真のような立て看板が立てられます。何回も JavaOne にきてますが、こんなのを見るのははじめて。

また、今日は JavaOne に取材にこられている JavaPress の編集の方とお会いして、いろいろとお話をすることができました。JavaOne に来る前から、編集の方が行かれることは知っていたのですが、すれ違いが多くてなかなか会えなかったのでが、今日ようやく会うことができました。

そんなこんなで、はじめて Media Facilities に入ってしまいました。なんと、私たちが話をしていたすぐ後ろでは John Gage がインタビューを受けてました。なんか、すぐそばにいるだけで緊張しますよ、本当に ^^;;

 

(2003.6.12)

 
 
Go to Contents Go to Java Page