This discussion is archived
12 Replies Latest reply: Nov 18, 2010 4:31 AM by jduprez RSS

java.lang.ClassCastException

Gage-Bollo Newbie
Currently Being Moderated
Hi,

Can anyone please tell me why i am getting this exception, "java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double" , and how to resolve it.

I have a column that fires this event as soon as the vaue in it is changed
public void tblCompoundItemsTableChanged(TableModelEvent e) {

        DecimalFormat df = new DecimalFormat("#,###,###,##0.00");
        if (!comboChanged) {
            int row = e.getFirstRow();
            int column = e.getColumn();
            TableModel model = (TableModel)e.getSource();

            if (column == 2) {
                double qty = (Double)model.getValueAt(row, column);
                double unitPrice = (Double)model.getValueAt(row, 3);

                //if unitPrice = 11,240.57
                System.out.println(df.format(unitPrice));

            }
   
        }
  
    }
And the DefaultTableModel for the table is as follows,
class MyTableModel extends DefaultTableModel {
    MyTableModel(ArrayList data, Vector column) {
        super();
        this.dataVector = convertToVector(data);
        this.columnIdentifiers = column;
    }

    public Vector blankRow() {
        Vector v = new Vector();

                v.add("");
                v.add("");
                v.add(new Double(1));
                v.add(new Double(0));
                v.add(new Double(0));

        return v;
    }

    Vector convertToVector(ArrayList al) {
        Vector data = new Vector();
        if (al != null) {
            for (int i = 0; i < al.size(); i++) {
                Vector v = new Vector();
                ProductView pv = (ProductView)al.get(i);
                v.add(pv.getProductCode());
                v.add(pv.getPurchaseDescription());
                v.add(pv.getQuantity());
                v.add(pv.getCostBase());
                v.add(pv.getLineTotal());

                data.add(v);
            }
        } else {

                data.add(blankRow());
        }

        return data;

    }

