← Back to list

Java Interview Cheatsheet: Basic (Class, Object, Variables, Methods, Modifiers)

This Java Interview Cheatsheet provides a concise yet comprehensive overview of fundamental Java concepts, suitable for beginners preparing…

Wensen Ma · 2024-02-06 02:05 · 58 claps · 24.3 min read
#java #java-interview-questions #java-interview #javainterviewtips
Open on Medium ↗

Java Interview Cheatsheet: Basic (Class, Object, Variables, Methods, Modifiers)

This Java Interview Cheatsheet provides a concise yet comprehensive overview of fundamental Java concepts, suitable for beginners preparing for interviews or professionals needing a quick refresher. It covers critical areas including JDK, JRE, JVM distinctions, Java’s portability, garbage collection mechanisms, class and object basics, constructors, and the Object class. Each section is structured to build understanding from foundational principles to more complex topics, ensuring a holistic grasp of Java programming.

JDK, JRE, JVM

Can you explain the differences between JDK, JRE, and JVM?

The JDK (Java Development Kit) is the full suite for Java developers, including the JRE (Java Runtime Environment), compilers, and development tools. The JRE is what you need to run Java applications; it includes the JVM (Java Virtual Machine) but not the development tools. The JVM executes Java bytecode and provides a platform-independent environment for Java applications, abstracting away the underlying hardware and OS.

Why is Java considered portable?

Java’s portability stems from its “write once, run anywhere” philosophy. Programs are compiled to bytecode, which the JVM can execute on any platform. This eliminates the need for platform-specific code, making Java applications platform-independent.

What role does the JVM play in Java’s architecture?

The JVM is central to Java’s architecture, ensuring platform independence by abstracting the application from the hardware. It executes bytecode, enabling Java programs to run on any device with a JVM, embodying the “write once, run anywhere” principle.

How does the JVM enhance the security of Java applications?

The JVM boosts Java security by verifying bytecode compliance with Java rules, managing access via a security manager, and preventing memory leaks through garbage collection, ensuring safe, stable applications.

Garbage Collection

What is the Java Garbage Collection?

Java garbage collection is an automatic memory management process in the Java Virtual Machine (JVM). It identifies and discards objects no longer used by a program, freeing up memory and preventing memory leaks. It’s a critical feature that allows Java programs to avoid the manual allocation and de-allocation of memory.

How does Java Garbage Collection work?

Java garbage collection works automatically without the need for explicit programmer intervention. The JVM implements the garbage collection process, which involves identifying objects no longer referenced by the program, marking them for deletion, and then deleting them. It can also compact the heap by moving the remaining objects to make space allocation more efficient for new objects.

What are the various steps during the Garbage Collection?

The garbage collection process typically involves three steps: Identifying and marking unreferenced objects as ready for garbage collection and deleting these marked objects to reclaim memory space. Third, optionally compacting the heap by rearranging the remaining objects into a contiguous block optimizes memory allocation for new objects.

How does the Generational Garbage Collection Strategy work?

In generational garbage collection, objects are categorized based on age since different age groups tend to have different survival rates. Younger objects are more likely to become unreachable quickly and are allocated to the younger generation. Objects that survive multiple garbage collection cycles in the Young Generation are then moved to the Old Generation, where garbage collection occurs less frequently. This strategy enhances efficiency by focusing on areas of the heap where garbage collection is most likely to find unreferenced objects.

What are the different classifications of objects by the Garbage Collector?

The heap in Java is typically divided into three sections for garbage collection purposes:

  1. Young Generation: For newly created objects. It’s subdivided into an Eden space and two Survivor spaces.
  2. Old Generation: For objects that have existed longer in the heap.
  3. Permanent Generation (or Metaspace in newer versions of Java): This stores metadata such as class and method objects.

6. What are the different types of Garbage Collectors in HotSpot JVM?

