如何在抽象类中初始化泛型值?

huangapple go评论57阅读模式
英文:

How to initialize a generic value in an abstract class?

问题

我有一个带有通用泛型值的通用抽象类,我想将其标记为 final:

public abstract class Value<T>
{
  final T value;

  static class StringValue extends Value<String>
  {
    StringValue(String value)
    {
      this.value = value + value;
    }
  }

  static class IntegerValue extends Value<Integer>
  {
    IntegerValue(Integer value)
    {
      this.value = value * value;
    }
  }

  public static void main(String[] args)
  {
    StringValue s = new StringValue("Hello");
    IntegerValue i = new IntegerValue(42);
  }
}

但是这不起作用:

Value.java:9: error: cannot assign a value to final variable value
      this.value = value;
          ^
Value.java:17: error: cannot assign a value to final variable value
      this.value = value;
          ^
2 errors

编译器强制我在抽象类中初始化通用值,但这毫无意义,因为这个值是通用的,只能在派生类中进行初始化。

如何解决这个问题?

英文:

I have a generic abstract class with a generic value, which I would like to mark final:

public abstract class Value&lt;T&gt;
{
  final T value;

  static class StringValue extends Value&lt;String&gt;
  {
    StringValue (String value)
    {
      this.value = value + value;
    }
  }

  static class IntegerValue extends Value&lt;Integer&gt;
  {
    IntegerValue (Integer value)
    {
      this.value = value * value;
    }
  }

  public static void main (String[] args)
  {
    StringValue  s = new StringValue (&quot;Hello&quot;);
    IntegerValue i = new IntegerValue (42);
  }
}

But this does not work:

<!-- language: none -->

Value.java:9: error: cannot assign a value to final variable value
      this.value = value;
          ^
Value.java:17: error: cannot assign a value to final variable value
      this.value = value;
          ^
2 errors

The compiler forces me to initialize the generic value in the abstract class, but this does not make any sense, because the value is generic and can only be initialized in the derived classes.

How to work around this problem?

答案1

得分: 11

你需要在声明时或类的构造函数中为final变量赋值。

这与子类的构造函数不兼容。

然而,抽象类可以有一个带有泛型类型作为参数的构造函数,并在其中使用它。

然后子类可以调用父类构造函数:

public abstract class Value<T>
{
  final T value;
  protected Value(T value){
    this.value=value;
  }

  static class StringValue extends Value<String>
  {
    StringValue (String value)
    {
      super(value + value);
    }
  }

  static class IntegerValue extends Value<Integer>
  {
    IntegerValue (Integer value)
    {
      super(value * value);
    }
  }

  public static void main (String[] args)
  {
    StringValue  s = new StringValue ("Hello");
    IntegerValue i = new IntegerValue (42);
  }
}
英文:

You need to either assign a final variable when declaring it or in the constructor of the class.

It does not work with the constructor of child classes.

However, the abstract class can have a constructor with the generic type as a parameter and use that.

The child classes can then call the parent constructor:

public abstract class Value&lt;T&gt;
{
  final T value;
  protected Value(T value){
    this.value=value;
  }

  static class StringValue extends Value&lt;String&gt;
  {
    StringValue (String value)
    {
      super(value + value);
    }
  }

  static class IntegerValue extends Value&lt;Integer&gt;
  {
    IntegerValue (Integer value)
    {
      super(value * value);
    }
  }

  public static void main (String[] args)
  {
    StringValue  s = new StringValue (&quot;Hello&quot;);
    IntegerValue i = new IntegerValue (42);
  }
}

huangapple
  • 本文由 发表于 2020年8月31日 02:40:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63660924.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定