从具有键引用的java公共类中获取值

时间:2017-07-24 07:19:48

标签: java reference

我们有一个java公共类,

public class Test {
    public class ob1 {
        public static final String test = "T1T1";
        public static final String test2 = "T7T7";
    }

    public class ob2 {
        public static final String test = "T2T2";
        public static final String test2 = "T8T8";
    }

    public static String getVal(int type, String key) {
        return type == 1 ? ob1.key : ob2.key;
    }
}

如何从类对象中获取值,如

String t = Test.getVal(1, test);   /// This should return T1T1

String t = Test.getVal(2, test2);  /// This should return T8T8

7 个答案:

答案 0 :(得分:4)

在java中,这不可能使用String后缀来访问其字段的对象。

使用反射来访问字段名称中的字段或重构类,以便它提供具有Map<String,String>的实现键值。

以下是键值映射的完整示例。

由于ob1ob2是内部类,因此对static使用(对于字段作为方法)有一些限制。
因此,解决方法是在外部类中声明static映射和static检索方法。
它会伤害责任的分离,但是使用这些修饰符约束,很难以不同的方式做,而是在内部类中使用实例字段和方法。

import java.util.HashMap;
import java.util.Map;

public class Test {

    public class ob1 {
      public static final String test = "T1T1";
      public static final String test2 = "T7T7";
    }

    public class ob2 {
      public static final String test = "T2T2";
      public static final String test2 = "T8T8";
    }

    static Map<String, String> valuesObj1;
    static Map<String, String> valuesObj2;

    static {
      valuesObj1 = new HashMap<>();
      valuesObj1.put("test", ob1.test );
      valuesObj1.put("test2", ob1.test2);

      valuesObj2 = new HashMap<>();
      valuesObj2.put("test", ob2.test);
      valuesObj2.put("test2",ob2.test2);
    }

    public static String getVal(int type, String key) {
      return type == 1 ? valuesObj1.get(key) : valuesObj2.get(key);
    }

    public static void main(String[] args) {
      System.out.println(Test.getVal(1, "test"));
      System.out.println(Test.getVal(2, "test2"));
    }
}

打印:

  

T1T1

     

T8T8

答案 1 :(得分:2)

您可以使用反射来获取值:

public static String getVal(int type, String key) throws ReflectiveOperationException {
    Class<?> clazz = Class.forName("Test$ob" + type);
    Field field = clazz.getDeclaredField(key);
    return (String) field.get(null);
}

但总的来说,最好使用键值对的内部地图维护类型的地图:

Map<String, String> ob1Mapping = new HashMap<>();
ob1Mapping.put("test", "T1T1");
ob1Mapping.put("test2", "");

Map<String, String> ob2Mapping = new HashMap<>();
ob2Mapping.put("test", "T2T2");
ob2Mapping.put("test2", "T8T8");

Map<Integer, Map<String, String>> typeMapping = new HashMap();
typeMapping.put(1, ob1Mapping);
typeMapping.put(2, ob1Mapping);

现在你的方法变得如此简单:

public static String getVal(int type, String key) {
    return typeMapping.get(type).get(key);
}

请注意,我故意遗漏了未知类型等故障处理。

答案 2 :(得分:1)

public static String getVal(int type, String key) {
    return type == 1 ? ob1.key : ob2.key;
}

这会尝试访问类key中名为ob1的静态变量,以及类key中另一个名为ob2的静态变量。这两个类都没有这样的变量,名称与名为key的参数完全无关。无论你怎么努力,这都无法编译。

在Java中,变量名仅在编译时可用(大多数情况下)。这意味着您不能将String变量的值用作变量名。

当然有Reflection API,但是如果你发现自己认为应该使用它,那么你最有可能使用错误的解决方案来解决问题。反射适用于IDE和调试器等工具。

答案 3 :(得分:1)

带反射的解决方案:

public class Test {

    public class ob1 {

        public static final String test = "T1T1";
        public static final String test2 = "T7T7";
    }

    public class ob2 {

        public static final String test = "T2T2";
        public static final String test2 = "T8T8";
    }

    public static String getVal(int type, String key) throws Exception {
        return getVal(type == 1 ? ob1.class : ob2.class, key);
    }

    private static String getVal(Class<?> type, String key) throws Exception {
        if (key != null) {
            Field field = type.getDeclaredField(key);
            if (Modifier.isStatic(field.getModifiers()) && field.getType() == String.class) {
                return (String) field.get(null);
            }
        }
        throw new IllegalArgumentException("Wrong argument: "+key);
    }

    public static void main(String[] args) throws Exception {
        System.out.println(Test.getVal(1, "test"));
        System.out.println(Test.getVal(1, "test2"));
        System.out.println(Test.getVal(2, "test"));
        System.out.println(Test.getVal(2, "test2"));
    }
}

打印:

T1T1
T7T7
T2T2
T8T8

答案 4 :(得分:0)

您可以使用反射来获取静态字符串。但是,如果您可以访问类Test,而不是使用静态内部类,则可以重构它以使用Map。

答案 5 :(得分:0)

没有反射的解决方案,也许不是那么干净,但是对于这个例子来说工作正常

public static String getVal(int type, String key) {
    if (type == 1) {
        if (key.equalsIgnoreCase("test")) {
            return ob1.test;
        } else {
            return ob1.test2;
        }
    }
    if (type == 2) {
        if (key.equalsIgnoreCase("test")) {
            return ob2.test;
        } else {
            return ob2.test2;
        }
    } else {
        return null;
    }
}

答案 6 :(得分:0)

请找到我的解决方案代码: -

import java.util.HashMap;
import java.util.Map;

public class Test {

    public class ob1 {
        public static final String test = "T1T1";
        public static final String test2 = "T7T7";
        public ob1() {
              valuesObj1 = new HashMap<>();
              valuesObj1.put("test", ob1.test );
              valuesObj1.put("test2", ob1.test2);


        }
    }

    public class ob2 {
        public static final String test = "T2T2";
        public static final String test2 = "T8T8";
        public ob2() {
              valuesObj2 = new HashMap<>();
              valuesObj2.put("test", test);
              valuesObj2.put("test2",test2);
        }
    }

    static Map<String, String> valuesObj1;
    static Map<String, String> valuesObj2;

    public static String getVal(int type, String key) {
        return type == 1 ? valuesObj1.get(key) : valuesObj2.get(key);
    }

    public static void main(String[] args) {
        Test t =new Test();
         t.new ob1();
         t.new ob2();

        System.out.println(getVal(1, "test"));
    }
}