The HotSpot JVM offers four main types of garbage collectors:

  1. Serial Garbage Collector: Uses a single thread for garbage collection, suitable for single-threaded applications.
  2. Parallel Garbage Collector: Utilizes multiple threads for garbage collection in the Young Generation and usually single-threaded in the Old Generation, ideal for multi-threaded applications.
  3. CMS (Concurrent Mark Sweep): Uses multiple threads and aims to minimize application pause times by performing most of its work concurrently with the application.
  4. G1 (Garbage First): A more modern, parallel, and concurrent collector suitable for applications with large heaps, focusing on predictable pause times.

7. What triggers Garbage Collection?

Several events can trigger garbage collection:

  1. Allocation Failure: When there’s not enough space in the heap to allocate a new object.
  2. Heap Size Thresholds: When the heap usage reaches a specific threshold.
  3. System.GC () Call: A hint to the JVM to initiate garbage collection, though it’s not a guaranteed trigger.
  4. Time-Based Triggers: Some algorithms, like G1, use time-based conditions to initiate garbage collection.

Class and Object Concept

What is a class and an object in Java?

A class in Java is a template or blueprint that defines the structure and behavior of objects, including their attributes (fields) and methods. An object is an instance of a class, representing a specific element with actual values for those attributes and the ability to execute the methods defined in the class. Essentially, if a class is a design, an object is a realization of that design.

How does Java load a class?

In Java, class loading is a process that occurs in three stages:

  1. Loading: The JVM reads the class file from its source and brings it into the runtime environment.
  2. Linking: Verifies the loaded class file, prepares it by allocating memory for class variables and resolving symbolic references within the class.
  3. Initialization: Executes any static initializers and static initialization blocks, setting initial values for static fields.

This process is triggered the first time a class is referenced in the program, ensuring that each class is loaded only once.

How are objects initialized in Java?

Objects in Java are initialized through constructors, which are special methods in the class that have the same name as the class itself. Constructors are called when an object is created using the new keyword and are used to set initial values for object attributes. If no constructor is explicitly defined in a class, Java automatically provides a default constructor that initializes objects with default values (null for objects, 0 for numeric types, false for boolean, etc.). Additionally, initialization blocks can be used within the class to perform more complex initialization tasks.

Object Initialization Flow Using the ‘new’ Keyword in Java

  1. Class Loading: If the class of the object isn’t already loaded, the JVM loads it into memory, converting the .class file into a Class object.
  2. Memory Allocation: Memory for the new object is allocated in the heap, sufficient to store all its instance variables.
  3. Default Initialization: Instance variables are set to their default values (e.g., 0 for numeric types, false for booleans, null for object references).
  4. Initialization Blocks: If it’s the class’s first load, static blocks are executed. Instance initialization blocks run before the constructor.
  5. Constructor Execution: The constructor matching the provided arguments initializes instance variables with specific values or performs other tasks.
  6. Object Reference Returned: After constructor completion, the memory address of the object is returned to be assigned to a reference variable, making the object ready for use.
  7. Garbage Collection Eligibility: The object remains in memory as long as it’s reachable. It becomes eligible for garbage collection once there are no more references to it.
  8. JVM Optimizations: Throughout this process, the JVM may apply optimizations to enhance performance.

This flow ensures that objects are properly initialized and managed within the JVM, promoting efficient memory use and application performance.

Can you explain the difference between the static and instance variables?

Static variables are class-level variables shared across all instances of a class, initialized when the class is loaded into the JVM. Instance variables are specific to each object instance, initialized whenever a new object is created. Static variables hold common data for the class, while instance variables hold data specific to each object.

Class Constructor

What is a constructor in Java?

A constructor in Java is a special method used to initialize new objects. It has the same name as the class and is called at the time of object creation. Constructors can be overloaded to allow different ways of initializing an object’s state. They do not have a return type, not even void.

Can you differentiate between a default constructor and a parameterized constructor?

A default constructor is provided by Java if no constructors are explicitly defined in a class; it has no parameters and initializes objects with default values. A parameterized constructor is defined by the programmer with one or more parameters, allowing for initializing objects with specific values.

