Java 从字符串到泛型类型的转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24589495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 13:15:42  来源:igfitidea点击:

Conversion from string to generic type

javagenericscasting

提问by SpeedEX505

I need to convert string to variable value. I found solution only for C#. I need it in Java.

我需要将字符串转换为变量值。我找到了仅适用于 C# 的解决方案。我需要它在 Java 中。

public class Property<T> {

    T value;

    public void setValue(String input){
        if(value instanceof String){
           value= input; // value is type of T not type of string (compilation error)
                         // incompatible types: String cannot be converted to T
        }
        if(value instanceof int){
           //parse string
        }
        if(value instanceof boolean){
           //parse string
        }
        ...
    }
}

采纳答案by MightyPork

That is not how it works. You can, however, use polymorphism, to achieve a useful result.

这不是它的工作原理。但是,您可以使用多态来实现有用的结果。

Solution with polymorphism

多态解决方案

Base generic (and abstract) property

基本通用(和抽象)属性

public abstract class Property<T> {
    T value;
    public abstract void setValue(String input);
}

Property for Strings

字符串的属性

public class StringProperty extends Property<String> {
    @Override
    public void setValue(String input) {
        this.value = input;
    }
}

Property for integers

整数的属性

public class IntegerProperty extends Property<Integer> {
    @Override
    public void setValue(String input) {
        this.value = Integer.valueOf(input);
    }
}

Not sure what your actual goal is, but this approach might work.

不确定您的实际目标是什么,但这种方法可能有效。

Note, that input instanceof Twill fail, because of type erasure. It's not gonna work.

请注意,input instanceof T由于类型擦除,这将失败。这是行不通的。



Solution with Class<T>as argument

Class<T>作为参数的解决方案

To elaborate more on your approach, this would work - but it's UGLY.

要详细说明您的方法,这会起作用 - 但它很丑。

Ugly and not very convenient. No idea why you'd want it, tbh.

丑陋而且不是很方便。不知道你为什么想要它,tbh。

class Property<T> {

    public T value;
    private final Class<T> clazz;

    public Property(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }       

    @SuppressWarnings("unchecked")
    public void setValue(String input) {
        if (clazz.isAssignableFrom(String.class)) {
            value = (T) input;
        } else if (clazz.isAssignableFrom(Integer.class)) {
            value = (T) Integer.valueOf(input);
        } else if (clazz.isAssignableFrom(Boolean.class)) {
            value = (T) Boolean.valueOf(input);
        } else if (clazz.isAssignableFrom(Double.class)) {
            value = (T) Double.valueOf(input);
        } else {
            throw new IllegalArgumentException("Bad type.");
        }
    }
}

Used like so:

像这样使用:

Property<String> ff = new Property<>(String.class);
ff.setValue("sdgf");

Property<Integer> sdg = new Property<>(Integer.class);
sdg.setValue("123");

System.out.println(ff.value);
System.out.println(sdg.value);


Solution with Reflection

解决方案 Reflection

Apparently, it's possible to figure out the parameter used to instantiate property.

显然,可以找出用于实例化属性的参数。

This little magic formula gives you just that:

这个神奇的小公式可以为您提供:

(Class<?>) getClass().getTypeParameters()[0].getBounds()[0]

I don't even know how I managed to find it. Well, here we go:

我什至不知道我是怎么找到它的。好吧,我们开始:

class Property<T> {

    T value;    

    @SuppressWarnings("unchecked")
    public void setValue(String input)
    {
        // BEHOLD, MAGIC!
        Class<?> clazz = (Class<?>) getClass().getTypeParameters()[0].getBounds()[0];

        if (clazz.isAssignableFrom(String.class)) {
            value = (T) input;
        } else if (clazz.isAssignableFrom(Integer.class)) {
            value = (T) Integer.valueOf(input);
        } else if (clazz.isAssignableFrom(Boolean.class)) {
            value = (T) Boolean.valueOf(input);
        } else if (clazz.isAssignableFrom(Double.class)) {
            value = (T) Double.valueOf(input); 
        } else {
            throw new IllegalArgumentException("Bad type.");
        }
    }
}

And don't look at me, I wouldn't use that. I have some common sense.

别看我,我不会用那个。我有一些常识。