12 Replies Latest reply: Nov 18, 2010 6:31 AM by jduprez RSS

    java.lang.ClassCastException

    Gage-Bollo
      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
          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
            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
              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
                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
                  Oh ok, I understand where you are getting at, what would you recommend?

                  Thanks.
                  • 6. Re: java.lang.ClassCastException
                    jduprez
                    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
                      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
                        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
                          Actually, I have it all figured out, I think.

                          Thanks for all the input.

                          Zweli
                          • 10. Re: java.lang.ClassCastException
                            jduprez
                            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
                              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
                                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)