Explain constructor overloading in Java.

Constructor overloading in Java is the practice of having multiple constructors within the same class, each having a different parameter list. This allows objects of the class to be initialized in different ways, providing flexibility in setting initial values for the object’s attributes based on the provided arguments. The JVM differentiates between these constructors based on the number and type of parameters.

How do you implement copy constructors in Java?

In Java, a copy constructor is implemented by defining a constructor that takes an instance of the class itself as a parameter. This constructor copies the properties of the passed object to the new object being created, allowing for an exact clone of the object’s state.

What is constructor chaining?

Constructor chaining in Java is the process of calling one constructor from another within the same class or across parent and child classes using this() and super() respectively. This allows for efficient code reuse and sequential initialization.

Is it possible to make a constructor private? If yes, give a scenario where it might be useful.

Yes, constructors in Java can be made private. This is useful in scenarios like implementing the Singleton pattern, where you want to restrict the instantiation of a class to a single object. A private constructor prevents the creation of class instances from outside the class, ensuring controlled access through a static method within the class that returns the instance.

Can a constructor call another constructor of the same class? How?

Yes, a constructor can call another constructor of the same class using this() with the appropriate parameters. This is known as constructor chaining and allows for code reuse among constructors within the same class. The this() call must be the first statement in the constructor.

Object Class

Why is the Object class considered the root of the Java class hierarchy?

The Object class is considered the root of the Java class hierarchy because it is the superclass of all other classes in Java. Every class in Java implicitly extends the Object class if it does not explicitly extend another class, making Object the ultimate parent class for all Java classes. This provides a common set of methods, such as equals(), hashCode(), and toString(), that are available to every object in Java.

Can you explain the significance of the equals() and hashCode() methods in Java?

The equals() and hashCode() methods in Java are fundamental to the use of objects as keys in hash-based collections like HashMap and HashSet. The equals() method determines if two objects are equivalent in terms of their state. The hashCode() method returns an integer representation of the object's memory address or a custom value that represents the object's state. For effective use in hash-based collections, if two objects are considered equal by the equals() method, they must also have the same hashCode() value. This ensures that objects are correctly located and retrieved from collections based on their content rather than their memory addresses.

Discuss the importance of the clone() method. How do you make an object cloneable?

The clone() method in Java is used to create a copy of an existing object. Its importance lies in its ability to duplicate an object's state without needing to know its specific type or the details of its construction, offering a convenient way to achieve object duplication.

To make an object cloneable, a class must:

  1. Implement the Cloneable interface. This interface is a marker interface (with no methods) that indicates to the Object.clone() method that it is legal for the object to make a field-for-field copy of instances of that class.
  2. Override the clone() method from the Object class. This method must be declared public (since the original clone() method in the Object class is protected) and can use super.clone() to obtain the cloned object.

Here’s an example:

public class Example implements Cloneable {
    private int data;

    // Constructor
    public Example(int data) {
        this.data = data;
    }

    // Overriding clone() method
    @Override
    public Example clone() throws CloneNotSupportedException {
        // Call clone in Object.
        return (Example) super.clone();
    }
}

In this example, Example class implements the Cloneable interface and overrides the clone() method to enable cloning. Not implementing Cloneable and attempting to clone an object will result in a CloneNotSupportedException being thrown. Making an object cloneable and properly overriding the clone() method allows for the duplication of objects, which is particularly useful in scenarios where creating a new instance and setting its properties manually would be cumbersome or inefficient.

What is the purpose of the finalize() method? When is it called?

The finalize() method in Java is used for cleanup just before an object is garbage collected. It's called by the Garbage Collector on an object when no more references to the object exist. However, its use is discouraged in newer Java versions due to unpredictability and potential issues with performance.

Explain the difference between == operator and equals() method in Java.

