Java记录泛型:非静态类型变量T无法从静态上下文中引用。

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

Java records Generics : non-static type variable T cannot be referenced from a static context

问题

public record Result<T>() {
    private static ResultState state;
    private static Exception exception;
    private static T value;

    public Result(T value) {
        state = ResultState.Success;
        value = value;
        exception = null;
    }

    public Result(Exception e) {
        state = ResultState.Faulted;
        exception = e;
        value = null;
    }

    public static Supplier<Boolean> isFaulted = () -> state == ResultState.Faulted;

    public static Supplier<Boolean> isSuccess = () -> state == ResultState.Success;

    public void match(Consumer<T> succ, Consumer<Exception> fail) {
        if (isFaulted.get())
            fail.accept(exception);
        else
            succ.accept(value);
    }
}

**Exception**

error: non-static type variable T cannot be referenced from a static context
    private static T value;
               ^
英文:
 public record Result&lt;T&gt;() {
    private static ResultState state;
    private static Exception exception;
    private static T value;

    public Result(T value) {
        state = ResultState.Success;
        value = value;
        exception = null;
    }

    public Result(Exception e) {
        state = ResultState.Faulted;
        exception = e;
        value = null;
    }

    public static Supplier&lt;Boolean&gt; isFaulted = () -&gt; state == ResultState.Faulted;

    public static Supplier&lt;Boolean&gt; isSuccess = () -&gt; state == ResultState.Success;

    public void match(Consumer&lt;T&gt; succ, Consumer&lt;Exception&gt; fail) {
        if (isFaulted.get())
            fail.accept(exception);
        else
            succ.accept(value);
    }
}

Exception

error: non-static type variable T cannot be referenced from a static context
    private static T value;
               ^

答案1

得分: 2

因为 `T` 是一个可以在不同实例之间不同的通用类型你不能将其用于静态字段这与记录无关这只是 Java 的工作方式例如如果你编写这个类你将会得到相同的编译错误

```java
class MyClass&lt;T&gt; {
    public static T staticField; // ... 无法从静态上下文引用
}

因此,如果你用 Object 替换通用类型 T,你的代码示例将会工作:

static record Result&lt;T&gt;() {
	private static ResultState state;
	private static Exception exception;
	private static Object value;
   
    // ...
}

然而,这看起来是错误的,因为每次计算都会覆盖之前的(静态)结果。在我看来,正确的方式应该是在记录本身内部声明 state, valueexception 字段,就像这样:

static record Result&lt;T&gt;(
	ResultState state,
	T value,
	Exception exception
) {

	public Result(T value) {
		this(ResultState.Success, value, null);
	}

	public Result(Exception e) {
		this(ResultState.Success, null, e);
	}

	public void match(Consumer&lt;T&gt; succ, Consumer&lt;Exception&gt; fail) {
		if (state == ResultState.Faulted)
			fail.accept(exception);
		else
			succ.accept(value);
	}
}
英文:

Since T is a generic type that can differ from one instance to another, you cannot use it for a static field. It doesn't have to do with records, it's just how java works. For instance, if you write this class, you'll get the same complication error:

class MyClass&lt;T&gt; {
    public static T staticField; // ... cannot be referenced from a static context
}

As a result, if you replace the generic type T with Object, your code example will work:

static record Result&lt;T&gt;() {
	private static ResultState state;
	private static Exception exception;
	private static Object value;
   
    // ...
}

However, this looks wrong because each computation will override the previous (static) result. In my opinion, the correct way would be declare the state, value and exception fields inside the record itself, like this:

static record Result&lt;T&gt;(
	ResultState state,
	T value,
	Exception exception
) {

	public Result(T value) {
		this(ResultState.Success, value, null);
	}

	public Result(Exception e) {
		this(ResultState.Success, null, e);
	}

	public void match(Consumer&lt;T&gt; succ, Consumer&lt;Exception&gt; fail) {
		if (state == ResultState.Faulted)
			fail.accept(exception);
		else
			succ.accept(value);
	}
}

huangapple
  • 本文由 发表于 2023年5月29日 19:24:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76356919.html
匿名

发表评论

匿名网友

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

确定