0% found this document useful (0 votes)
12 views11 pages

Java Exception Handling Lab Tasks

The document contains a series of Java programming tasks focused on exception handling, including file operations, arithmetic operations, bank account simulations, network connections, and complex nested try-catch structures. Each task includes specific requirements for handling exceptions, using custom exceptions, and ensuring proper resource management with finally blocks. The provided code snippets demonstrate the implementation of these tasks along with the expected outputs.

Uploaded by

mu468032
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views11 pages

Java Exception Handling Lab Tasks

The document contains a series of Java programming tasks focused on exception handling, including file operations, arithmetic operations, bank account simulations, network connections, and complex nested try-catch structures. Each task includes specific requirements for handling exceptions, using custom exceptions, and ensuring proper resource management with finally blocks. The provided code snippets demonstrate the implementation of these tasks along with the expected outputs.

Uploaded by

mu468032
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

National University of Technology

Computer Science Department


Program : Software Engineering
Course : SCDA

Lab 06

Submitted To: Submitted By:


Lec. Momina Mir Taha Mehmood
F23608003
Task 1:
File Handling with Multiple Exceptions
Create a Java program that reads a file specified by the user. Handle the following exceptions:
1. FileNotFoundException - if the file does not exist
2. IOException - for other file reading errors
3. SecurityException - if the program doesn't have permission to read the file
Use a finally block to ensure that the file is closed properly, even if an exception occurs. Add a
message in the finally block indicating whether the file was closed successfully or if there was
an issue closing it.

Code :

package lab6_scd;
import [Link].*;
import [Link];

public class FileReaderWithExceptions {


public static void main(String[] args) {
Scanner scanner = new Scanner([Link]);
[Link]("Enter the file path: ");
String filePath = [Link]();
[Link]();

FileReader fileReader = null;


BufferedReader bufferedReader = null;

try {
fileReader = new FileReader(filePath);
bufferedReader = new BufferedReader(fileReader);
String line;
[Link]("File content:");
while ((line = [Link]()) != null) {
[Link](line);
}
} catch (FileNotFoundException e) {
[Link]("Error: The file was not found.");
} catch (IOException e) {
[Link]("Error: An I/O error occurred while reading the file.");
} catch (SecurityException e) {
[Link]("Error: Permission denied to read the file.");
} finally {
try {
if (bufferedReader != null) {
[Link]();
[Link]("BufferedReader closed successfully.");
}
if (fileReader != null) {
[Link]();
[Link]("FileReader closed successfully.");
}
} catch (IOException e) {
[Link]("Error: Failed to close the file properly.");
}
}
}
}

Output:

Task 2:
Arithmetic Operations with Custom Exception
Create a Java program that performs division of two numbers entered by the user. Implement
the following:
1. Handle ArithmeticException for division by zero
2. Create a custom exception InvalidInputException for negative numbers
3. Use a finally block to display a message indicating the completion of the operation

Code :
package lab6_scd;
import [Link];

// Custom exception for invalid input (negative numbers)


class InvalidInputException extends Exception {
public InvalidInputException(String message) {
super(message);
}
}
public class task2 {
public static void main(String[] args) {
Scanner scanner = new Scanner([Link]);

try {
[Link]("Enter numerator: ");
int numerator = [Link]();

[Link]("Enter denominator: ");


int denominator = [Link]();

// Check for negative numbers


if (numerator < 0 || denominator < 0) {
throw new InvalidInputException("Negative numbers are not allowed.");
}

// Perform division
int result = numerator / denominator;
[Link]("Result: " + result);

} catch (ArithmeticException e) {
[Link]("Error: Division by zero is not allowed.");
} catch (InvalidInputException e) {
[Link]("Error: " + [Link]());
} finally {
[Link]("Operation completed.");
[Link]();
}
}
}

Output:
Task 3:
Bank Account Operations
Create a Java program that simulates bank account operations. Implement the following:
1. Handle IllegalArgumentException for invalid account numbers
2. Handle InsufficientFundsException (custom exception) for withdrawal amounts
exceeding balance
3. Use nested try-catch blocks for different operations (deposit, withdrawal, balance
check)
4. Implement a finally block that logs the transaction details to a file

Code :
package lab6_scd;

import [Link];
import [Link];
import [Link];

// Custom exception for insufficient funds


class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}