In Java, the == operator compares object references, checking if two references point to the same object in memory. The equals() method compares the values within two objects for equality. By default, equals() behaves like == but can be overridden in a class to compare object states instead.

What happens if you override the hashCode() method? Why is it important to override hashCode() when overriding equals()?

When you override the hashCode() method in Java, you ensure that objects that are considered equal by the equals() method also have the same hash code. This is important for maintaining consistency in collections that use hashing, like HashMap and HashSet. Overriding hashCode() when overriding equals() ensures that equal objects are placed in the same bucket in hash-based collections, allowing for correct storage and retrieval based on object content.

Java Data Types and Variables

What are the different types of variables in Java?

In Java, variables are primarily classified into three types based on their scope and usage context:

  1. Local Variables: These are declared within methods, constructors, or blocks and are only accessible within their declaring block of code. Local variables are created when the block is entered and destroyed upon exit, requiring initialization before use.
  2. Instance Variables (Non-static Fields): Defined without the static keyword, these variables are unique to each instance of a class. They are declared within a class but outside any method and are initialized when a new instance of the class is created. Instance variables can have different values for each object instance.
  3. Static Variables (Class Variables): Declared with the static modifier, these variables are shared among all instances of a class. They are initialized when the class is loaded by the JVM. Static variables are used to store common data shared by all instances of the class and can be accessed directly with the class name.

What are the memory sizes of primitive data types and reference types in Java?

In Java, the memory sizes of primitive data types are fixed, whereas the memory size of reference types depends on the JVM implementation. Here’s a brief overview:

Primitive Data Types:

  1. byte: 8 bits (1 byte)
  2. short: 16 bits (2 bytes)
  3. int: 32 bits (4 bytes)
  4. long: 64 bits (8 bytes)
  5. float: 32 bits (4 bytes)
  6. double: 64 bits (8 bytes)
  7. char: 16 bits (2 bytes)
  8. boolean: JVM-specific (not precisely defined in the Java specification, commonly 1 byte for practical JVM implementations)

Reference Types:

  • Reference (Object Reference): The size depends on the JVM architecture:
  • 32-bit JVM: typically 4 bytes per reference.
  • 64-bit JVM: typically 8 bytes per reference, but this can be reduced to 4 bytes with compressed pointers (a feature in many JVMs).
  • Objects and Arrays: The total memory usage includes the object’s overhead (commonly 12 bytes in a 32-bit JVM or 16 bytes in a 64-bit JVM with uncompressed pointers) plus the size of its fields (primitives + references) and padding to a multiple of 8 bytes.

What are the main differences between primitive and wrapper data types in Java?

Primitive data types in Java are basic types (e.g., int, float, char, boolean) that store simple values directly. They are not objects and therefore cannot call methods. Wrapper data types (e.g., Integer, Float, Character, Boolean) are classes that encapsulate a primitive value in an object, allowing primitives to be used in contexts requiring objects, like in collections. Wrapper classes provide methods to manipulate these values, and support null values, unlike primitives.

Why would you use a wrapper class over a primitive type?

You would use a wrapper class over a primitive type to utilize Java’s object-oriented features, such as being able to call methods on the value, to store null values as a valid state (which primitives cannot represent), and to use them in collections like ArrayList that can only hold objects, not primitives. Wrapper classes also provide utility methods for converting, comparing, and processing values.

How does autoboxing and unboxing work in Java?

Autoboxing in Java automatically converts primitive types into their corresponding wrapper class objects, while unboxing does the opposite, converting wrapper class objects back into their equivalent primitive types. This process simplifies coding by allowing seamless integration between primitives and objects

What are the types of references in Java, and how do they differ?

