简体   繁体   中英

How to declare a variable type knowing its type by a string

I'm trying to declare a variable type using a json document... The problem is that i need to declare its type Long or Double and that depends on the string for example:

the raw value is a double:

{"raw":119970000,"fmt":"119.97M","longFmt":"119,970,000"}

this is a Double too:

{"raw":0.068,"fmt":"6.80%"}

but this is a long:

{"raw":1443571200,"fmt":"2015-09-30"}

i'm using regex on the "fmt" fields so i can know the type but the proble i got is at the moment of declaring the type

i'm trying to do this but there is an error and i don't know exactly why.

This is my "Field" Class:

    public class Field {

      @JsonProperty("raw") private RawField raw;
      @JsonProperty("fmt") private String fmt;
      @JsonIgnore private FieldType fieldType;

      @JsonCreator
      public Field(
        @JsonProperty("raw") RawField raw,
        @JsonProperty("fmt") final String fmt
      ) {
        this.setFmt(fmt);
        this.setRaw(raw, fmt);
      }

      private boolean isDate(String fmt){
        Pattern datePattern = Pattern.compile(
          "[0-9]{4}-(([1][0-2])|(0[0-9]))-((0[1-9])|(1[0-9])|(2[0-9])|(3[0-1]))"
        );
        Matcher matcher = datePattern.matcher(fmt);
        return matcher.find();
      }

      private boolean isDouble(String fmt) {
        Pattern datePattern = Pattern.compile(
          "[0-9]+\\.?[0-9]*(M|B|%)?$"
        );
        Matcher matcher = datePattern.matcher(fmt);
        return !isDate(fmt) && matcher.find();
      }


      public String getFmt() {
        return fmt;
      }

      public void setFmt(final String fmt) {
        this.fmt = fmt;
      }

      public RawField getRaw() {
        return raw;
      }

      public void setRaw(final RawField raw) {
        this.raw = raw;
      }

      private void setRaw(final RawField raw, String fmt) {
        if(isDate(fmt)) {
          this.raw = new RawField<Long>(raw); //error
        } else {
          if(isDouble(fmt)){
            this.raw = new RawField<Double>(raw); //error
          }
        }


      }
    }

and this is my RawField class:

public class RawField <E> {

  @JsonProperty("raw") private E rawField;

  @JsonCreator
  public RawField (E rawField){
    this.setRawField(rawField);
  }

  @JsonProperty("raw")
  public void setRawField(E rawField) {
    this.rawField = rawField;
  }
  @JsonProperty("raw")
  public E getRawField() {
    return rawField;
  }
}

The generic class RawField<E extends Number> for E being either Long or Double is cumbersome, because of type erasure.

So I would use either the base type, Number , or a one-in-all BigDecimal

 Number raw;

 private void setRaw(final RawField raw, String fmt) {
    if(isDate(fmt)) {
      long t = ...
      this.raw = t;
    } else {
      if(isDouble(fmt)) {
        double x = .... 
        this.raw = x;
      }
    }
  }

  double y = field.raw.doubleValue();
  long n = field.raw.longValue();
  if (field.raw instanceof Double) { ... }

BigDecimal would have the advantage over a double by having a precision: new BigDecimal("3.14") has a precision of 2 and is exact.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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