Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 调用TreeSet时的ClassCastException<;Long>;。包含(Long.valueOf(someLongValue))_Java_Generics_Jsf 2_Updatemodel - Fatal编程技术网

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;
}

}