In Java, there are four types of references, each with a different level of strength and purpose:

  1. Strong Reference: The default type. An object with a strong reference cannot be garbage collected as long as the reference exists.
  2. Soft Reference: Softly-referenced objects are cleared at the discretion of the garbage collector, typically when memory is needed. Useful for caches that can be reclaimed but should stay as long as possible.
  3. Weak Reference: Weakly-referenced objects are more aggressively reclaimed by the garbage collector than soft references. Once the only references to an object are weak references, it can be garbage collected. Useful for metadata or cache entries that should not prevent garbage collection.
  4. Phantom Reference: The weakest reference type, used to determine exactly when an object was removed from memory. It cannot be used to retrieve the object, making it useful for pre-cleanup actions or to avoid resurrection of objects during finalization.

Each type serves different purposes, particularly in contexts of memory sensitivity and object lifecycle management.

How can different reference types be used in memory management and caching strategies?

Different reference types in Java can be strategically used in memory management and caching strategies as follows:

  • Strong References are used for essential objects that must remain in memory. However, they’re not suitable for caching since they prevent garbage collection.
  • Soft References are ideal for caches that can afford to be cleared under memory pressure. The JVM clears soft references before throwing an OutOfMemoryError, making them useful for memory-sensitive caches.
  • Weak References are suitable for caches where entries can be collected more aggressively. Once an object only has weak references, it can be garbage collected anytime, making this approach useful for non-critical cache data that should not prevent its keys or values from being reclaimed.
  • Phantom References are mainly used for scheduling pre-cleanup actions before an object is collected. They are not directly used for caching but can help manage resources, such as releasing native resources when an object is about to be collected.

Using these reference types allows for more flexible and efficient memory management, enabling the creation of caches that automatically adjust to the JVM’s memory needs.

Can you explain the lifecycle of local and instance variables?

The lifecycle of local and instance variables in Java differs based on their scope and allocation:

  • Instance Variables: Their lifecycle begins when an object is instantiated and ends when the object is garbage collected. Instance variables are tied to the lifecycle of the object they belong to, meaning they remain in memory as long as their parent object exists.
  • Local Variables: Their lifecycle starts when their containing block or method is entered and ends when it is exited. Local variables are stored on the stack and are automatically destroyed once the execution flow exits the block or method where they are defined.

Instance variables are used to store the state of an object, while local variables are temporary and used within blocks or methods to perform operations.

How are instance and local variables initialized, and what are their default values?

Instance variables are automatically initialized with default values if not explicitly initialized (e.g., 0 for numeric types, false for boolean, null for object references). Local variables are not automatically initialized and must be explicitly initialized before use; otherwise, the compiler will throw an error.

Can a static method access instance variables directly? Why or why not?

No, a static method cannot directly access instance variables because static methods belong to the class, not to any particular instance. Instance variables are tied to specific objects, so without a reference to an object, static methods cannot access them. Static methods can only access static variables and methods directly.

Explain the concept of a static block in Java. What is its purpose?

A static block in Java, defined using static { ... }, is a block of code that gets executed when the class is first loaded into the JVM. Its purpose is to perform static initializations, typically initializing static variables or executing a static setup process before any objects of the class are created or any static methods are called. Static blocks are executed only once, at the time of class loading.

What are the limitations or disadvantages of using static methods or variables in Java?

Using static methods or variables in Java has several limitations or disadvantages:

  1. Lack of Object Orientation: Static methods and variables belong to the class level, making them less suitable for object-oriented programming where behavior is supposed to be encapsulated within objects.
  2. Testing Challenges: Static methods can make testing harder, as they cannot be overridden in subclasses, complicating the mocking process.
  3. Global State: Static variables maintain a global state, leading to issues with data consistency and concurrency in multi-threaded environments.
  4. Memory Management: Static variables stay in memory as long as their class stays loaded, which could lead to memory leaks if not carefully managed.
  5. Inflexibility: Static methods cannot access instance methods or variables directly, limiting their use to operations that do not require object state.

Methods

List all Object class methods with their purpose