class BankAccount {
private String accountNumber;
private double balance;

public BankAccount(String accountNumber, double initialBalance) {


if (![Link]("taha1234")) {
throw new IllegalArgumentException("Invalid account number. It should be 6-12 digits long.");
}
[Link] = accountNumber;
[Link] = initialBalance;
}

public void deposit(double amount) {


if (amount <= 0) {
throw new IllegalArgumentException("Deposit amount must be positive.");
}
balance += amount;
[Link]("Deposited: " + amount);
}

public void withdraw(double amount) throws InsufficientFundsException {


if (amount > balance) {
throw new InsufficientFundsException("Insufficient balance for withdrawal.");
}
balance -= amount;
[Link]("Withdrawn: " + amount);
}

public void checkBalance() {


[Link]("Current balance: " + balance);
}

public String getTransactionDetails() {


return "Account: " + accountNumber + ", Balance: " + balance;
}
}

public class task3 {


public static void main(String[] args) {
Scanner scanner = new Scanner([Link]);
BankAccount account = null;

try {
[Link]("Enter account number: ");
String accountNumber = [Link]();
account = new BankAccount(accountNumber, 1000.0); // Initial balance

[Link]("Enter amount to deposit: ");


double depositAmount = [Link]();
[Link](depositAmount);

try {
[Link]("Enter amount to withdraw: ");
double withdrawAmount = [Link]();
[Link](withdrawAmount);
} catch (InsufficientFundsException e) {
[Link]("Error: " + [Link]());
}

[Link]();
} catch (IllegalArgumentException e) {
[Link]("Error: " + [Link]());
} finally {
try (FileWriter writer = new FileWriter("[Link]", true)) {
if (account != null) {
[Link]([Link]() + "\n");
[Link]("Transaction logged successfully.");
}
} catch (IOException e) {
[Link]("Error logging transaction: " + [Link]());
}
[Link]();
}
}
}

Output:

Task 4:
Network Connection Simulation
Create a Java program that simulates connecting to a network resource. Implement the
following:
1. Handle UnknownHostException for invalid host names
2. Handle SocketTimeoutException for connection timeouts
3. Use a finally block to close the connection properly, even if an exception occurs
4. Implement a custom exception ConnectionFailedException for other connection-related
Issues

Code :
package lab6_scd;
import [Link].*;
import [Link].*;
import [Link];

// Custom exception for connection failure


class ConnectionFailedException extends Exception {
public ConnectionFailedException(String message) {
super(message);
}
}

