Search code examples
javaillegalargumentexception

IllegalArgumentException when formatting a Java MessageFormat text


I'm given the main and the TEXT but all of the other classes and implementation are possible to be the cause of the error.

Updated

import java.util.*;
import java.lang.*;
import java.text.*;
import java.math.*;


class BankAccount extends AccountHolder { 
private static final String TEXT =  "I am a {0} account with {1} units of {2} 
currency";

public static void main(String args[] ) throws Exception {

    List<BankAccount> accounts = new ArrayList<BankAccount>();
    accounts.add(new SavingsAccount("USD",3));//Savings
    accounts.add(new SavingsAccount("EUR",2));//Savings
    accounts.add(new CheckingAccount("HUF",100));//Checking
    accounts.add(new CheckingAccount("COP",10000));//Checking
    accounts.add(new BrokerageAccount("GBP",2));//Brokerage
    accounts.add(new BrokerageAccount("INR",600));//Brokerage

    accounts.stream().forEach(
                                account -> System.out.println(
                                    MessageFormat.format(TEXT,
                                        new Object[]{

account.getAccountType().getName(),//make this work
                                        account.getUnits(),//make this work
                                        account.getCurrency()//make this work
                                                       })));
}

AccountHolder customer = new AccountHolder();
String units;
Integer currency;

void setCustomer(AccountHolder acctHolder) {
    this.customer = acctHolder;
}

AccountHolder getAccountType() {
    return customer;
}

//set units
void setUnits(String unit) {
    this.units = unit;
}

void setType(String type) {
    customer.setType(type);
}

String getUnits() {
    return units;
}

//set currency 
void setCurrency(Integer curr) {
    this.currency = curr;       
 }

Integer getCurrency() {
    return currency;
  }
 }

class SavingsAccount extends BankAccount {

SavingsAccount(String unit, Integer curr) {
    super.setName("Saving");
    super.setUnits(unit);
    super.setCurrency(curr);
  } 
 }

class CheckingAccount extends BankAccount {

CheckingAccount(String unit, Integer curr) {
    super.setName("Checking");
    super.setUnits(unit);
    super.setCurrency(curr);
  } 
 }

 class BrokerageAccount extends BankAccount {

 BrokerageAccount(String unit, Integer curr) {
    super.setName("Brokerage");
    super.setUnits(unit);
    super.setCurrency(curr);
}   
}

 class AccountHolder {

 String name;
 String acctType;

String getName() {
    return name;
}   

void setName(String name) {
    this.name = name;
}

void setType(String type) {
    this.acctType = type;
}

String getType() {
    return acctType;
  }
 }

Updated Revised

import java.util.*;
import java.lang.*;
import java.text.*;
import java.math.*;


class BankAccount extends AccountHolder { 
private static final String TEXT =  "I am a {0} account with {1,number,#} 
units of {2} currency";

public static void main(String args[] ) throws Exception {

    List<BankAccount> accounts = new ArrayList<BankAccount>();
    accounts.add(new SavingsAccount("USD",3));//Savings
    accounts.add(new SavingsAccount("EUR",2));//Savings
    accounts.add(new CheckingAccount("HUF",100));//Checking
    accounts.add(new CheckingAccount("COP",10000));//Checking
    accounts.add(new BrokerageAccount("GBP",2));//Brokerage
    accounts.add(new BrokerageAccount("INR",600));//Brokerage

    accounts.stream().forEach(
                                account -> System.out.println(
                                    MessageFormat.format(TEXT,
                                        new Object[]{

account.getAccountType().getName(),//make this work
                                        account.getUnits(),//make this work
                                        account.getCurrency()//make this work
                                                       })));
}

AccountHolder customer = new AccountHolder();
Integer units;
String currency;

void setCustomer(AccountHolder acctHolder) {
    this.customer = acctHolder;
}

AccountHolder getAccountType() {
    return customer;
}

//set units
void setUnits(Integer unit) {
    this.units = unit;
}

void setType(String type) {
    customer.setType(type);
}

Integer getUnits() {
    return units;
}

//set currency 
void setCurrency(String curr) {
    this.currency = curr;       
}

String getCurrency() {
    return currency;
 }
}

class SavingsAccount extends BankAccount {

 SavingsAccount(String curr, Integer unit) {
    super.getAccountType().setName("Saving");
    super.setUnits(unit);
    super.setCurrency(curr);
  } 
 }

class CheckingAccount extends BankAccount {

 CheckingAccount(String curr, Integer unit) {
    super.setUnits(unit);
    super.getAccountType().setName("Checking");
    super.setCurrency(curr);
 }  
}

class BrokerageAccount extends BankAccount {

BrokerageAccount(String curr, Integer unit) {
    super.getAccountType().setName("Brokerage");
    super.setUnits(unit);
    super.setCurrency(curr);
    }   
 }

class AccountHolder {

 String name;
 String acctType;

 String getName() {
    return name;
 }   

 void setName(String name) {
    this.name = name;
 }

 void setType(String type) {
    this.acctType = type;
 }

 String getType() {
    return acctType;
 }
}

This is that the console stack trace:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot format given Object as a Number
    at java.text.DecimalFormat.format(Unknown Source)
    at java.text.Format.format(Unknown Source)
    at java.text.MessageFormat.subformat(Unknown Source)
    at java.text.MessageFormat.format(Unknown Source)
    at java.text.Format.format(Unknown Source)
    at java.text.MessageFormat.format(Unknown Source)
    at BankAccount.lambda$main$0(BankAccount.java:22)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
    at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source)
    at BankAccount.main(BankAccount.java:20)

I've tried returning the currency as an Integer as shown but also Number, and casting but all return an error somewhat similar. The use of Strings doesn't have issue it's only with the creation of the new Objects and passing through with the numeric value. It's provided the type is of Object.

Edit I changed the units into Number type from the input given. Now I get

  Exception in thread "main" java.lang.NumberFormatException: For input 
 string: 
   "USD"
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at java.lang.Integer.valueOf(Unknown Source)
    at SavingsAccount.<init>(BankAccount.java:69)
    at BankAccount.main(BankAccount.java:13)

Solution

  • BankAccount.units field is of type String however you are attempting to display it as a number with {1,number,#} format.

    Either change units to something that can be converted to a numbers (e.g. Integer) or use a different format to print it (e.g. display as-is with just {1}).