The Object class in Java provides the foundation for all other classes and objects. Here are its methods and their purposes:

  1. clone() - Creates and returns a copy of this object.
  2. equals(Object obj) - Determines whether another object is "equal to" this one.
  3. finalize() - Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. Its use is discouraged in new applications.
  4. getClass() - Gets the runtime class of this object.
  5. hashCode() - Returns a hash code value for the object, used in hashing-based collections like HashMap.
  6. notify() - Wakes up a single thread that is waiting on this object's monitor.
  7. notifyAll() - Wakes up all threads that are waiting on this object's monitor.
  8. toString() - Returns a string representation of the object, typically including the class name and hash code or other object-specific information.
  9. wait() - Causes the current thread to wait until another thread invokes notify() or notifyAll() on this object, or a specified amount of time has elapsed. There are three overloaded versions of wait().
  10. wait(long timeout) - Causes the current thread to wait until either another thread invokes notify() or notifyAll() on this object, or a specified amount of time has elapsed.
  11. wait(long timeout, int nanos) - Causes the current thread to wait until another thread invokes notify() or notifyAll() on this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.

These methods provide essential mechanisms for object lifecycle management, thread coordination, and fundamental object behaviors in Java.

What is method overloading and how does it differ from method overriding?

Method overloading occurs when multiple methods in the same class have the same name but different parameter lists, allowing different implementations based on the number or type of arguments passed. Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. Overloading is about polymorphism at compile time, while overriding is about runtime polymorphism, enabling dynamic method dispatch.

Can you overload a method with the same return type but different argument types in Java?

Yes, you can overload a method in Java with the same return type but different argument types. Method overloading means having multiple methods with the same name but different parameter lists (types, number, or order of parameters) within the same class. The return type can be the same or different; it is the parameters that distinguish overloaded methods.

What rules must be followed when overriding a method in a subclass?

When overriding a method in a subclass in Java, the following rules must be followed:

  1. Method Signature: The overriding method must have the same name and parameter list as the method in the superclass.
  2. Return Type: The return type of the overriding method must be the same as or a subtype of the return type declared in the original overridden method in the superclass.
  3. Access Level: The access level of the overriding method cannot be more restrictive than the overridden method. For example, if the superclass method is protected, the overriding method can be protected or public, but not private.
  4. Final Method: You cannot override a method marked as final in the superclass.
  5. Static Methods: Static methods cannot be overridden. If you declare a static method in the subclass with the same signature as a static method in the superclass, it is considered method hiding, not overriding.
  6. Abstract Methods: If a subclass extends an abstract class, it must override all abstract methods of the superclass unless the subclass is also declared abstract.
  7. Exceptions: The overriding method can throw the same, narrower (subclass), or no exceptions, but it cannot throw broader (checked) exceptions than the overridden method.
  8. Invocation of Superclass Method: The overriding method can call the overridden method in the superclass using the super keyword.

Explain the use of the @Override annotation.

The @Override annotation in Java is used to indicate that a method is intended to override a method in a superclass or implement an abstract method from an interface. Its use helps with two main aspects:

  1. Compile-Time Checking: It allows the compiler to verify that the annotated method indeed overrides or implements a method from a superclass or interface, respectively. If the method does not correctly override a superclass method (e.g., due to a mismatch in the method signature), the compiler will generate an error.
  2. Code Readability: It makes the code more readable and understandable by clearly indicating the developer’s intent to override a method, making it easier for others to understand the code’s behavior.

Using @Override improves code safety and maintainability by catching common errors at compile time, such as typos in method names or incorrect method signatures.

Can methods be overloaded by changing the return type in Java?

No, methods in Java cannot be overloaded solely by changing the return type. Overloading requires a change in the parameter list (types, number, or order of parameters). If two methods have the same name and parameter list but different return types, it will result in a compilation error.

Explain how Java passes arguments to methods (pass-by-value vs. pass-by-reference).

Java always passes arguments to methods by value. This means it copies the value of an argument into the method’s parameter. For primitive types, the method receives a copy of the primitive value. For objects, the method receives a copy of the reference to the object, not the object itself. Changes to primitives in the method do not affect the original value, while modifications to the object’s attributes via the reference copy can affect the original object since both references point to the same object in memory. However, reassigning the object reference in the method does not change the original reference outside the method.

