我有一个包含各种ID常量的程序,比如
final int MN=8;
final int PY=58;
final int RB=13;
...
这些costants是矩阵中元素的索引,由于各种原因难以解释,会很好如果我可以做一个接收两个字符串的方法,例如
Object getElement("MN","PY"){
...
}
像
这样的行为 Object o=mymatrix[MN][PY];
使用传递的字符串引用声明的字段
有没有办法直接访问这些字段(不将它们放在Map中或使用switch和if else条件的每个字段)?
答案 0 :(得分:2)
我认为您可以查看此链接:Get variable by name from a String
那里有四个有趣的建议,使用不同的方法:反射,地图,番石榴和Enum。
-------------- EDITED ANSWER ------------- (David Wallace的贡献)
请检查以下程序:
import java.lang.reflect.Field;
public class Main
{
public final static int MN = 0;
public final static int PY = 1;
public final static int RB = 2;
private static int[][] myMatrix = new int[][]
{
{ 1, 2, 3 },
{ 10, 20, 30 },
{ 100, 200, 300 }
};
public static void main( String[] args ) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException
{
System.out.println( getElement( "MN", "PY" ) );
System.out.println( getElement( "PY", "RB" ) );
System.out.println( getElement( "RB", "RB" ) );
}
public static int getElement( String i0, String i1 ) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException
{
return myMatrix[ getValueByName( i0 )] [ getValueByName( i1 ) ];
}
public static int getValueByName( String varName ) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException
{
Field f = Main.class.getField( varName );
return f.getInt( f );
}
}
输出为:2,30,300。 它会回答你的问题吗?
答案 1 :(得分:2)
以下是如何使用反射执行此操作的说明。
public class Matrix {
private Object[][] values = new Object[100][100];
private final int MN=8;
private final int PY=58;
private final int RB=13;
public static void main(String[] args){
Matrix matrix = new Matrix();
matrix.values[8][58] = "Hello";
try {
System.out.println(matrix.getElement("MN","PY"));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
public Object getElement(String rowConstant, String columnConstant)
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
return values[getConstant(rowConstant)][getConstant(columnConstant)];
}
private int getConstant(String constant)
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
return getClass().getDeclaredField(constant).getInt(this);
}
}
在main
方法中查看如何将对象放入数组中,然后使用反射来检索它。
我完全不推荐这种技术。我只是在这里提出这个答案,因为你特意问我这个问题。我真的认为你这是错误的做法。
如果你有少量的常量,你应该使用HashMap
或类似的结构。如果你确实有617个,那么你应该使用某种数据文件,属性文件或数据库。你不可能想要一长串的常量列表成为源代码的一部分。
答案 2 :(得分:1)
有很多方法可以做到这一点,但到目前为止最简单的方法是将所有常量放在HashMap
中,并在需要引用时使用get
。
答案 3 :(得分:0)
考虑重新审视您的原始假设。在运行时按名称查找变量并不是一个好方法,尤其是。在Java中。它使你的任务比必要的更难。更脆弱 - 变量可以通过Proguard等处理工具重命名。
所有常量定义final int MN=8;
......首先来自何处?如果它们是由代码生成的,那么你最好还是生成代码来构造一个HashMap,或者一个你可以读入HashMap的数据文件。或者如果你必须从那些常量定义开始,写一个小程序来读取源代码文本并构造一个HashMap。
最终的int定义对他们目前的形式没有太大帮助。