首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用泛型类型时的Java AtomicReferenceFieldUpdater - ClassCastException

使用泛型类型时的Java AtomicReferenceFieldUpdater - ClassCastException
EN

Stack Overflow用户
提问于 2015-08-06 22:08:04
回答 1查看 397关注 0票数 0

我得到以下错误:

代码语言:javascript
复制
Exception in thread "main" java.lang.ClassCastException
at java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.<init>(AtomicReferenceFieldUpdater.java:336)
at java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdater.java:109)
at org.telegram.bot.util.FieldTimer.<init>(FieldTimer.java:27)
at org.telegram.bot.util.FieldTimer.<init>(FieldTimer.java:19)
at org.telegram.bot.util.FieldTimer.main(FieldTimer.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

当对泛型类型使用AtomicReferenceFieldUpdater时。

我完全糊涂了,我不知道我为什么会犯这样的错误。

我使用的代码:

代码语言:javascript
复制
public final class FieldTimer<V> {

    private volatile V value;
    private final V defaultValue;
    private final long resetTimeout;
    private final AtomicLong lastSet;
    private final AtomicReferenceFieldUpdater<FieldTimer, V> updater;

    public FieldTimer(V value, Class<V> type, long resetTimeout, TimeUnit unit) {
        this(value, value, type, resetTimeout, unit);
    }

    public FieldTimer(V value, V defaultValue, Class<V> type, long resetTimeout, TimeUnit unit) {
        this.value = value;
        this.defaultValue = defaultValue;
        this.resetTimeout = unit.toMillis(resetTimeout);
        lastSet = new AtomicLong(System.currentTimeMillis());
        updater = AtomicReferenceFieldUpdater.newUpdater(FieldTimer.class, type, "value");
    }

    public V get() {
        return System.currentTimeMillis() - lastSet.get() >= resetTimeout
                ? defaultValue
                : value;
    }

    public void set(V value) {
        updater.set(this, value);
        lastSet.set(System.currentTimeMillis());
    }

    public boolean compareAndSet(V expect, V update) {
        boolean set = updater.compareAndSet(this, expect, update);
        if (set) {
            lastSet.set(System.currentTimeMillis());
        }
        return set;
    }

}

异常发生在这一行代码中:

代码语言:javascript
复制
updater = AtomicReferenceFieldUpdater.newUpdater(FieldTimer.class, type, "value");

但如果我把它改成这样的话:

代码语言:javascript
复制
public final class LongFieldTimer {

    private volatile Long value;

    ...

    public LongFieldTimer(Long value, Long defaultValue, long resetTimeout, TimeUnit unit) {
        ...
        updater = AtomicReferenceFieldUpdater.newUpdater(LongFieldTimer.class, Long.class, "value");
    }

}

那么就不会有错误:x(但是为什么?)

是什么导致了这个问题?以及如何解决这个问题?

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-06 22:11:45

你的领域

代码语言:javascript
复制
private volatile V value;

Object类型的,因为type erasureAtomicReferenceFieldUpdater#newUpdater的javadoc声明它抛出

ClassCastException -如果字段类型错误

您可能已经传递了Long.classlong.class作为type参数的参数。它期望Object.class

在第二个示例中,该字段显式地定义为Long类型。

代码语言:javascript
复制
private volatile Long value;

因此,Long.class可以工作,因为这是所期望的字段类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31866625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档