public class NetworkConnectionSimulation {

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


Scanner scanner = new Scanner([Link]);
Socket socket = null;

try {
[Link]("Enter the host name (e.g., [Link]): ");
String hostName = [Link]();
[Link]("Enter the port number: ");
int port = [Link]();

// Simulate connecting to the network resource


socket = new Socket();
[Link](new InetSocketAddress(hostName, port), 5000); // Timeout set to
5000ms

[Link]("Successfully connected to the host: " + hostName);

} catch (UnknownHostException e) {
[Link]("Error: Unknown host. The provided host name is invalid or
unreachable.");
} catch (SocketTimeoutException e) {
[Link]("Error: Connection timed out. Unable to connect within the
specified time.");
} catch (IOException e) {
[Link]("Error: An IO error occurred while trying to connect to the
network.");
} finally {
// Ensure the socket connection is properly closed
try {
if (socket != null && ![Link]()) {
[Link]();
[Link]("Connection closed.");
}
} catch (IOException e) {
[Link]("Error while closing the connection: " + [Link]());
}

// Close the scanner to prevent resource leak


[Link]();
}
}
}

Output:

Task 5:
Complex Nested Try-Catch Structure
Create a Java program that demonstrates a complex nested try-catch structure with multiple
finally blocks. The program should:
1. Have at least three levels of nested try-catch blocks
2. Handle different types of exceptions at different levels
3. Include finally blocks at each level that perform different cleanup operations
4. Demonstrate how exceptions propagate through different levels
5. Show how finally blocks execute even when exceptions are thrown

Code :
package lab6_scd;
import [Link].*;

public class ComplexNestedTryCatch {

public static void main(String[] args) {


// Simulate different levels of exception handling and finally blocks
try {
[Link]("Outer try block (Level 1)");

try {
[Link](" Inner try block (Level 2)");

try {
[Link](" Innermost try block (Level 3)");

// Simulate an arithmetic exception


int result = 10 / 0; // This will throw ArithmeticException

} catch (ArithmeticException e) {
[Link](" Caught ArithmeticException in Level 3: " + [Link]());
throw new NullPointerException("Simulating a NullPointerException after catching
ArithmeticException");
} finally {
[Link](" Finally block of Level 3: Performing cleanup tasks.");
}

} catch (NullPointerException e) {
[Link](" Caught NullPointerException in Level 2: " + [Link]());
throw new IOException("Simulating IOException after catching NullPointerException");
} finally {
[Link](" Finally block of Level 2: Performing other cleanup tasks.");
}

} catch (IOException e) {
[Link]("Caught IOException in Level 1: " + [Link]());
} finally {
[Link]("Finally block of Level 1: Final cleanup tasks.");
}
}
}
Output:

Common questions

Powered by AI

Standardizing exceptions across application modules streamlines error handling by establishing a common vocabulary and response paradigm for different error scenarios, leading to consistency and predictability in behavior. This improves maintainability, as developers can rely on familiar exception types and handling patterns when traversing different parts of the application. Furthermore, it promotes reuse of error handling logic and reduces redundancy, facilitating easier integration and management of components. Standardized exceptions also aid in creating consistent logs and reports, enhancing diagnostic capabilities and aiding in comprehensive system audits .

The InvalidInputException is a custom exception designed to handle specific invalid scenarios, specifically the input of negative numbers, which are not allowed for division operations in this context. This exception provides a more descriptive and tailored error message for invalid inputs compared to a standard ArithmeticException, which is used to handle mathematical errors like division by zero. By using a custom exception, the program can distinctly identify and communicate different problems encountered during operation .

The custom ConnectionFailedException enhances error handling by allowing developers to specifically capture and manage instances where network connection issues occur that are not covered by standard exceptions. It provides a means to define and handle a broader range of network-related problems, potentially improving diagnostics and offering more context-specific responses, thus enhancing the overall reliability of the application in diverse connectivity scenarios .

Implementing a finally block to log transaction details ensures that transaction logging occurs regardless of whether an exception is thrown or not. This guarantees that transaction details are consistently recorded, aiding in maintaining an audit trail for the operations conducted, thus enhancing accountability and traceability. This feature is critical in financial applications where tracking the flow of funds is necessary. By utilizing the finally block, the system provides a robust structure that supports critical logging even in the face of errors, thereby preserving data integrity .

The simulation addresses UnknownHostException for invalid host names, SocketTimeoutException for connection timeouts, and IOException for general network I/O issues. Managing these exceptions is crucial because network connections are prone to diverse failure scenarios, and improper handling can cause the application to crash or behave unpredictably. Effective error management ensures that such failures are gracefully handled and informative messages are provided to users, which aids in diagnosing problems and enhances the robustness of the application's network interaction capabilities .

The Java program handles file operation exceptions using three catch blocks that specifically manage FileNotFoundException, IOException, and SecurityException. Each type of exception is handled uniquely to inform the user about what went wrong during the file reading process. The 'finally' block is beneficial as it ensures resources are released properly, in this case, closing the file readers to prevent resource leakage even if an error occurs during execution. This helps maintain system stability and prevents memory leaks .

In a complex nested try-catch structure, finally blocks serve the purpose of executing cleanup code that should be run regardless of whether exceptions occur, such as resource deallocation. The finally blocks execute in reverse order of nesting, ensuring local cleanup is completed before moving onto higher levels. This stacking means that resources are cleaned at each respective level before control returns, reducing resource leaks during exception propagation. Furthermore, the assurance of finally blocks executing aids in systematic resource management and helps ensure that any side-effects of exceptions don't impact subsequent operations .

The program uses nested try-catch blocks to separately manage multiple transactional operations such as deposits and withdrawals, thus enabling the handling of specific exceptions at each transaction level. For example, an IllegalArgumentException is caught when an invalid account number is entered or when a negative deposit amount is detected. Similarly, an InsufficientFundsException is caught specifically during the withdraw operation. This design allows for granular control and management of different failure scenarios, ensuring that any exception does not affect the other operations and that each problem is communicated to the user clearly. The nested structure also facilitates logging of transaction details through a 'finally' block .

Throwing new exceptions within a catch block allows for exception transformation, enabling the program to communicate errors at an appropriate abstraction level. This technique aids in catching specific lower-level exceptions and re-throwing them as higher-level exceptions that might be more meaningful in the broader context of the application. It effectively propagates exceptions, maintaining a clear flow of error information up the call hierarchy, while still allowing for localized error handling and cleanup through finally blocks .

Custom exceptions like InsufficientFundsException provide significant advantages in applications such as a bank account simulation by offering precise mechanisms to handle domain-specific errors. They enhance code readability and maintenance, allowing developers to capture specific error conditions uniquely associated with business logic, such as withdrawal limits being exceeded, which standard exceptions cannot express. This targeted approach improves error handling precision, facilitates debugging by clearly distinguishing between general errors and application-specific anomalies, and enables providing users with clearer, more actionable feedback tailored to specific scenarios in financial processes .

You might also like