2013-05-23 3 views
4

Existe-t-il un moyen d'implémenter ce type de code en Java?Passer une référence par chaîne en Java

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

et d'imprimer 3?

Edit: Plus précisément, je voudrais analyser un String ou char et retourner un int représentant un KeyEvent. Par exemple, j'aimerais pouvoir faire ceci:

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

Non, ce n'est pas possible. Qu'est-ce que vous essayez d'accomplir? –

+0

Je voudrais analyser un 'String' dans un tableau de' KeyEvent's. –

+0

C'est certainement possible; voir ma réponse ci-dessous. Si cela devrait être fait est une autre question. :-) –

Répondre

2

En général, en Java, vous ne pouvez pas référencer des variables par nom (comme des chaînes, dans l'exécution, ce qui appelle Perl « références soft »). Mais dans certains cas (champs, variables non locales), vous pouvez obtenir un comportement similaire avec la réflexion.

Pour votre intention, vous pouvez le faire:

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); 
}  

Mais garder à l'esprit qu'un événement chaîne saisie peut déclencher plus d'un VK_ * (par exemple passer.). Et les deux H et h correspondent à VK_H, donc ce ne sera pas imiter exactement les événements déclenchés en tapant la chaîne hello (sans parler des caractères non-alphanumériques, des touches mortes, backspaces, etc etc)

+0

Merci! La réflexion semble très intéressante; Je vais faire quelques lectures à ce sujet. –

-1

Vous pouvez utiliser la réflexion java.

Reflection for field

 Class<?> c = Class.forName("YOUR_CLASS_NAME"); 
     Field f = c.getField("FOO"); 
     System.out.println(f.getInt()); 
+0

Veuillez poster un exemple de code montrant comment accomplir ceci avec réflexion. –

+1

Non, vous ne pouvez pas le faire avec les locaux :) – dasblinkenlight

+0

@dasblinkenlight Pas encore: D –

6

Sans savoir exactement ce que vous essayez d'accomplir, c'est le plus proche, je pense que vous pourriez obtenir:

Map<String, Integer> map = new HashMap<String, Integer>(); 

map.put("foo", 3); 

System.out.println(map.get("foo")); 
0

Vous pouvez utiliser le code suivant:

int foo = 3; 
String data = Integer.toString(foo); 

Ceci permettra à l'int d'être stocké dans un fichier String. Je suppose que vous pourriez le passer dans votre méthode et retourner tout ce que vous voulez.

Bien que le code ci-dessus fonctionne, je ne sais pas quand vous l'utiliserez.

+0

Une raison de downvote? Je ne suis pas sûr à 100% de ce que l'OP veut, mais si j'ai fait une erreur/supposition, dites-le. –

1

Voici comment faire avec réflexion:

char c = "C"; 
Robot rob = new Robot(); 
Field field = KeyEvent.class.getDeclaredField("VK_"+c);   
int i = field.getInt(null); 
rob.keyPress(i); 
1

Je vois ce que vous essayez faire. Aucune des autres réponses n'est correcte.

Vous voulez obtenir la constante "correcte" KeyEvent pour un caractère donné, et vous voulez le faire sans avoir à écrire une sorte de table de recherche qui serait une longueur de zillion.

En effet, la réflexion vous aidera ici. Ce sera raisonnablement lent. Mais ça va faire le boulot. Si le travail a réellement besoin de faire est une autre question.:-)

La fonction en question que vous voulez est probablement quelque chose comme ceci:

/** 
* 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); 
} 

Ensuite, vous pouvez le nourrir comme suit, bien que vous aurez toutes sortes de problèmes si le String fourni contient des caractères la fonction I décrit ci-dessus n'est pas modifié pour gérer les exceptions correctement:

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; 
} 

Tout ce code est non testé. Bonne chance. Je devine que vous avez encore quelque chose de trop compliqué, mais j'espère que cela vous aidera à vous orienter dans la bonne direction.

+0

@leonbloy a répondu en même temps que moi; nos réponses sont essentiellement similaires; bonne chance! –

+0

Foire. Mais je ne suis pas tout à fait d'accord avec vos affirmations; ces cas doivent être (au plus) des exceptions (voir par exemple les commentaires de cette réponse http://stackoverflow.com/a/2758262/277304 ou http://stackoverflow.com/questions/1276308/exception-vs-assertion) – leonbloy

+0

'String # toCharArray()' est documenté pour ne jamais retourner 'null'. Donc, un 'affirmer 'est approprié ici (nous réifions la documentation). De plus, nous avons déjà vérifié 's.isEmpty()'. Il est donc impossible que le tableau 'char' ait une longueur inférieure ou égale à' 0'. Je suis d'accord avec les assertions. –