4

この種のコードを Java で実装する方法はありますか?

int foo = 3;
String data = "foo";
System.out.println(StringToReference(data));

と印刷3

編集:String具体的には、 orを解析して、 aを表すcharを返したいと思います。たとえば、私はこれを行うことができるようにしたいと思います:intKeyEvent

for(char c : "hello")
    new Robot().keyPress(StringToReference("KeyEvent.VK_"+c));
4

6 に答える 6

2

一般に、Java では変数を名前で参照することはできません (実行時に文字列として。Perl が「ソフト参照」と呼ぶもの)。ただし、場合によっては (ローカル変数ではなくフィールド)、リフレクションで同様の動作を得ることができます。

あなたの意図のために、これを行うことができます:

public static int getKeyEventVK(char c) throws 
                      IllegalArgumentException, SecurityException, 
                      IllegalAccessException, NoSuchFieldException {
    return KeyEvent.class.getField("VK_" + 
               String.valueOf(c).toUpperCase()).getInt(null);

}

public static void main(String[] args) throws Exception{
    System.out.println(getKeyEventVK('h'));
    System.out.println(KeyEvent.VK_H);
}       

ただし、型指定された文字列が複数の VK_* イベントをトリガーする可能性があることに注意してください (例: shift)。と の両方Hが にh対応するVK_Hため、文字列を入力することによってトリガーされるイベントを正確に模倣することはできませんhello(英数字以外の文字、デッド キー、バックスペースなどは言うまでもありません)。

于 2013-05-23T19:46:25.360 に答える
1

私はあなたがやろうとしていることを見ます。他の答えはどれも正しくありません。

与えられた文字の「正しい」KeyEvent定数を取得したいのですが、膨大な行数になるルックアップ テーブルを作成する必要はありません。

確かに、反射はここであなたを助けます。かなり遅くなります。しかし、それは仕事をします。仕事が実際に行う必要があるかどうかは別の問題です。:-)

問題の関数は、おそらく次のようなものです。

/**
 * If possible, returns an {@code int} equal to one of the {@code public
 * static final int} constants present in the {@link KeyEvent} class
 * whose names start with {@code VK_}.
 *
 * <p>This implementation does no error handling whatsoever and has not
 * been tested or compiled.</p>
 * 
 * <p>This method is placed explicitly in the public domain.</p>
 *
 * @param c the character to use while searching for a field; no attempt
 * will be made by this implementation to validate it in any way
 *
 * @return a {@link KeyEvent} constant whose name starts with {@code VK_}
 *
 * @exception Exception for any of a number of possible reasons
 */
public int getKeyEventConstant(final char c) throws Exception {
  final Field field = KeyEvent.class.getField(String.format("VK_%S", Character.valueOf(c)));
  assert field != null;
  return field.getInt(null);
}

次に、次のようにフィードできますが、提供さStringれたに文字が含まれていると、さまざまな問題が発生します。上記の関数は、例外を適切に処理するように編集されていません。

public  toKeyEventCodes(final String s) {
  int[] returnValue = null;
  if (s != null && !s.isEmpty()) {
    final Collection<Integer> codes = new ArrayList<Integer>(s.length());
    final char[] chars = s.toCharArray();
    assert chars != null;
    assert chars.length > 0;
    for (final char c : chars) {
      if (!Character.isWhitespace(c)) { // TODO: weed out other obvious dumb chars
        codes.add(Integer.valueOf(getKeyEventConstant(c)));
      }
    }
    returnValue = codes.toArray(new int[codes.size()]);
  }
  if (returnValue == null) {
    returnValue = new int[0];
  }
  return returnValue;
}

このコードはすべてテストされていません。幸運を。まだ複雑すぎる問題が発生していると思いますが、うまくいけば、これで正しい方向に進むことができます。

于 2013-05-23T19:56:34.543 に答える
-1

Java リフレクションを使用できます。

フィールドの反射

       Class<?> c = Class.forName("YOUR_CLASS_NAME");
       Field f = c.getField("FOO");
       System.out.println(f.getInt());
于 2013-05-23T19:22:29.890 に答える