What happens to the object references passed to methods?

When object references are passed to methods in Java, a copy of the reference is passed, not the actual object. This means the method operates on the same object that the reference points to, allowing changes to the object’s attributes to affect the original object. However, reassigning the reference to a new object within the method does not affect the original reference outside the method.

Discuss the effect of method argument changes on primitive types vs. objects.

When method arguments are primitive types, changes made to them within the method do not affect the original values outside the method, because Java passes primitive types by value, creating a copy of the value for method use.

For objects, the method receives a copy of the reference to the object. Any modifications to the object’s properties through this reference will affect the original object outside the method, because both the original reference and the copied reference point to the same object in memory. However, reassigning the object reference to a new object within the method does not change the original reference.

Differentiate between formal and actual parameters in Java methods.

In Java methods, formal parameters (or formal arguments) are the variables defined by the method that receive values when the method is called. They are placeholders within the method definition that specify the type and name of the data the method expects to receive.

Actual parameters (or actual arguments) are the real values or variables passed to the method when it is called. These values are used to initialize the method’s formal parameters.

The key difference is in their usage context: formal parameters are used in the method declaration to define what type of arguments the method can accept, while actual parameters are the specific values or references passed to the method during a call.

Impact of Access Modifiers on Java Methods and Variables

Access modifiers in Java determine the visibility and accessibility of classes, methods, and variables within different parts of a program. The impact of using different access modifiers is as follows:

  • public: Methods and variables are accessible from any other class in the Java application, facilitating interface exposure and interaction between different parts of a program.
  • protected: Methods and variables are accessible within the same package and by subclasses, allowing for controlled inheritance and package-level interaction while protecting from external access.
  • default (no modifier): Methods and variables are accessible only within classes in the same package, supporting package cohesion by limiting visibility outside the package.
  • private: Methods and variables are accessible only within the declaring class, encapsulating and hiding implementation details from other classes, even within the same package.

Using these modifiers correctly is crucial for encapsulation, security, and designing a robust and maintainable Java application.

Utilizing the ‘final’ Keyword in Java

The final keyword in Java has several uses, impacting the behavior of classes, methods, and variables:

  • Final Classes: When applied to a class, final prevents the class from being subclassed. This is useful for enhancing security and ensuring immutability.
  • Final Methods: A method marked as final cannot be overridden by subclasses. This is beneficial for locking down the implementation of a method to prevent alteration by extending classes, ensuring consistent behavior.
  • Final Variables: For variables, final makes them constants, meaning that once they are initialized, their value cannot be changed. This applies to both member variables and local variables and is critical for creating immutable objects and thread-safe instances that don't change state.

Utilizing final can lead to safer, more reliable code by making intentions clear and enforcing immutability where appropriate.

Understanding Static Methods and Variables in Java

Static methods and variables in Java belong to the class rather than any instance of the class, making them shared among all instances.

  • Static Variables: Also known as class variables, they are initialized when the class is loaded into the JVM and destroyed when the program ends. They are used for values that are constant or common across all instances, like a counter to track the number of objects created from a class.
  • Static Methods: These methods can be called without creating an instance of the class. They cannot access instance variables or methods directly and are often used for utility or helper functions that don’t require object state.

Static members are useful for implementing class-level data management and methods that do not require data from instance variables to perform their tasks, promoting a form of functionality that’s accessible without the need to instantiate a class.

Usage of ‘this’ and ‘super’ Keywords in Java

In Java, this and super keywords have distinct roles in object-oriented programming:

  • this Keyword: Refers to the current instance of the class. It's used to access instance variables, methods, and constructors within the same class. this is useful for distinguishing between class fields and parameters with the same name, and for calling one constructor from another within the same class.
  • super Keyword: Refers to the superclass (parent class) of the current instance. super is used to access or call superclass's methods and constructors. It allows subclasses to access methods of their superclass that have been overridden, and to call superclass constructors from a subclass.

