Personal tools
You are here: Home ブログ アリエル開発者のブログ JavaでのVariant型?型不定な値の扱い
Document Actions

JavaでのVariant型?型不定な値の扱い

アリエルでのディスカッションからの抜粋です。

最初の質問は、

ユーザには多くの属性値があります。
AquaType(aka AirForm, Air-otype)同様、拡張属性を持ちます。
この拡張属性の扱いをJavaでどうすべきでしょうか?

要は、
Map<String, Foo> attributes;
で属性名からFoo型の属性値を取れるようにしたいのですが、
Foo型をどうするかです。

Object型にして(アプリ側が)キャストするしかないのでしょうか。
Javaなら、何か素晴しい方法がありますか?

というものです。この質問に対して、C++オタクからの反応は、

C++だとboost::variantというのがあります。

> boost:variant v;

> v.set(1);

> std::cout << v.get<int>() << std::endl;

みたいに使います。setInt()とかsetString()とかいちいち用意する代わりに、
parameterized typeで解決する手法ですが、
Java1.5のGenericで同じことができるかどうかは知りません。

class templateしかサポートしてなくて、function templateは使えなかった
気がするので駄目?それでも、helper class templateを使えばいけるかなぁと
思ったけど、newしないとobjectを作れない不便言語なので、こっちの線も辛いと
ころ。やるとしたら、気持ち悪いけどこんな感じかなぁ。

> Variant v;

> new Setter<int>(v).set(1);

> System.out.println(new Getter<int>(v).get());


C++だとnewが要らないので、いくらかマシな見た目(とパフォーマンス)になります。

[追記]
function templateが使えるっぽい。でも、genericの実装方法から考えると、

> public class Variant {

>   public <T> T get() {return (T)value;}

>   public <T> Variant set(T value) {this.value = value;}

>   private Object value;

> }

みたいなのはコンパイルが通らない気がする。

というものです。C++オタクはさらに調べて、

reflection(Class.cast() method)を使って、

> Variant v;

> v.set(new Interger(1));

> Integer i = v.get("java.lang.Integer");


てのはどうだ。

となっています。ここで、別の人の回答として、

素晴らしい方法は知りません。そもそもJavaには存在しないのか、
それとも私が不勉強なだけなのかもわかりませんせんが。

キャストするか、サポートしている型を答える、その型で値を返す、
などのメソッドを用意した拡張属性の独自のInterfaceとかを作って使うか、
それくらいしか思いつきません。

とここで、ひと段落したかにみめましたが、C++オタクは

> public class Variant {

>   private Object value = null;

>   public Variant(Object value) {

>     this.value = value;

>   }

>   public get(String typeName)

>     throws ClassCastException, ClassNotFoundException {

>     return Class.forName(typeName).cast(this.value);

>   }

>   public set(Object value) {

>     this.value = value;

>   }

>   public set(int value) {

>     this.value = new Integer(value);

>   }

>   // declare for other primitive types.

> }
 
無意味?

とコードを交えて切り返してきます。ここで、大人の回答が出てきます。

> 無意味? 

無意味かどうかは、困ったなあ、と思われたご本人がどう評価されるかだと
思うのですが、そもそも、何に「困った」かですよね。 

1. 属性値を利用する側で毎回キャストするのが面倒(あるいは無駄) 
2. 型での制約が実質的に無効となってよろしくない 

という辺りなのかと想像するのですが、もっと深い意味があるのかもしれません
(意趣返し)。

2の方の意味が強い場合は、難しいのではないでしょうか

となってきます。この困ったにもともとの質問者ではなくC++オタクが次のように答えています。

例えば、

> static String fooType = "java.lang.Integer";
    
> void bar(Variant v) {

>   Integer foo = v.get(fooType);

> }


とかやって使う。本質的にはtypedefの代わり。

となっています。JavaのVariantの議論に対して、今後の展開はどうなるのでしょう。

Category(s)
開発
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/dev/java306evariant578b-578b4e0d5b9a306a5024306e62713044/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.