- PR -

クラスの変数名の取得

1
投稿者投稿内容
VIM
ベテラン
会議室デビュー日: 2003/11/14
投稿数: 76
投稿日時: 2003-12-02 11:26
Javaをはじめて数週間ですが、
凝ったことをやろうとしてまして、よろしければ教えてください。

クラスの変数名(インスタンス名)を取得したいのですが、
そういったことは可能なのでしょうか?

たとえば、getInstanceName()というメソッドだとすると次のようなイメージです。

■ソース
xClass x = new xClass();
System.out.println( "変数名は[" + x.getInstanceName() + "]です" );
xClass a = new xClass();
System.out.println( "変数名は[" + a.getInstanceName() + "]です" );

■出力
変数名は[x]です
変数名は[a]です

こんなことをやろうとしています。可能でしょうか?
不可能ならばそれでかまいませんが、
できるのなら、ヒント等を教えていただきたく思います。
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-12-02 11:31
不可能ですよ。
変数につけられた変数名は開発者やコンパイラが認識するために存在するに過ぎないので、
実際に実行時にこの名前である必要は全く無いわけです。別にこの名前が文字列として
プログラム中に格納されているわけではありません。

例えば、以下のコードでString型の変数名が違うことになんら意味はありません。

コード:

String hoge = "ほげほげ";
System.out.println(hoge);



コード:

String fuga = "ほげほげ";
System.out.println(fuga);




[ メッセージ編集済み 編集者: おばけ 編集日時 2003-12-02 11:36 ]
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2003-12-02 11:34
クラスの構造を調べたり、実行時になって初めて呼び出したいメソッド名がわかるような場合はリフレクション API 呼ばれるものを利用します。
→java.lang.reflect.*
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/package-frame.html

インスタンス名、ではなくて恐らく”フィールド名”のことだと思いますので、

xClass x = new xClass();
Field[] fields = x.getClass().getFields[];

または、

Field[] fields = xClass.class.getFields[];

で、フィールドに関する情報がとれます。Field クラスからどんなことが出来るかは API を見てください。
簡単なサンプルでは、こんなかんじでしょうか。

import java.lang.reflect.*;
public class ReflectSample{
public String theFieldName = "hoge";
public static void main(String arg[]){
Field f = Ref.class.getFields()[0];
System.out.println(f.getName());
}
}


$ java ReflectSample
theFieldName


[ メッセージ編集済み 編集者: インギ 編集日時 2003-12-02 11:45 ]
Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2003-12-02 13:14
引用:

VIMさんの書き込み (2003-12-02 11:26) より:
■ソース
xClass x = new xClass();
System.out.println( "変数名は[" + x.getInstanceName() + "]です" );
xClass a = new xClass();
System.out.println( "変数名は[" + a.getInstanceName() + "]です" );

■出力
変数名は[x]です
変数名は[a]です

こんなことをやろうとしています。可能でしょうか?


↓じゃだめですか?
■ソース
xClass x = new xClass();
System.out.println( "変数名は[x]です" );
xClass a = new xClass();
System.out.println( "変数名は[a]です" );

ソースコードのある位置での変数名は固定なので、問題ないように思いますが...。
Keisuke
大ベテラン
会議室デビュー日: 2003/10/24
投稿数: 105
投稿日時: 2003-12-02 13:34
やりたいことを勝手に想像すると・・・

JavaCC( https://javacc.dev.java.net/ )を使って
パーシングするのが良いのでは?
VIM
ベテラン
会議室デビュー日: 2003/11/14
投稿数: 76
投稿日時: 2003-12-02 13:56
ちょっと例が悪かったようでした。

デバッグクラスのようなイメージです。
またまた例が悪いですが、C言語の場合、
#defineで変数名とその値を吐き出すデバッグ関数(下の例だとdprint)を使用していたので、
それに似たような感じをイメージしていました。

■Cの例
#define dprint(expr) printf( #expr " = %d", expr );
x = 1;
dprint( x ); // 出力→ 「x=1」
(実際#defineはプリコンパイル部分だから、javaとはかけ離れていますが・・・。)

今回は、java言語ということで、
インスタンスの所持するメンバ変数と、そのインスタンスの名前を出力するというメソッドを考えていたのです。

class personal()
{
int height, weight;
public void dprint(){
System.out.println( "変数名" + this.getInstanceName() +
"\n\theight:" + height +
"\n\tweight:" ... );
return;
}
}

void hoge{
xClass x = new xClass( 165, 60 );
x.dprint();
xClass y = new xClass( 170, 65 );
y.dprint();
}

■hoge()の出力
変数名:x height:165 weight 60
変数名:y height:165 weight 60


■Keisukeさん
紹介にあったJavaCCをざっとみました。
C言語でいうプリコンパイルの部分に該当すると思うので、
まだ試していませんが、できるかもしれません。
ありがとうございます。

■Wataさん
例では、publicメソッドでgetInstanceNameを公開していますが、
実際はprivateを想定していました。
お手数をおかけしました。

■インギさん
フィールド名といえばそうなのですが・・・例がちょっと悪かったです。
この場合personalクラスから親のインスタンスを取得する必要が出てきます。
生成時にthisを渡せばいいという話もありますが、
親クラスには迷惑をかけない方針でいきたいのです。
Field クラスについては、別途ためになりました。
ありがとうございます。

■おばけさん
ということで、どうやら普通にやるには不可能なようですね。
クラス名が取得できるから、変数名と思ったのですが・・・。
単純にデバッグクラスみたいな感じをイメージしていたのですが、
どうも簡単にはいかないみたいです。
ありがとうございました。

[ メッセージ編集済み 編集者: VIM 編集日時 2003-12-02 13:58 ]

[ メッセージ編集済み 編集者: VIM 編集日時 2003-12-02 14:54 ]
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2003-12-02 14:05
引用:

VIMさんの書き込み (2003-12-02 13:56) より:

単純にデバッグクラスみたいな感じをイメージしていたのですが、
どうも簡単にはいかないみたいです。


簡単に実現するとしたら「Object#toStringをオーバーライドする」かな?

System.out.println("x=" + x.toString());
こんな感じに。
(一般的にはこの様にしますよね)

[ メッセージ編集済み 編集者: ぽん 編集日時 2003-12-02 14:17 ]
おばけ
ぬし
会議室デビュー日: 2002/11/14
投稿数: 609
お住まい・勤務地: 東京都江東区
投稿日時: 2003-12-02 14:55
引用:

またまた例が悪いですが、C言語の場合、
# defineで変数名とその値を吐き出すデバッグ関数(下の例だとdprint)を使用していたので、
# それに似たような感じをイメージしていました。


厳密に言うとCのプリプロセッサはCの言語処理系とは関係ないですよね。
プリプロセッサのディレクティブ(って言うんでしたっけ?#hogehogeっていうやつ)が無い場合は、
プリプロセッサを通さずいきなりコンパイラ(厳密な意味で、C→オブジェクトコード変換を行う
プログラム)を通しても問題ないはずですし。

Javaで同様のことをやりたいのであれば、Java用のプリプロセッサがあれば良いのではないかと
思います。
1

スキルアップ/キャリアアップ(JOB@IT)