Both keywords facilitate clear inheritance hierarchies and class architectures by managing scope and relationships between classes and their instances.

Exploring Varargs in Java

Varargs (Variable Arguments) in Java allow a method to accept zero or more arguments of the same type as input when called, providing flexibility in the number of arguments a method can receive. Implemented with the syntax type... name, varargs enable methods to handle an undefined number of arguments, internally treating them as an array of the specified type. This feature simplifies method creation that requires variable numbers of parameters, making code more readable and maintainable.

Operators

Explain the difference between the == operator and the .equals() method in Java.

In Java, the == operator compares the memory addresses of objects, checking if two references point to the same object, while the .equals() method compares the values within two objects for equality. By default, .equals() behaves like == for objects unless overridden in a class to compare object states, making it suitable for logical equality checks. For primitive types, == compares their actual values.

How does the instanceof operator work, and when would you use it?

The instanceof operator in Java checks if a given object is an instance of a specific class or interface, or any of its subclasses. It returns true if the object is an instance of the specified type, false otherwise. Use instanceof when you need to verify the type of an object at runtime, especially before casting it to a specific class to avoid ClassCastException, or to implement type-specific behavior.

What are the differences between the bitwise operators (&, |, ^) and the logical operators (&&, ||) in Java?

In Java, bitwise operators (&, |, ^) and logical operators (&&, ||) serve different purposes:

Bitwise Operators: Operate on individual bits of integer types (int, long, short, char, byte).

  • & (AND) sets each bit to 1 if both bits are 1.
  • | (OR) sets each bit to 1 if at least one of the bits is 1.
  • ^ (XOR) sets each bit to 1 if only one of the two bits is 1.

Logical Operators: Operate on boolean values.

  • && (AND) results in true if both operands are true; otherwise, it is false. It short-circuits, meaning the second operand is not evaluated if the first is false.
  • || (OR) results in true if at least one operand is true; otherwise, it is false. It also short-circuits, meaning the second operand is not evaluated if the first is true.

Bitwise operators are used for manipulating individual bits, performing bit-level operations, while logical operators are used for conditional expressions, evaluating to true or false.

What does the >>> operator do, and how does it differ from the >> operator?

The >>> operator in Java is the unsigned right shift operator, which shifts the bits of the operand to the right, filling the leftmost bits with zeros, regardless of the sign. It does not consider the sign bit, making it suitable for unsigned binary shift operations.

The >> operator is the signed right shift operator, which shifts the bits of the operand to the right. The leftmost bits are filled based on the sign bit of the original number, preserving the sign of the operand. If the number is positive, zeros are used as fillers; if negative, ones are used.

The key difference is how they handle the sign bit: >>> treats the number as unsigned, while >> maintains the sign of the number.

Advanced

Boxing and Unboxing in Java

Boxing in Java is the automatic conversion of a primitive type into its corresponding wrapper class object (e.g., converting an int to an Integer). Unboxing is the reverse process, where a wrapper class object is converted back into its corresponding primitive type (e.g., converting an Integer to an int). These processes allow primitive types to be used as objects when needed, such as in collections that require objects.

Utilizing the ‘final’ Keyword in Java

In Java, the final keyword is used to declare constants, prevent method overriding, and prohibit class inheritance. When applied to variables, final makes them immutable once they're initialized. For methods, it prevents them from being overridden in subclasses. For classes, it prevents them from being extended.


메타데이터
post_id
af78cfe4d82f
slug
java-interview-cheatsheet-basic-class-and-object-af78cfe4d82f
url
https://medium.com/@wensenma/java-interview-cheatsheet-basic-class-and-object-af78cfe4d82f
canonical_url
https://medium.com/@wensenma/java-interview-cheatsheet-basic-class-and-object-af78cfe4d82f
author_url
https://medium.com/@wensenma
status
ok
fetched_at
2026-07-24 11:33:09