【问题标题】:java.lang.String cannot be cast to java.lang.Double when using generics [duplicate]使用泛型时,java.lang.String 无法转换为 java.lang.Double [重复]
【发布时间】:2017-06-12 11:05:48
【问题描述】:

我正在使用 JSF/Primefaces 创建一个表单以允许用户输入数据。我已经定义了一个通用类Input 来允许访问数据(因为不同的字段有不同的类型)。但是,当我尝试从声明为 Input<Double> 的对象中检索数据时,我得到了异常 java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double

我有点困惑,为什么会发生这种情况,因为Input 中存储的值应该是 Double?如果有人能指出导致这种情况的正确方向,我将不胜感激。

FormBean.java

@ManagedBean(name="form", eager=true)
@SessionScoped
public class FormBean {

    private Input<String> name = new Input<>();
    private Input<Date> date = new Input<>();
    private Input<Double> hours = new Input<>();
    private Input<Double> amount = new Input<>();

    public void submit(){
        System.out.println(name.getValue());
        System.out.println(parseDate(date.getValue(),"dd/MM/yy"));
        System.out.println(formatDouble(hours.getValue()));
        System.out.println(formatDouble(amount.getValue()));    
    }

    public static String parseDate(Date date, String format){
        if(date == null) return "";
        DateFormat df = new SimpleDateFormat(format);
        return df.format(date);
    }

    public static String formatDouble(Double d){
        if(d==null) return "";
        else return String.format("%.2f", (double)d);
    }

    //-------------------GETTERS AND SETTERS----------------------------

    public Input<String> getName() {
        return name;
    }
    public Input<Date> getDate() {
        return date;
    }
    public Input<Double> getHours() {
        return hours;
    }
    public Input<Double> getAmount() {
        return amount;
    }
}

Input.java

public class Input<T> {

    private T value;
    private String styleClass = "inputdefault";

    public T getValue() {
        return value;
    }
    public void setValue(T value) {
        this.value = value;
    }
    public String getStyleClass() {
        return styleClass;
    }
    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }
}

form.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

    <h:head>
        <ui:define name="title">Form</ui:define>
    </h:head>

    <h:body>    
            <h:form id="form">
                <p:panelGrid id="formGrid" style="text-align:center;margin:20px;" columns="2" layout="grid">
                    <h:outputText class="output" value="Name"/>
                    <p:inputText id="name" class="#{form.name.styleClass}" value="#{form.name.value}"/>

                    <h:outputText class="output" value="Date:"/>
                    <p:calendar class="#{form.date.styleClass}" value="#{form.date.value}" pattern="dd/MM/yy"/>

                    <h:outputText class="output" value="Hours:"/>
                    <p:inputNumber id="hours" class="#{form.hours.styleClass}" value="#{form.hours.value}" decimalPlaces="2"/>

                    <h:outputText class="output" value="Amount:"/>
                    <p:inputNumber class="#{form.amount.styleClass}" value="#{form.amount.value}" decimalPlaces="2"/>   
                </p:panelGrid>

                <p:commandButton value="Submit" update="@form" action="#{form.submit}" class="left"/>
            </h:form>
    </h:body>

</html>

FormBean.java中submit()方法的第13行出现错误:System.out.println(formatDouble(amount.getValue()));

如果需要任何其他信息,请告诉我。 谢谢!

编辑:添加堆栈跟踪:

Jun 12, 2017 1:10:55 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
WARNING: #{form.submit}: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
javax.faces.FacesException: #{form.submit}: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: javax.faces.el.EvaluationException: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    ... 26 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
    at FormBean.submit(FormBean.java:20)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    ... 27 more

Jun 12, 2017 1:10:55 PM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
SEVERE: javax.faces.el.EvaluationException: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
    at FormBean.submit(FormBean.java:20)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    ... 27 more

【问题讨论】:

  • 错误出现在哪一行?
  • FormBean.java中submit()方法第13行出现错误:System.out.println(formatDouble(amount.getValue()));
  • 删除else return String.format("%.2f", (double)d); 中的双重转换后会得到什么输出?
  • 如果我删除双重演员,我会得到完全相同的错误。
  • stackoverflow.com/questions/14521882/…stackoverflow.com/questions/14521882/… 中的哪一个是最好的副本?我假设后者

标签: java jsf generics primefaces


【解决方案1】:

我认为问题不能在代码的和平中找到。 在您期望异常的地方,bean 只是第一次访问 bean 属性。 JSF 正在尝试调用 Input.setValue(Double double) 但从 jsf 控件出来的值是一个字符串。所以我认为这里抛出了异常。

为了确保请发布异常的堆栈跟踪。

该问题的解决方案是为您的控件配置一个值转换器。

http://download.oracle.com/otn_hosted_doc/jdeveloper/j2ee101302/jsf_apps/eventvalidate/sf_avc_converters.html

另一种解决方案是将原始值作为字符串存储在输入类中,并在调用方法以获取转换后的值(而不是 getter 方法)时将其转换为目标类型

【讨论】:

  • 我已经发布了堆栈跟踪,当submit() 方法尝试将amount.getValue() 传递给接受Double 的formatDouble() 方法时,错误似乎只发生在该行上。我查看了 PrimeFaces 文档,&lt;p:inputNumber&gt; 确实返回了 Double。
猜你喜欢
  • 2023-01-22
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多