Java Exam Quick Revision Guide
Java Exam Quick Revision Guide
The 'final' keyword in Java denotes a non-changeable entity, be it a variable, method, or class. A final variable cannot have its value reassigned, enhancing reliability by preventing accidental modification. A final method cannot be overridden, ensuring the intended behavior is preserved in derived classes. A final class cannot be subclassed, which improves security and performance, as the JVM takes certain optimization liberties knowing that classes won't change at runtime .
Java's exception handling features, including try-catch-finally blocks and the use of throw and throws keywords, allow developers to manage and respond to exceptions gracefully rather than crashing the application. The try-catch block enables the capture and handling of exceptions that occur during runtime, while finally ensures the execution of code regardless of whether an exception is thrown. The throw keyword allows manual exception initiation, and throws declares potential exceptions in method signatures, promoting robust programming by enforcing error acknowledgment and management at all levels .
A Java thread goes through several life cycle stages: New, Runnable, Running, Blocked, and Dead. A thread begins in the New state, transitions to Runnable after the start method is invoked, enters Running when the thread scheduler picks it, and can become Blocked if it waits for resources. It terminates in the Dead state after execution completes. Synchronization in Java multithreading is crucial for preventing thread interference and consistency problems, ensuring that only one thread can access critical code sections at a time, thus avoiding data corruption during concurrent operations .
In Java, single inheritance allows a class to inherit from only one superclass, promoting code reuse and simplicity. Multilevel inheritance involves a chain of inheritance; a class derives from a class that is itself derived from another. Hierarchical inheritance occurs when multiple classes derive from a single base class, promoting shared functionality. Practically, single inheritance is common in class extension, multilevel is seen in class hierarchies like Animal -> Mammal -> Dog, and hierarchical in scenarios like a database model where multiple entities share a common interface or functionality .
The StringBuffer class in Java is preferred over the regular String class when frequent modifications to a string's content are necessary, such as appending or inserting characters. Since String objects are immutable, each modification results in the creation of a new object, leading to increased overhead and memory footprint. StringBuffer, being mutable, allows in-place modifications, which enhances performance significantly in scenarios involving heavy string manipulations by reducing the need for temporary object creation .
Encapsulation in Java is implemented using access modifiers: private, protected, and public. By declaring class variables as private and providing public getter and setter methods, Java restricts unauthorized access and misuse, safeguarding the object's state from external entities. This not only hides the internal implementation details but also enhances maintainability and flexibility as the internal workings can change without affecting external interactions, thereby enforcing a clean separation between a class's interface and its implementation .
Widening type casting in Java, also known as implicit casting, occurs automatically when a smaller data type is converted into a larger data type (e.g., int to float). It's safe and doesn't cause data loss. Narrowing type casting, or explicit casting, requires a programmer's intervention to convert a larger data type into a smaller one (e.g., double to int), which can lead to data loss and precision reduction. Widening is common when arithmetic operations are performed on variables of different types, while narrowing is used when data from a larger type needs to fit into a smaller storage .
Interfaces in Java are used to achieve abstraction and multiple inheritance. They can only contain abstract methods (prior to Java 8), but from Java 8 onwards, they can also have default and static methods. Abstract classes, on the other hand, can include both abstract and concrete methods, allowing more flexible method implementations within subclasses. This distinction influences developers to use interfaces when they need classes to implement common behavior across various unrelated class hierarchies, while abstract classes are preferred when closely related classes require a common base with shared but incomplete functionality .
The equals() method and the '==' operator serve distinct purposes in string comparison within Java. The equals() method evaluates the content of the strings for equality, making it the standard method for logical string comparison. Conversely, the '==' operator compares whether two references point to the same memory location. Therefore, while '==' might return true for string literals pooled by the JVM, it's unsuitable for consistent content comparison. equals() is essential when comparing dynamically created strings or ensuring logical equality irrespective of object references .
Java ensures robust and platform-independent code execution through its use of the Java Virtual Machine (JVM), which converts bytecode into machine code specific to the underlying hardware. This bytecode runs consistently across all platforms with a compatible JVM, making Java inherently platform-independent. The robustness comes from features like exception handling and strong memory management, reducing the risk of crashes and data corruption .