调用 TreeSet<Long>.contains( Long.valueOf( someLongValue ) ) 时出现 ClassCastException [英] ClassCastException when calling TreeSet&lt;Long&gt;.contains( Long.valueOf( someLongValue ) )

查看:18
本文介绍了调用 TreeSet<Long>.contains( Long.valueOf( someLongValue ) ) 时出现 ClassCastException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被难住了.我这样声明我的集合:

Im stumped. I declare my set thusly:

    private Set<Long> applicationIds;

然后我像这样填充它:

public void setApplicationIds( Set<Long> applicationIds ) {
    this.applicationIds = new TreeSet<Long>( applicationIds );
    this.applications = null;
}

然后我尝试使用它:

public List<Application> getApplications() {
    if ( applications == null ) {
        applications = new ArrayList<Application>();
        if ( applicationIds != null ) {
            for ( Application application : availableApplications ) {
                if ( applicationIds.contains( Long.valueOf( application.getId() ) ) ) {
                    applications.add( application );
                }
            }
        }
    }
    return applications;
}

我最终得到了这个:

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
    at java.lang.Long.compareTo(Long.java:50)
    at java.util.TreeMap.getEntry(TreeMap.java:346)
    at java.util.TreeMap.containsKey(TreeMap.java:227)
    at java.util.TreeSet.contains(TreeSet.java:234)
    at org.mitre.asias.pf.pnp.viewmodel.Subscription.getApplications(Subscription.java:84)

导致异常的行(堆栈跟踪中的第 84 行)是这样的:

The line causing the exception (line 84 from the stack trace) is this one:

                if ( applicationIds.contains( Long.valueOf( application.getId() ) ) ) {

也许我遗漏了一些东西,但是如果声明是 Set 并且我正在调用 contains 方法并传入一个 Long.valueOf值,我怎么能得到这个异常?

Perhaps I am missing something, but if the declaration is Set<Long> and I am calling the contains method passing in a Long.valueOf value, how can I be getting this exception?

这是一个 JSF 应用程序的模型 bean.我正在使用 Java 6、Tomcat 6.0.32、mojarra 2.1.14,但这些都不重要,因为泛型应该防止这种问题编译时间...

This is a model bean for a JSF application. I am using Java 6, Tomcat 6.0.32, mojarra 2.1.14, but none of that should really matter as the Generics are supposed to prevent this kind of problem compile time...

-------------- 编辑 -----------------

它实际上是 JSF...我用这个 setter 拼凑了一个超级简化的例子:

Its actually the JSF... I threw together a super simplified example with this setter:

public void setSelectedValues(Set<Long> selectedValues) {
    this.selectedValues = selectedValues;
    if (logger.isTraceEnabled()) {
        StringBuilder message = new StringBuilder("Selected values:");
        for (Object value : selectedValues) {
            message.append("
	'").append(value.getClass().getName())
                    .append("': '").append(value.toString()).append("'");
        }
        logger.trace(message.toString());
    }
    this.selections = null;
}

绑定到这个组件:

<p:selectManyCheckbox id="numbers"
   value="#{controller.selectedValues}" layout="pageDirection">
  <f:selectItems value="#{controller.availableValues}" />
</p:selectManyCheckbox>

将其写入日志:

15:45:16.887 [http-bio-8080-exec-9] TRACE com.pastdev.learn.debug.Controller - Selected values:
    'java.lang.String': '1'
    'java.lang.String': '5'

所以,简单的答案是正确的(感谢@PaulTomblin 强调这一点).使用包含 StringSet 调用 setter .那么现在,转换的最佳过程是什么?我是否需要遍历列表将每个值转换为 Long?

So, the simple answer is the correct one (thank you @PaulTomblin for emphasizing this). The setter is getting called with a Set that contains Strings. So now, what is the best process for conversion? Will I need to iterate through the list casting each value to a Long?

附带说明,我使用 Java 7 在 Tomcat 7 上对此进行了测试,ClassCastException 消失了,但是,contains 方法总是按预期返回 false.

As a side note, I tested this on Tomcat 7 using Java 7 and the ClassCastException went away, however, the contains method always returns false as should be expected.

-------------- EDIT 2 -----------------

我在此处找到了绑定组件的正确方法的答案.

I found an answer with the correct way to bind my component here.

-------------- 编辑 3 -----------------

这里是对问题的更好解释.

推荐答案

也许我遗漏了一些东西,但是如果声明是 Set 并且我正在调用传递 Long.valueOf 值的 contains 方法,我怎么能得到这个异常?

Perhaps I am missing something, but if the declaration is Set and I am calling the contains method passing in a Long.valueOf value, how can I be getting this exception?

请注意,在Java中,泛型类型注解只是对编译器的提示,在运行时没有任何作用,因此在运行时可能会违反这些约束(但在某处会出现编译器警告).

Note that in Java, generic type annotations are only hints for the compiler and have no effect at runtime, so it is possible to violate these constraints at runtime (but there will be a compiler warning somewhere).

看起来您的 Set 实际上至少包含一个字符串.那个 Set 是从哪里来的?

Looks like your Set<Long> actually contains at least one String. Where is that Set coming from?

因为泛型应该防止这种问题编译时间

as the Generics are supposed to prevent this kind of problem compile time

是的,您的代码中应该有一个关于缺少泛型类型或未经检查的强制转换的警告.这只是一个警告,因为泛型是可选的.在您确实使用它们的地方,这将是一个错误.

Yes, there should be a warning somewhere in your code about missing generic types or unchecked casts. It is only a warning because generics are optional. In the places where you did use them, it would have been an error.

这篇关于调用 TreeSet<Long>.contains( Long.valueOf( someLongValue ) ) 时出现 ClassCastException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