如何修复java.lang.ClassCastException:java.lang.Double无法转换为变量表达式的java.math.BigDecimal错误?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何修复java.lang.ClassCastException:java.lang.Double无法转换为变量表达式的java.math.BigDecimal错误?相关的知识,希望对你有一定的参考价值。
我有一个变量,它包含在报告(预览)中时返回错误,但编译时没有错误。
该变量应该根据字段的数量在报告上输出2位数字。
我有一个字段$F{total balance}
的java.lang.String
类型和一个变量$V{Total_balance_num}
将其转换为数字。变量$V{Total_balance_num}
的类型为java.math.BigDecimal
:
<variable name="Total balance num" class="java.math.BigDecimal">
<variableExpression><![CDATA[new Double(Double.parseDouble($F{total_balance}))]]></variableExpression>
</variable>
主要部分是根据$V{Total_balance_num}
的数量在报告上打印不同的2位数字。这个变量叫做$V{groups}
类型的java.lang.String
:
<variable name="groups" class="java.lang.String">
<variableExpression><![CDATA[$V{Total balance num}.doubleValue() <= new java.math.BigDecimal(250).doubleValue() ? "15":
($V{Total balance num}.doubleValue() <= new java.math.BigDecimal(1000).doubleValue() ? "30":
($V{Total balance num}.doubleValue() <= new java.math.BigDecimal(10000).doubleValue() ? "30" :
($V{Total balance num}.doubleValue() <= new java.math.BigDecimal(50000).doubleValue() ? "40":"0"
)
))]]></variableExpression>
</variable>
我必须从字段字符串的字段总余额开始。编译时没有错误。但是,如果我创建一个字段来输出变量,然后单击预览我会收到此错误:
net.sf.jasperreports.engine.fill.jrexpressionevalexception error evaluating expression
net.sf.jasperreports.engine.JRException: net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression:
Source text: $V{Total_balance_num}.doubleValue() <= new java.math.BigDecimal(250).doubleValue() ? "15":($V{Total_balance_num}.doubleValue() <= new java.math.BigDecimal(1000).doubleValue() ? "30" ($V{Total_balance_num}.doubleValue() <= new java.math.BigDecimal(10000).doubleValue() ? "30" : ($V{Total_balance_num}.doubleValue() <= new java.math.BigDecimal(50000).doubleValue() ? "40":"0" ) ) )
at com.jaspersoft.studio.editor.preview.view.control.ReportControler.fillReport(ReportControler.java:466)
..
Caused by: net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression :
Source text : $V{Total_balance_num}.doubleValue() <= new java.math.BigDecimal(250).doubleValue() ? "15":($V{Total_balance_num}.doubleValue() <= new java.math.BigDecimal(1000).doubleValue() ? "30": ($V{Total_balance_num}.doubleValue() <= new java.math.BigDecimal(10000).doubleValue() ? "30" ($V{Total_balance_num}.doubleValue() <= new java.math.BigDecimal(50000).doubleValue() ? "40":"0") ) )
at net.sf.jasperreports.engine.fill.JREvaluator.evaluateEstimated(JREvaluator.java:327)
...
Caused by: java.lang.ClassCastException: java.lang.Double cannot be cast to java.math.BigDecimal at S01_1556196241282_981700.evaluateEstimated(S01_1556196241282_981700:935)
at net.sf.jasperreports.engine.fill.JREvaluator.evaluateEstimated(JREvaluator.java:314) ... 9 more
重现问题的示例代码:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="S01" pageWidth="595" pageHeight="842" columnWidth="595" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0" uuid="9b44ef22-1966-46f3-acbe-4bfb10170dbc">
<queryString language="xPath">
<![CDATA[/letter/fields]]>
</queryString>
<field name="total_balance" class="java.lang.String">
<fieldDescription><![CDATA[total_balance]]></fieldDescription>
</field>
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<variable name="Total balance num" class="java.math.BigDecimal">
<variableExpression><![CDATA[new Double(Double.parseDouble($F{total_balance}))]]></variableExpression>
</variable>
<variable name="groups" class="java.lang.String">
<variableExpression><![CDATA[$V{Total balance num}.doubleValue() <= new java.math.BigDecimal(250).doubleValue() ? "15":
($V{Total balance num}.doubleValue() <= new java.math.BigDecimal(1000).doubleValue() ? "30":
($V{Total balance num}.doubleValue() <= new java.math.BigDecimal(10000).doubleValue() ? "30" :
($V{Total balance num}.doubleValue() <= new java.math.BigDecimal(50000).doubleValue() ? "40":"0"
)
)
)]]></variableExpression>
</variable>
<detail>
<band height="841" splitType="Stretch">
<textField>
<reportElement x="62" y="136" width="238" height="15" uuid="85a6b895-3aa5-4607-b2e7-8959da279c1d">
</reportElement>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
<staticText>
<reportElement x="110" y="200" width="314" height="20" uuid="4d2918f5-b6d9-4d81-8be6-e68e1c19bd32"/>
<textElement textAlignment="Center"/>
<text><![CDATA[TEST TEXT]]></text>
</staticText>
</band>
</detail>
</jasperReport>
还有xml代码用作输入数据的适配器(保存为xml - >在Jaspersoft studio中创建新数据适配器 - >选择XML文档 - >选择文件并选择在填写报表时使用报表Xpath表达式 - >完)
<letter>
<fields>
<name>Jeff</name>
<total_balance>14576.88</total_balance>
</fields>
</letter>
What is wrong?
groups
变量的表达是正确的。你有异常,因为另一个表达式是错误的:
<variable name="Total balance num" class="java.math.BigDecimal">
<variableExpression><![CDATA[new Double(Double.parseDouble($F{total_balance}))]]></variableExpression>
</variable>
您有Caused by: java.lang.ClassCastException: java.lang.Double cannot be cast to java.math.BigDecimal
异常,因为您正在尝试为BigDecimal类型的对象分配double值。
正确的版本是:
<variable name="Total balance num" class="java.math.BigDecimal">
<variableExpression><![CDATA[$F{total_balance} == null || $F{total_balance}.length() == 0 ? BigDecimal.ZERO : new BigDecimal($F{total_balance})]]></variableExpression>
</variable>
您可以使用此表达式获取NumberFormatException。要防止出现此问题,您可以添加检查$F{total_balance}
是否为数字,例如在org.apache.commons.lang3.StringUtils.isNumeric方法的帮助下。在这种情况下,您需要将导入添加到jrxml并将Apache Commons Lang库添加到classpath。
jrxml的片段:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport ... />
<!-- ... -->
<import value="org.apache.commons.lang3.StringUtils"/>
<!-- ... -->
<variable name="Total balance num" class="java.math.BigDecimal">
<variableExpression><![CDATA[StringUtils.isNumeric($F{total_balance}) ? new BigDecimal($F{total_balance}) : BigDecimal.ZERO]]></variableExpression>
</variable>
Optimization 1. Using right type of field
您可以将字段声明为<field name="total_balance" class="java.math.BigDecimal">
。在这种情况下,您的报告将如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="S01" pageWidth="595" pageHeight="842" columnWidth="595" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0" uuid="9b44ef22-1966-46f3-acbe-4bfb10170dbc">
<queryString language="xPath">
<![CDATA[/letter/fields]]>
</queryString>
<field name="total_balance" class="java.math.BigDecimal">
<fieldDescription><![CDATA[total_balance]]></fieldDescription>
</field>
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<variable name="groups" class="java.lang.String">
<variableExpression><![CDATA[$F{total_balance}.doubleValue() <= new java.math.BigDecimal(250).doubleValue() ? "15":
($F{total_balance}.doubleValue() <= new java.math.BigDecimal(1000).doubleValue() ? "30":
($F{total_balance}.doubleValue() <= new java.math.BigDecimal(10000).doubleValue() ? "30" :
($F{total_balance}.doubleValue() <= new java.math.BigDecimal(50000).doubleValue() ? "40":"0"
)
)
)]]></variableExpression>
</variable>
<detail>
<band height="30" splitType="Stretch">
<textField>
<reportElement x="23" y="0" width="238" height="15" uuid="85a6b895-3aa5-4607-b2e7-8959da279c1d"/>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="23" y="15" width="240" height="15" uuid="33a58249-b338-4741-ad5a-4c67846cf006">
<textFieldExpression><![CDATA[$V{groups}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
使用您的测试数据,此版本的报告运行良好。
Optimization 2. Compare BigDecimal objects in right manner
比较BigDecimal对象的正确方法是使用BigDecimal.compareTo(BigDecimal)方法。
More info:
- Convert double to BigDecimal and set BigDecimal Precision
- Convert string to BigDecimal in java
- How to check if a String is numeric in Java
- How to use comparison operators like >, =, < on BigDecimal
以上是关于如何修复java.lang.ClassCastException:java.lang.Double无法转换为变量表达式的java.math.BigDecimal错误?的主要内容,如果未能解决你的问题,请参考以下文章