    @Override
    public int getColumnCount() {
        return columnIdentifiers.size();
    }
    @Override
    public int getRowCount() {
        return dataVector.size();
    }
    @Override
    public String getColumnName(int col) {
        return columnIdentifiers.elementAt(col).toString();
    }
    @Override
    public Object getValueAt(int row, int col) {
        Vector vecRow = (Vector) dataVector.elementAt(row);
        return vecRow.elementAt(col);
    }
    @Override
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }
    @Override
    public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        if (col == 1 | col > 2) {
            return false;
        } else {
            return true;
        }
    }

    public void setData(ArrayList newData) {
        this.dataVector = convertToVector(newData);
        fireTableDataChanged();
    }
}
Thanks,
Zweli
  • 1. Re: java.lang.ClassCastException
    Kayaman Guru
    Currently Being Moderated
    Maybe parseDouble() is what you want.


    Just because you say a String is a Double, doesn't mean that Java will believe you.
  • 2. Re: java.lang.ClassCastException
    jduprez Pro
    Currently Being Moderated
    Gage-Bollo wrote:
    Can anyone please tell me why i am getting this exception, "java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double" , and how to resolve it.
    if (column == 2) {
    double qty = (Double)model.getValueAt(row, column);
    double unitPrice = (Double)model.getValueAt(row, 3);
    ...
    }
    
    Vector convertToVector(ArrayList al) {
    ...
    v.add(pv.getProductCode());
    v.add(pv.getPurchaseDescription());
    v.add(pv.getQuantity());
    v.add(pv.getCostBase());
    (...)
    Apparently (since the code is only partial), you're trying to cast a Quantity and a CostBase properties to Double. Are you sure those are actually doubles?

    On an unrelated note:
    @Override
    public int getColumnCount() {
    @Override
    public int getRowCount() {
    @Override
    public String getColumnName(int col) {
    @Override
    public Object getValueAt(int row, int col) {
    }
    Usually you don't have to override those when you already subclass DefaultTableModel, since that latter is meant to provide a sensible implementation of those. If you do find yourself overriding all of them, consider extending AbstractTableModel instead, at least it's more intention-revealing.
  • 3. Re: java.lang.ClassCastException
    jduprez Pro
    Currently Being Moderated
    Apparently (since the code is only partial), you're trying to cast a Quantity and a CostBase properties to Double. Are you sure those are actually doubles?
    Note, but again it's probably not related to your problem, that double seems a poor choice for such things.
    - Actual values of quantities are usually integer numbers, or decimal numbers. More rarely, fractional numbers, but that's odd. int, BigInteger, BigDecimal are a preferred choice for such things (general fractional numbers would require double, or a specific class).
    - prices should almost never be floating-point numbers. In almost all applications, the accuracy of operations on "money things" is a must, and floating-point numbers (float, double) operations have known rounding effects (as they cannot represent infinite precision on a finite number of bits). Prices and more generally, money quantities, are usually represented using BigDecimal, or a specific class (e.g. to support different currencies, or rounding rules).
  • 4. Re: java.lang.ClassCastException
    Gage-Bollo Newbie
    Currently Being Moderated
    Thanks, but if I use parseDouble(), I get a "java.lang.NumberFormatException: For input string: "11,240.57"".
  • 5. Re: java.lang.ClassCastException
    Gage-Bollo Newbie
    Currently Being Moderated
    Oh ok, I understand where you are getting at, what would you recommend?

    Thanks.
  • 6. Re: java.lang.ClassCastException
    jduprez Pro
    Currently Being Moderated
    Thanks, but if I use parseDouble(), I get a "java.lang.NumberFormatException: For input string: "11,240.57"".
    So, the value was definitely a String, not a Double.
    java.lang.NumberFormatException: For input string: "11,240.57"
    As specified by the [url http://download.oracle.com/javase/6/docs/api/java/lang/Double.html#parseDouble%28java.lang.String%29]API Javadoc for Double.parseDouble() :
    public static double parseDouble(String s) throws NumberFormatException
    Returns a new double initialized to the value represented by the specified String, as performed by the valueOf method of class Double.
    public static Double valueOf(String s) throws NumberFormatException

    Returns a Double object holding the double value represented by the argument string s.
    (...) s should constitute a FloatValue as described by the lexical syntax rules:

    FloatValue: (...)
    as defined in the lexical structure sections of the of the Java Language Specification.
    The point is, the string should be a double as you write it in Java source (e.g. +11240.57+ ), not the way you write a real value in everyday life ( +11,240.57+ if you're american)
  • 7. Re: java.lang.ClassCastException
    jduprez Pro
    Currently Being Moderated
    not the way you write a real value in everyday life ( +11,240.57+ if you're american)
    And the reason is exactly that: "everyday format" of numbers is locale-dependant (me poor French would write it +11 240,57+ instead).
    The javadoc for Double.valueOf(String) explicitly mentions:
    To interpret localized string representations of a floating-point value, use subclasses of NumberFormat.
  • 8. Re: java.lang.ClassCastException
    Gage-Bollo Newbie
    Currently Being Moderated
    Ahhhh, I also used the NumberFormat, in the code below, and it works!!
    public void tblCompoundItemsTableChanged(TableModelEvent e) {
           
            if (!comboChanged && !newItem) {
                int row = e.getFirstRow();
                int column = e.getColumn();
                TableModel model = (TableModel)e.getSource();
    
                if (column == 2) {
                    double qty = (Double)model.getValueAt(row, column);
                    
                    String str = model.getValueAt(row, 3).toString();
                    NumberFormat nf = NumberFormat.getInstance();
                    try {
                        Number num = nf.parse(str);
                        double unitPrice = num.doubleValue();
                        
                        model.setValueAt(unitPrice * qty, row, 4);
                    } catch (ParseException pe) {}
                   
                }
       
            }
      
        }
    Just for interest sake though, while on the NumberFormat topic, where and why would I get a "java.lang.IllegalArgumentException: Cannot format given Object as a Number"?
    As I stated, the code works, but i get an exception if i, eg add and insert into a new row.

    Thanks, Zweli
  • 9. Re: java.lang.ClassCastException
    Gage-Bollo Newbie
    Currently Being Moderated
    Actually, I have it all figured out, I think.

    Thanks for all the input.

    Zweli
  • 10. Re: java.lang.ClassCastException
    jduprez Pro
    Currently Being Moderated
    Just for interest sake though, while on the NumberFormat topic, where and why would I get a "java.lang.IllegalArgumentException: Cannot format given Object as a Number"?
    As I stated, the code works, but i get an exception if i, eg add and insert into a new row.
    I would have like to point you at the API Javadoc, but I don't find how parse could throw such an exception. I suspect you have it in a format(...) call instead: from the API Javadoc of NumberFormat.format(Object,...) :
    public StringBuffer format(Object number, ...)

    Formats a number and appends the resulting text (...)

    Throws:
    IllegalArgumentException - if number is null or not an instance of Number.
    Or more generally, for Format.format(Object) :
    public final String format(Object obj)

    Formats an object to produce a string. This is equivalent to
    (...)
    Throws:
    IllegalArgumentException - if the Format cannot format the given object
    So presumably you try to format an object that is not a java.lang.Number .
  • 11. Re: java.lang.ClassCastException
    Gage-Bollo Newbie
    Currently Being Moderated
    Oh ok, then it must be something else because when I add a new row, the default values are 1,for quantity, and 0.0, for unit price. And only throws the when I add values into designated columns

    Zweli
  • 12. Re: java.lang.ClassCastException
    jduprez Pro
    Currently Being Moderated
    I cannot infer more based on the code provided.
    The best way to get help from that point would be:
    1) provide the exact exception text and stack trace
    2) provide the code involved in that stack trace
    3) preferably, provide an [url http://sscce.org]SSCCE demonstrating the problem.
    4) mark the topic as unanswered again, or open a new topic (people may skip answered topics, to focus on contributing to those still needing help)

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points