Java 调用TreeSet时的ClassCastException<;Long>;。包含(Long.valueOf(someLongValue))
我被难住了。我宣布我的套装如下:Java 调用TreeSet时的ClassCastException<;Long>;。包含(Long.valueOf(someLongValue)),java,generics,jsf-2,updatemodel,Java,Generics,Jsf 2,Updatemodel,我被难住了。我宣布我的套装如下: private Set<Long> applicationIds; 导致异常的行(堆栈跟踪的第84行)如下所示: if ( applicationIds.contains( Long.valueOf( application.getId() ) ) ) { 也许我遗漏了什么,但是如果声明是Set,并且我调用contains方法传递Long.valueOf值,那么我如何获得此异常 这是一个JSF应用程序的模型
private Set<Long> applicationIds;
导致异常的行(堆栈跟踪的第84行)如下所示:
if ( applicationIds.contains( Long.valueOf( application.getId() ) ) ) {
也许我遗漏了什么,但是如果声明是Set
,并且我调用contains
方法传递Long.valueOf
值,那么我如何获得此异常
这是一个JSF应用程序的模型bean。我使用的是Java 6、Tomcat 6.0.32、mojarra 2.1.14,但这些都不重要,因为泛型应该可以防止编译时出现这种问题
------编辑-----------------
实际上是JSF。。。我用这个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("\n\t'").append(value.getClass().getName())
.append("': '").append(value.toString()).append("'");
}
logger.trace(message.toString());
}
this.selections = null;
}
因此,简单的答案是正确的(谢谢@PaulTomblin强调这一点)。正在使用包含字符串的Set
调用setter。那么现在,转换的最佳过程是什么?我是否需要遍历列表,将每个值转换为Long
作为补充说明,我使用Java7在Tomcat7上测试了这一点,ClassCastException消失了,但是,contains
方法总是像预期的那样返回false
--------------编辑2--------------
我找到了一个正确的方法来绑定我的组件
--------------编辑3--------------
这是对问题的更好解释
也许我遗漏了一些东西,但是如果设置了声明并且调用了contains方法并传入了Long.valueOf值,我怎么能得到这个异常呢
请注意,在Java中,泛型类型注释只是编译器的提示,在运行时没有任何效果,因此在运行时可能会违反这些约束(但在某些地方会出现编译器警告)
看起来您的集实际上至少包含一个字符串。那台电视机是从哪里来的
因为泛型应该在编译时防止这种问题
是的,代码中应该有一个关于缺少泛型类型或未选中类型转换的警告。这只是一个警告,因为泛型是可选的。在您使用它们的地方,这可能是一个错误
也许我遗漏了一些东西,但是如果设置了声明并且调用了contains方法并传入了Long.valueOf值,我怎么能得到这个异常呢
请注意,在Java中,泛型类型注释只是编译器的提示,在运行时没有任何效果,因此在运行时可能会违反这些约束(但在某些地方会出现编译器警告)
看起来您的集实际上至少包含一个字符串。那台电视机是从哪里来的
因为泛型应该在编译时防止这种问题
是的,代码中应该有一个关于缺少泛型类型或未选中类型转换的警告。这只是一个警告,因为泛型是可选的。在您确实使用它们的地方,这可能是一个错误。好的@Lucas我刚刚尝试使用快速脏代码,使用您作为问题一部分发布的代码,效果很好。您可能需要再次检查应用程序
类
package javaapplication2;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class JavaApplication2 {
private static Set<Long> applicationIds;
private List<Application> applications;
private static final List<Application> availableApplications = new ArrayList<>();
public static void main(String[] args) {
JavaApplication2 proj = new JavaApplication2();
for (int i = 1; i <= 11; i++) {
Application application = new Application();
application.setId(i);
availableApplications.add(application);
}
Set<Long> applicationIds1 = new TreeSet<>();
applicationIds1.add(11L);
applicationIds1.add(12L);
applicationIds1.add(13L);
proj.setApplicationIds(applicationIds1);
for (Application appl : proj.getApplications()) {
System.out.println(appl.getId());
}
}
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;
}
好的@Lucas我刚刚尝试了使用快速脏代码,使用了你作为问题的一部分发布的代码,效果很好。您可能需要再次检查应用程序
类
package javaapplication2;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class JavaApplication2 {
private static Set<Long> applicationIds;
private List<Application> applications;
private static final List<Application> availableApplications = new ArrayList<>();
public static void main(String[] args) {
JavaApplication2 proj = new JavaApplication2();
for (int i = 1; i <= 11; i++) {
Application application = new Application();
application.setId(i);
availableApplications.add(application);
}
Set<Long> applicationIds1 = new TreeSet<>();
applicationIds1.add(11L);
applicationIds1.add(12L);
applicationIds1.add(13L);
proj.setApplicationIds(applicationIds1);
for (Application appl : proj.getApplications()) {
System.out.println(appl.getId());
}
}
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;
}
看起来您的集实际上至少包含一个字符串。该集合来自何处?您确定application.getId()
返回的内容Long.valueOf将合法地转换为Long吗?@PaulTomblin:如果不是,那将是一个编译错误(或至少是另一个堆栈跟踪)。setApplicationIds
一定是用错误的集合调用的。使用调试器。对包含要设置的非长字符串的集合调用“SetApplicationId”的十比一。看起来您的集合实际上至少包含一个字符串。该集合来自何处?您确定application.getId()
返回的内容Long.valueOf将合法地转换为Long吗?@PaulTomblin:如果不是,那将是一个编译错误(或至少是另一个堆栈跟踪)。setApplicationIds
一定是用错误的集合调用的。使用调试器。十比一调用“SetApplicationID”的集合包含您要设置的非long值。控制台输出如预期的那样:11
,控制台输出如预期的那样:11
“但在某个地方会有编译器警告”,假设TreeSet API是类型安全的,也就是说,如果你有一个树集,没有
,你通过将它强制转换到树集
,将它传递到setApplicationID中,那么很可能它里面有不长的东西,然后当你试图调用时,你会得到ClassCastException。contains
。正如亨利·斯宾塞(Henry Spencer)的一句名言“如果你对编译器撒谎,程序将得到报复”。@RyanStewart,打得好。。。JSF调用了setApplicationID()
,并发送了一个Set
,其中包含对oracle文档的String
sA引用和一些调试问题的代码:“但是在某个地方会有编译器警告”,假设TreeSet API是类型安全的,也就是说,如果你有一个树集,没有
,你通过将它强制转换到树集
,将它传递到setApplicationID中,那么很可能它里面有不长的东西,然后当你试图调用时,你会得到ClassCastException。contains
。正如亨利·斯宾塞(Henry Spencer)的一句名言“如果你对编译器撒谎,程序将得到报复”。@RyanStewart,打得好。。。是的
public void setSelectedValues(Set<Long> selectedValues) {
this.selectedValues = selectedValues;
if (logger.isTraceEnabled()) {
StringBuilder message = new StringBuilder("Selected values:");
for (Object value : selectedValues) {
message.append("\n\t'").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'
package javaapplication2;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class JavaApplication2 {
private static Set<Long> applicationIds;
private List<Application> applications;
private static final List<Application> availableApplications = new ArrayList<>();
public static void main(String[] args) {
JavaApplication2 proj = new JavaApplication2();
for (int i = 1; i <= 11; i++) {
Application application = new Application();
application.setId(i);
availableApplications.add(application);
}
Set<Long> applicationIds1 = new TreeSet<>();
applicationIds1.add(11L);
applicationIds1.add(12L);
applicationIds1.add(13L);
proj.setApplicationIds(applicationIds1);
for (Application appl : proj.getApplications()) {
System.out.println(appl.getId());
}
}
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;
}
package javaapplication2;
class Application {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}