Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用字符串引用程序代码中的字段_Java_Android_Reflection - Fatal编程技术网

Java 如何使用字符串引用程序代码中的字段

Java 如何使用字符串引用程序代码中的字段,java,android,reflection,Java,Android,Reflection,我有一个带有各种ID常量的程序,比如 final int MN=8; final int PY=58; final int RB=13; ... 这些协方差是矩阵中元素的索引,由于各种难以解释的原因,如果我能做一个接收两个字符串的方法,这将是很好的 Object getElement("MN","PY"){ ... } 假装 Object o=mymatrix[MN][PY]; 使用传递的字符串引用声明的字段 是否有任何方法可以直接访问字段,而无需将其放入地图或使用开关以及每个字

我有一个带有各种ID常量的程序,比如

final int MN=8;
final int PY=58;
final int RB=13;
...
这些协方差是矩阵中元素的索引,由于各种难以解释的原因,如果我能做一个接收两个字符串的方法,这将是很好的

Object getElement("MN","PY"){
    ...
}
假装

 Object o=mymatrix[MN][PY];
使用传递的字符串引用声明的字段


是否有任何方法可以直接访问字段,而无需将其放入地图或使用开关以及每个字段的if-else条件?

我想您可以查看以下链接:

这里有四个有趣的建议,使用不同的方法:反射、映射、番石榴和枚举

-------编辑答案------- 大卫·华莱士的贡献

请检查以下程序:

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 );
    }
}
输出为:23000。
它是否回答了您的问题?

我想您可以查看以下链接:

这里有四个有趣的建议,使用不同的方法:反射、映射、番石榴和枚举

-------编辑答案------- 大卫·华莱士的贡献

请检查以下程序:

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 );
    }
}
输出为:23000。
它回答了你的问题吗?

有很多方法可以做到这一点,但到目前为止最简单的方法是将所有常量放在HashMap中,并在需要引用时使用get。

有很多方法可以做到这一点,但到目前为止,最简单的方法是将所有常量放在一个HashMap中,并在需要引用时使用get。

考虑重新审视您最初的假设。在运行时按名称查找变量不是一种很好的方法,特别是在Java中。这让你的任务变得比必要的更难。此外,更脆弱的变量可能会被处理工具(如Proguard)重命名

所有常量定义最终int MN=8。。。你从哪里来?如果它们是由代码生成的,那么您最好让它生成用于构造哈希映射的代码,或者生成可以读入哈希映射的数据文件。或者,如果您必须从这些常量定义开始,那么可以编写一个小程序来读取源代码文本并构造HashMap


最终的int定义在当前形式下对您没有多大帮助。

考虑重新审视您的原始假设。在运行时按名称查找变量不是一种很好的方法,特别是在Java中。这让你的任务变得比必要的更难。此外,更脆弱的变量可能会被处理工具(如Proguard)重命名

所有常量定义最终int MN=8。。。你从哪里来?如果它们是由代码生成的,那么您最好让它生成用于构造哈希映射的代码,或者生成可以读入哈希映射的数据文件。或者,如果您必须从这些常量定义开始,那么可以编写一个小程序来读取源代码文本并构造HashMap


最终的int定义在其当前形式下对您没有多大帮助。

下面是一个如何使用反射实现这一点的示例

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个,那么应该使用某种数据文件、属性文件或数据库。你不可能希望一个长长的常量列表成为源代码的一部分。

下面是一个如何使用反射来实现这一点的示例

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个,那么应该使用某种数据文件、属性文件或数据库。你不可能想要一个长长的常量列表成为源代码的一部分。

谢谢你的建议,但我正在寻找一种方法,不妨碍我将每个变量都放入映射或使用开关。没有办法直接访问字段吗?嗯,你可以使用反射,但它比仅仅使用映射更复杂,更容易出错。我更愿意冒险,因为否则我必须编写大量的代码行。XD您能给我更多关于如何使用反射来实现这一点的细节吗?谢谢,您将不得不编写更多的代码来实现反射,因为存在各种各样的检查异常,这只会让事情变得一团糟。我仍然建议使用映射-它只需要比声明所有常量多一行代码

yway,因为您将替换final int MN=8;具有常数。putMN,8;你需要的唯一额外的一行是你创建地图的那一行。我真不明白你为什么不想这么做。但是,如果您想要更长、更复杂的基于反射的解决方案,我会在稍后发布。感谢您的建议,但如果您让我看到基于反射的解决方案,我将非常感激。感谢suggewstion,但我正在寻找一种方法,不妨碍我将每个变量放入映射或使用开关。没有办法直接访问字段吗?嗯,你可以使用反射,但它比仅仅使用映射更复杂,更容易出错。我更愿意冒险,因为否则我必须编写大量的代码行。XD您能给我更多关于如何使用反射来实现这一点的细节吗?谢谢,您将不得不编写更多的代码来实现反射,因为存在各种各样的检查异常,这只会让事情变得一团糟。我仍然建议使用映射-它只需要比声明所有常量多一行代码,因为您将替换final int MN=8;具有常数。putMN,8;你需要的唯一额外的一行是你创建地图的那一行。我真不明白你为什么不想这么做。但是,如果您想要更长、更复杂的基于反射的解决方案,我会在稍后发布。感谢您的建议,但如果您让我看到基于反射的解决方案,我将非常感激。感谢您的回答,但我正在寻找一种方法,不妨碍我将每个变量放入映射或使用开关。没有办法直接访问字段吗?不客气。请给出一个你想要的代码的例子好吗?嗨,AndreaF。我刚刚编辑了我的答案,以便为您提出的问题提供一个可能的解决方案。最好根据我答案下的注释使用getField,而不是遍历所有617个。是的。好多了。我正在编辑代码。谢谢David Wallace。谢谢你的回答,但我正在寻找一种方法,不妨碍我将每个变量放入映射或使用开关。没有办法直接访问字段吗?不客气。请给出一个你想要的代码的例子好吗?嗨,AndreaF。我刚刚编辑了我的答案,以便为您提出的问题提供一个可能的解决方案。最好根据我答案下的注释使用getField,而不是遍历所有617个。是的。好多了。我正在编辑代码。谢谢大卫·华莱士。字母和数字有规律吗?你能把它们放在一个枚举中并引用它们的序号吗?例如,枚举x{AA,BB,CC,DD},然后调用x.AA.ordinal将返回0,BB是1,等等。不,字段的名称是随机的。您可以发布更多这些常量吗?有多少人?您应该在运行时将它们作为键/值对放置在映射中。MN或PY是键,8或58是值。很简单,您可以在文本编辑器中使用find/replace将其更改为映射。将所有617个变量添加到www.pastebin.com,我将为您格式化。稍微超出正方形,但您甚至可以将整个地块复制/粘贴到属性文件中,只需搜索/替换空格为点,将分号替换为零。然后使用properties.getPropertyfinal.int+字段名;在你的密码里,字母和数字有没有一个模式?你能把它们放在一个枚举中并引用它们的序号吗?例如,枚举x{AA,BB,CC,DD},然后调用x.AA.ordinal将返回0,BB是1,等等。不,字段的名称是随机的。您可以发布更多这些常量吗?有多少人?您应该在运行时将它们作为键/值对放置在映射中。MN或PY是键,8或58是值。很简单,您可以在文本编辑器中使用find/replace将其更改为映射。将所有617个变量添加到www.pastebin.com,我将为您格式化。稍微超出正方形,但您甚至可以将整个地块复制/粘贴到属性文件中,只需搜索/替换空格为点,将分号替换为零。然后使用properties.getPropertyfinal.int+字段名;在你的代码中。