简体   繁体   English

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

[英]Get the value from a java public class with key reference

We have a java public class as, 我们有一个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;
    }
}

How to get the value from class object like, 如何从类对象中获取值,如

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

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

This is not possible in java to suffix an object with a String to access to a field of it. 这在java中不可能为具有String的对象添加后缀以访问其字段。

Either use reflection to access the fields from the field names or refactor the class so that it provides an implementation key-value with a Map<String,String> for example. 使用反射来从字段名称访问字段或重构类,以便它提供一个实现键值,例如Map<String,String>

Here is a full example with key-value map. 这是一个带键值映射的完整示例。

As ob1 and ob2 are inner classes, these have some limitations about static use (for fields as methods). 由于ob1ob2是内部类,因此它们在static使用方面存在一些限制(对于字段作为方法)。
So a workaround is declaring the static maps and the static retrieval method in the outer class. 因此,解决方法是在外部类中声明static映射和static检索方法。
It hurts a little the separation of responsibilities but with these modifier constraints, it is hard to do in a different way but using instance fields and methods in the inner classes. 它有点伤害责任分离,但是使用这些修饰符约束,很难以不同的方式做,而是使用内部类中的实例字段和方法。

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

It prints : 它打印:

T1T1 T1T1

T8T8 T8T8

You could use reflection to get the values: 您可以使用反射来获取值:

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

But in general, it is better to maintain a map for your types with inner maps for the key-value-pairs: 但一般来说,最好使用键值对的内部贴图维护类型的贴图:

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

Now your method becomes as easy as: 现在您的方法变得如此简单:

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

Note, that I intentionally left out failure handling such as unknown types. 请注意,我故意遗漏了未知类型等故障处理。

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

This attempts to access a static variable named key in the class ob1 and a another static variable also named key in the class ob2 . 这种试图访问一个静态变量命名的key在类ob1和另一静态变量也叫key在课堂ob2 Neither class has such a variable and the name is completely unrelated to the parameter named key . 这两个类都没有这样的变量,并且名称与名为key的参数完全无关。 This just will not compile no matter how hard you try. 无论你怎么努力,这都无法编译。

In Java, variable names are only available at compile time (mostly). 在Java中,变量名仅在编译时可用(大多数情况下)。 This means that you cannot use the value of a String variable as a variable name. 这意味着您不能将String变量的值用作变量名。

Granted there is the Reflection API, but if you find yourself thinking you should use this, you are most likely using the wrong solution for the problem. 虽然有反射API,但如果你发现自己认为应该使用它,那么你最有可能使用错误的解决方案来解决问题。 Reflection is intended for tools, such as IDEs and debuggers. 反射适用于IDE和调试器等工具。

A solution with reflection: 有反射的解决方案:

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

It prints: 它打印:

T1T1
T7T7
T2T2
T8T8

You could use reflection to get to the static Strings. 您可以使用反射来获取静态字符串。 However, instead of using static inner classes, if you have access to class Test, you could refactor it to use a Map. 但是,如果您可以访问类Test,而不是使用静态内部类,则可以重构它以使用Map。

a solution without reflection and maybe not that clean, but working fine for this example 一个没有反射的解决方案,可能不是那么干净,但对于这个例子工作正常

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

Please find my solution code :- 请找到我的解决方案代码: -

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM