抛出自定义异常

huangapple go评论60阅读模式
英文:

Throwing own exceptions

问题

import java.io.IllegalArgumentException;

class Account {
    final int accountNo;
    final Customer owner;
    final double overdraft;

    double balance = 0;

    private Account(int accountNo, Customer owner, double overdraft) {
        this.accountNo = accountNo;
        this.owner = owner;
        this.overdraft = overdraft;
    }

    void print() {
        Out.println("Kontonummer: " + accountNo);
        owner.print();
        Out.format("Kontostand: %.2f%nÜberziehungsrahmen: %.2f%n", balance, overdraft);
    }

    public boolean deposit(double amount) throws IllegalArgumentException {
        if (amount <= 0) {
            throws new IllegalArgumentException("Cannot deposit negative amounts!");
            break;
        } else {
            balance += amount;
            return true;
        }
    }

    public boolean withdraw(double amount) throws OverdraftLimitReachedException {
        if (amount <= 0 || !isCovered(amount)) {
            throw new OverdraftLimitReachedException("Overdraft limit has been reached", accountNo);
            break;
        } else {
            balance -= amount;
            return true;
        }
    }

    boolean isCovered(double amount) {
        return amount - overdraft <= balance;
    }

    boolean transfer(Account target, double amount) {
        boolean success = withdraw(amount);
        if (!success) return false;

        target.deposit(amount);
        return true;
    }
}
public class NoSuchAccountException extends AccountException {
    public NoSuchAccountException(int accountNo) {
        super(message, accountNo);
    }
}
class Banking {
    static final int CAPACITY = 100;

    final Account[] accounts = new Account[CAPACITY];
    int nOfAccounts = 0;

    int createAccount(String firstName, String lastName, String phone, double overdraft) {
        if (nOfAccounts == CAPACITY) return -1;

        // use nOfAccounts as accountNo and index to array
        Customer owner = new Customer(firstName, lastName, phone);
        Account account = new Account(nOfAccounts, owner, overdraft);
        accounts[nOfAccounts] = account;
        nOfAccounts++;

        return account.accountNo;
    }

    boolean deposit(int accountNo, double amount) {
        if (accountNo < 0 || accountNo >= nOfAccounts) return false;

        Account account = accounts[accountNo];
        return account.deposit(amount);
    }

    boolean withdraw(int accountNo, double amount) {
        if (accountNo < 0 || accountNo >= nOfAccounts) return false;

        Account account = accounts[accountNo];
        return account.withdraw(amount);
    }

    boolean transfer(int fromNo, int toNo, double amount) {
        if (fromNo < 0 || toNo < 0 ||
            fromNo >= nOfAccounts || toNo >= nOfAccounts) return false;

        Account from = accounts[fromNo];
        Account to = accounts[toNo];
        return from.transfer(to, amount);
    }

    double getBalance(int accountNo) {
        if (accountNo < 0 || accountNo >= nOfAccounts) return 0;

        Account account = accounts[accountNo];
        return account.balance;
    }

    double getBalance() {
        double sum = 0;

        for (int i = 0; i < nOfAccounts; i++) {
            sum += accounts[i].balance;
        }
        return sum;
    }

    void print() {
        Out.println("---------- Bankauszug ----------");

        for (int i = 0; i < nOfAccounts; i++) {
            accounts[i].print();
            Out.println("--------------------------------");
        }
        Out.format("Bilanzsumme: %.2f%n", getBalance());
        Out.println("--------------------------------");
    }

    // ... Rest of the code
}
英文:

I have this class Account

    import java.io.IllegalArgumentException;

    class Account {
	    final int accountNo;
	    final Customer owner;
	    final double overdraft;

	    double balance = 0;

	    private Account(int accountNo, Customer owner, double overdraft) {
		    this.accountNo = accountNo;
		    this.owner = owner;
		    this.overdraft = overdraft;
	    }

	    void print() {
		    Out.println(&quot;Kontonummer: &quot; + accountNo);
		    owner.print();
		    Out.format(&quot;Kontostand: %.2f%n&#220;berziehungsrahmen: %.2f%n&quot;, balance, overdraft);
	    }

	    public boolean deposit(double amount) throws IllegalArgumentException {
		    if (amount &lt;= 0) {
			    throws new IllegalArgumentException(&quot;Cannot deposit negative amounts!&quot;);
			    break;
		    } else {
			    balance += amount;
			    return true;
		    }

		    public boolean withdraw(double amount) throws OverdraftLimitReachedException {
			    if (amount &lt;= 0 || !isCovered(amount)) {
				    throw new OverdraftLimitReachedException(&quot;Overdraft limit has been reached&quot;, accountNo);
				    break;
			    } else {
				    balance -= amount;
				    return true;
			    }

			    boolean isCovered(double amount) {
				    return amount - overdraft &lt;= balance;
			    }

			    boolean transfer(Account target, double amount) {
				    boolean success = withdraw(amount);
				    if (!success) return false;

				    target.deposit(amount);
				    return true;
			    }
		    }
        }
    }

Now I also have this exception that I wrote

    public class NoSuchAccountException extends AccountException {

	    public NoSuchAccountException(int accountNo) {
		    super(message, accountNo);
	    }
    }

Now I need to throw this exception in the class account,when the searched account number does not exist.Now my question is in which method(or function I think that is the same,please correct me if I'm wrong) do I throw this exception.And after what check.How would I check if the account number exist,and if it doesnt I'll throw this exception. Thank you!

EDIT: The class banking, to complete the program

class Banking {
static final int CAPACITY = 100;
final Account[] accounts = new Account[CAPACITY];
int nOfAccounts = 0;
int createAccount(String firstName, String lastName, String phone, double overdraft) {
if (nOfAccounts == CAPACITY) return -1;
// use nOfAccounts as accountNo and index to array
Customer owner = new Customer(firstName, lastName, phone);
Account account = new Account(nOfAccounts, owner, overdraft);
accounts[nOfAccounts] = account;
nOfAccounts++;
return account.accountNo;
}
boolean deposit(int accountNo, double amount) {
if (accountNo &lt; 0 || accountNo &gt;= nOfAccounts) return false;
Account account = accounts[accountNo];
return account.deposit(amount);
}
boolean withdraw(int accountNo, double amount) {
if (accountNo &lt; 0 || accountNo &gt;= nOfAccounts) return false;
Account account = accounts[accountNo];
return account.withdraw(amount);
}
boolean transfer(int fromNo, int toNo, double amount) {
if (fromNo &lt; 0 || toNo &lt; 0 ||
fromNo &gt;= nOfAccounts || toNo &gt;= nOfAccounts) return false;
Account from = accounts[fromNo];
Account to = accounts[toNo];
return from.transfer(to, amount);
}
double getBalance(int accountNo) {
if (accountNo &lt; 0 || accountNo &gt;= nOfAccounts) return 0;
Account account = accounts[accountNo];
return account.balance;
}
double getBalance() {
double sum = 0;
for (int i = 0; i &lt; nOfAccounts; i++) {
sum += accounts[i].balance;
}
return sum;
}
void print() {
Out.println(&quot;---------- Bankauszug ----------&quot;);
for (int i = 0; i &lt; nOfAccounts; i++) {
accounts[i].print();
Out.println(&quot;--------------------------------&quot;);
}
Out.format(&quot;Bilanzsumme: %.2f%n&quot;, getBalance());
Out.println(&quot;--------------------------------&quot;);
}
// --------------------- Optionaler Teil ---------------------
public static void main(String[] args) {
Banking banking = new Banking();
char op;
do {
printMenu();
op = readOperation();
switch (op) {
case &#39;a&#39;: {
printTitle(&quot;Konto anlegen&quot;);
String firstName = getString(&quot;Vorname&quot;);
String lastName = getString(&quot;Nachname&quot;);
String phone = getString(&quot;Telefonnummer&quot;);
double overdraft = getDouble(&quot;&#220;berziehungsrahmen&quot;);
int accountNo = banking.createAccount(
firstName, lastName, phone, overdraft);
printMessage(&quot;Anlegen von Konto &quot; + accountNo, accountNo != -1);
break;
}
case &#39;e&#39;: {
printTitle(&quot;Einzahlen&quot;);
int accountNo = getInt(&quot;Kontonummer&quot;);
double amount = getDouble(&quot;Einzahlungsbetrag&quot;);
boolean success = banking.deposit(accountNo, amount);
printMessage(&quot;Einzahlen&quot;, success);
break;
}
case &#39;b&#39;: {
printTitle(&quot;Abheben&quot;);
int accountNo = getInt(&quot;Kontonummer&quot;);
double amount = getDouble(&quot;Abhebungsbetrag&quot;);
boolean success = banking.withdraw(accountNo, amount);
printMessage(&quot;Abheben&quot;, success);
break;
}
case &#39;t&#39;: {
printTitle(&quot;&#220;berweisen&quot;);
int fromNo = getInt(&quot;Von Kontonummer&quot;);
int toNo = getInt(&quot;Auf Kontonummer&quot;);
double amount = getDouble(&quot;Betrag&quot;);
boolean success = banking.transfer(fromNo, toNo, amount);
printMessage(&quot;&#220;berweisen&quot;, success);
break;
}
case &#39;d&#39;:
banking.print();
break;
case &#39;q&#39;:
Out.println(&quot;Beenden&quot;);
break;
default:
Out.println(&quot;Ung&#252;ltige Operation&quot;);
break;
}
} while(op != &#39;q&#39;);
}
static void printMenu() {
Out.println();
Out.println(&quot;*********** Bankverwaltung ********&quot;);
Out.println(&quot;Konto anlegen ................... a&quot;);
Out.println(&quot;Einzahlen ....................... e&quot;);
Out.println(&quot;Beheben ......................... b&quot;);
Out.println(&quot;&#220;berweisen ...................... t&quot;);
Out.println(&quot;&#220;bersicht drucken ............... d&quot;);
Out.println(&quot;Beenden ......................... q&quot;);
Out.print(&quot;Welche Menuoption? [a|e|b|t|d|q]: &quot;);
}
static char readOperation() {
char ch = Character.toLowerCase(In.readChar());
In.readLine();
return ch;
}
static void printTitle(String text) {
Out.println(&quot;*** &quot; + text + &quot; ***&quot;);
}
static String getString(String text) {
Out.print(text + &quot;: &quot;);
return In.readLine();
}
static double getDouble(String text) {
Out.print(text + &quot;: &quot;);
return In.readDouble();
}
static int getInt(String text) {
Out.print(text + &quot;: &quot;);
return In.readInt();
}
static void printMessage(String operation, boolean success) {
String message = success ?
operation + &quot; erfolgreich durchgef&#252;hrt&quot; :
&quot;Ung&#252;ltige Operation&quot;;
Out.println(message);
}
}

答案1

得分: 1

这取决于您创建的接口。您当前在代码中有一个接口,在该接口中,如果未找到帐户或其他操作失败,您会返回false。这种错误处理方式有其优点和缺点。其中一个潜在的脆弱性是方法的调用者可能会忘记检查返回代码,这对于这种情况可能非常不利(调用者首先尝试取出一些钱,但失败了,然后将钱存入另一个帐户,从无处创造了资金)。

关于这个问题有赞成和反对的观点。处理错误的另一种替代方式是抛出异常,而不是返回布尔值进行错误处理 - 这种方式也有其优点和缺点。在Java中,如果确保它是一个受检异常,调用者将被强制捕获或抛出异常作为类型系统的一部分。无论如何,我不确定是否要混合处理错误的这两种方式,因为这可能非常容易出错和令人困惑。

如果您采用异常处理错误的方式,一个常见的重构可能是创建一个名为checkOrThrowAccountMustExist的私有方法,该方法以帐户ID作为输入,如果帐户不存在则抛出异常。

还有一个问题是是否将检查放在Banking类和/或Account类中。我个人的感觉是,至少在这两个类中包含一些检查可能是有意义的,并且在那些对外部或程序的其他部分公开的类中包含检查可能是一个好主意(如果某个类不打算在程序的一个小部分之外使用,则进行文档记录)。但这可能超出了您的任务范围。

英文:

It depends on the interface you create. You currently have an interface in your code where you return false if the account is not found or something other fails. That kind of error handling has benefits and drawbacks. One way that is potentially fragile is that the caller of the method(s) might forget to check the return code, which could be potentially very bad for this case (the caller first attempts to withdraw some money, which fails, and then deposits money into another account, creating money out of nowhere).

There are arguments for and against. An alternative way of doing error handling would be to throw exceptions instead of returning a boolean for error handling - that would have its own benefits and drawbacks. In Java, if you ensure it is a checked exception, the caller would be forced to catch or throw the exception as part of the type system. In any case, I don't know how I feel about mixing the two ways of handling errors, since that might be very error prone and confusing.

If you go along with the exception way of handling errors, one common refactoring might be to have a private method called checkOrThrowAccountMustExist, that takes an account ID as input and throws if it does not exist.

There is also the issue of whether to place the checks in the Banking class and/or in the Account class. My own feeling would be that it may make sense to include at least some checks in both, and that it would be a good idea to include checks in those classes that are exposed externally or to other parts of your program (and document if a class is not meant to be used outside a small part of your program). But this may or may not be outside the scope of your assignment.

答案2

得分: 0

我猜你有一个名为Bank(或类似的)的类,客户前来执行与他的钱有关的操作。所以他给你一个账户号码、一个任务,还可能是一定金额的钱。
这个类会需要一个账户的数组或列表。这个类中的方法将是你的异常的正确位置。然后你会有一些方法,基本上和你的账户中的方法相同。它们首先会检查数组/列表中是否存在该账户,然后在选定的账户上调用方法,或者如果账户不存在则抛出异常。

方法 vs 函数:
在我理解中,方法和函数是相同的,除了一个小小的区别:函数是在全局空间中的函数,而方法是绑定到类或对象的函数。因此,Java没有真正的函数。但在我看来,每个静态方法都是一个函数,只不过它绑定在类的命名空间中。但这更多是一个实际的观点,而不是理论上的。

英文:

I'd guess you have a class Bank or the like and a customer comes to do something with his money. So he gives you an account number, a task and maybe an amount of money.
This class would need an Array or List of Accounts. The methods in this class would be thew right place for your Exception. You than have methods, basically the same as in your account. They first check if the Account exists in the array / list and then call the method on the chosen account or throw the exception if it doesn't exist.

method vs function:
In my understanding methods and functions are the same except for one little difference: a function is a function in global space, whereas a method is a function bound to a class or an object. Thus Java doesn't have real functions. But in my understanding, every static method is a function, but bound to the namespace of a class. But that is more a practical than a theoretical point of view.

答案3

得分: 0

提取获取账户的通用位置

private Account getAccount(int accountNo) {
  if (accountNo >= accounts.length || accounts[accountNo] == null) {
    throw new NoSuchAccountException();
  }
  return accounts[accountNo];
}

boolean deposit(int accountNo, double amount) {
  Account account = getAccount(accountNo);
  return account.deposit(amount);
}
英文:

Extract the common place for acquiring the account

private Acount getAccount(accountNo) {
if (accountNo &gt;= accounts.length || accounts[accountNo] == null) {
throw new NoSuchAccountException();
}
return account;
}
boolean deposit(int accountNo, double amount) {
Account account = getAccount(accountNo);
return account.deposit(amount);
}

答案4

得分: 0

在账户类中创建一个方法,该方法接受账户号码,如果账户存在则返回true,否则返回false。您可以在存款或取款方法中调用此方法,只有在它返回true时才继续,否则抛出NoSuchAccountException异常。

英文:

Create a method in account class which accepts account number and return true if account is present otherwise false. You can call this method from deposit or withdraw methods and proceed only when it returns true otherwise throw NoSuchAccountException.

huangapple
  • 本文由 发表于 2020年5月30日 21:11:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/62102927.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定