如何从Generic获取特定的返回类型

时间:2018-03-27 10:16:37

标签: java generic-programming

我有类属性

class Attribute{
private Parser parser;
private String value;
private ParserType parseType;
}

和Enum

Enum ParserType{
STRING,NUMBER,RANGE
}

和解析器接口

interface Parser<S,T>{
 T parse(S s){
}
}

现在基于不同的数据类型,我以不同的方式解析值。所以为此我创建了类

class StringParser implements Parser<String,String>{

@override
public String parse(String value){
return //... parse and return string
}

以类似的方式我有其他解析器

 class DoubleParser implements Parser<String,Double>{

@override
public Double parse(String value){
return //... parse and return double
}

我在这里做的是在属性中引用Parser并根据其 ParserType

设置不同类型的解析器

例如

class Attribute{
private Parser parser;
private String value;
private ParserType parseType;

Attribute(String value,ParserType parsertype){
 this.value=value;
 this.parserType=parserType
 }

private void setParserType()
 {
 switch(parserType){
  case ParserType.String:
   parser=new StringParser();
  break;

  case ParserType.Number:
  parser=new NumberParser();
  break;
 }

 }

  public void parse(){
  parser.parse(value); // here return type is object...  and i want it to be String if it is StringParser and bouble if it is DoubleParser
  }
}

如果您在属性类中看到 parse()方法。如果它是 StringParser ,我希望它给出String数据类型,如果它是 DoubleParser

,我希望它是double

我知道我在使用泛型做错了。所以我的问题是实现这一目标的最佳做法是什么?

已更新

感谢回答那些人..但是现在我想在地图中存储属性,但是当我做这样的事情时,它会返回对象

// I did changes in my Attribute class 
public T parse(){
return parser.parse(value); // here return type is object...  and i want it to be String if it is StringParser and bouble if it is DoubleParser
}

Map<String,Attribute> map;
//assuming my map has some entries
for(Map.Entry<String,Attribute> m:map.entrySet()){
 map.getValue().parse(); // this parse methods returns object to me here. I want it to be some specific type like String or Double
}

2 个答案:

答案 0 :(得分:1)

在创建Attribute.java

对象时提供您的返回类型

<强> Parser.java

interface Parser<S,T>{
     T parse(S s);
}

<强> StringParser.java

public class StringParser<S> implements Parser<String, S>{
    @Override
    public S parse(String s) {
        return (S) "Hello";
    }
}

<强> DoubleParser.java

public class DoubleParser<S> implements Parser<Double, S>{
    @Override
    public S parse(Double s) {
        return (S) new Double(1);
    }
}

<强> Attribute.java

public class Attribute<T, R> {
    public T value;
    private Parser<T, R> parser;

    public Attribute(T value, String parserType) {
        switch (parserType) {
        case "ParserTypeString":
            parser = (Parser<T, R>) new StringParser<R>();
            break;
        case "ParserTypeNumber":
            parser = (Parser<T, R>) new DoubleParser<R>();
            break;
        }

    }

    public R parseReturn() {
        return parser.parse(value);
    }
}

<强> Test.java

public class Test {
    public static void main(String[] args) {
        Attribute<String, String> str = new Attribute<String, String>("World", "ParserTypeString");
        System.out.println(str.parseReturn());

        Attribute<Double, Double> dbl = new Attribute<Double, Double>(5D, "ParserTypeNumber");
        System.out.println(dbl.parseReturn());
    }
}

答案 1 :(得分:1)

你可以这样做。

class Attribute<T, R> {

    private final T value;

    private final Parser<T, R> parser;

    public Attribute(T value, Parser<T, R> parser) {
        this.value = value;
        this.parser = parser;
    }

    private R parse() {
        return parser.parse(value);
    }

    private interface Parser<T, R> {
        R parse(T t);
    }

    private static class StringParser implements Parser<String, String> {
        @Override
        public String parse(String s) {
            return s;
        }
    }

    private static class DoubleParser implements Parser<String, Double> {
        @Override
        public Double parse(String s) {
            return Double.parseDouble(s);
        }
    }

    public static void main(String[] args) {
        Attribute<String, String> stringAttribute = new Attribute<>("input", new StringParser());
        Attribute<String, Double> doubleAttribute = new Attribute<>("1.0", new DoubleParser());

        System.out.println(stringAttribute.parse()); //should print the string
        System.out.println(doubleAttribute.parse()); //prints the double value
    }
}

注意 - 我已在同一个类中添加了所有接口和类,以便将示例保存在单个文件中,供您复制和运行,而无需创建多个文件。

我还稍微改变了结构,使其更具可读性。您可以在构造属性类期间提供解析器,而不是将ParserType保留在类中,然后决定要实例化的解析器。属性类不应该对此负责。