1.
Why are Java programs assumed to be Robust, Architectural-neutral and
Dynamic?
Java programs are considered robust, architectural-neutral, and dynamic due to several powerful
features built into the language. Java is robust because it emphasizes early error detection, strong
memory management, and exception handling. The absence of pointers reduces the chances of
memory corruption, and automatic garbage collection ensures efficient memory utilization.
Architectural neutrality comes from Java’s bytecode system. Java source code is compiled into
platform-independent bytecode, which can be executed by the Java Virtual Machine (JVM) on any
operating system. This “write once, run anywhere” capability eliminates platform dependency. Java
is dynamic because it supports runtime linking of classes and dynamic loading of libraries. The JVM
can load classes on demand during execution, making Java programs highly flexible. Reflection
and the ability to modify behavior at runtime add to Java’s dynamic nature. Moreover, Java
supports dynamic memory allocation, ensuring efficient and adaptable program execution. These
factors together make Java a robust, neutral, and dynamic programming language widely used for
reliable and scalable applications.
2. What is Java Runtime Environment (JRE)? How is it different from Java
Development Kit (JDK)?
Java Runtime Environment (JRE) is the environment required to run Java programs. It includes the
Java Virtual Machine (JVM), core libraries, and supporting files necessary for Java application
execution. The JRE does not contain development tools; it only allows users to run precompiled
Java applications. In contrast, the Java Development Kit (JDK) is a complete software development
package that includes the JRE along with essential tools such as the Java compiler (javac),
debugger, documentation generator (javadoc), and other utilities required for developing Java
applications. The JDK is used by developers to write, compile, and debug Java programs, while the
JRE is used by end users to run Java applications. In simple terms, JDK = JRE + development
tools. JRE focuses only on execution, whereas JDK focuses on both development and execution.
JVM, included inside the JRE, converts Java bytecode into machine code, ensuring platform
independence. Thus, JDK is essential for programmers, while JRE is sufficient for running Java
applications.
3. Compare Java Abstract class and Interface in terms of fields, methods,
inheritance and root.
An abstract class in Java can contain both abstract and non-abstract methods, whereas an
interface traditionally contained only abstract methods, though newer versions of Java allow default
and static methods. In abstract classes, fields can be non-final and non-static, while interfaces
contain only public static final variables by default. Abstract classes support single inheritance,
meaning a class can extend only one abstract class. Interfaces allow multiple inheritance because
a class can implement multiple interfaces. Abstract classes can contain constructors, but interfaces
cannot. When considering design, an abstract class is chosen when classes share a common base
with partial implementation. Interfaces, however, define a common contract for unrelated classes.
The root of an abstract class is inheritance-based, whereas the root of an interface is
implementation-based. Interfaces provide better abstraction for designing loosely coupled systems.
For example, an abstract class Shape may contain implemented methods like area(), while the
interface Drawable may only declare draw() to be implemented by multiple unrelated classes. Thus,
abstract classes focus on partial implementation, while interfaces focus on behavior abstraction.
4. Can we Overload or Override static methods in Java? Explain with
examples.
In Java, static methods belong to the class rather than an instance. They cannot be overridden
because method overriding is based on dynamic binding at runtime, while static methods use static
binding at compile time. Therefore, overriding a static method is not allowed. However, static
methods can be overloaded because method overloading depends on the number and type of
parameters, not on runtime behavior. For example: class A { static void show(int x) {} }; class B
extends A { static void show(String s) {} }; Here, show() is overloaded, not overridden. If a subclass
declares a static method with the same signature as in the parent class, it hides the parent method
rather than overriding it. This concept is known as method hiding. Therefore, static methods can be
overloaded but not overridden. Overloading provides compile-time polymorphism, while overriding
requires dynamic dispatch, which static methods do not support. Hence, Java restricts overriding of
static methods but fully supports overloading them to allow flexibility.
5. Write a program to print Fibonacci series using Recursive Methods.
A Fibonacci series is a sequence where each number is the sum of the previous two numbers.
Using recursion, a function calls itself to compute the next number in the series. In Java, a recursive
function can be defined to compute the nth Fibonacci number. A sample program is: class
Fibonacci { static int fib(int n) { if(n <= 1) return n; return fib(n-1) + fib(n-2); } public static void
main(String[] args) { int n = 10; for(int i = 0; i < n; i++) [Link](fib(i) + " "); } }. Recursion
divides the task into smaller subproblems, making the code simple and readable. However,
recursive Fibonacci can be slow due to repeated calculations. Despite this, recursion is widely used
to demonstrate mathematical sequences. The base condition ensures termination. This method
shows how Java handles recursive calls using stack frames. Thus, printing Fibonacci numbers
using recursion is a classic example of functional logic in Java programming.
6. How to create a user-defined package? Explain using a simple example.
A user-defined package in Java helps organize classes into structured groups. Packages provide
modularity, reusability, and prevent naming conflicts. To create a user-defined package, we first
declare the package name at the top of the Java file. For example: package mypack; public class
Hello { public void display() { [Link]("Hello from package!"); } }. This file must be placed
in a folder named mypack. After compiling with: javac -d . [Link] the package directory is
created automatically, storing the class file. To use this package in another program: import
[Link]; class Test { public static void main(String[] args) { Hello h = new Hello(); [Link](); }
}. Packages allow better project management and grouping of related classes. They also support
access protection and hierarchical structure in large applications. Thus, creating user-defined
packages makes Java programs more organized and maintainable.
7. Explain about Exception Propagation.
Exception propagation refers to the process where an exception moves up the call stack until it is
caught by a matching catch block. When a method throws an exception and does not handle it
internally, the exception is passed to the calling method. If the calling method also does not handle
it, the exception continues to propagate upward. This continues until a handler is found or the
program terminates. For example: void m1() { int x = 10/0; } void m2() { m1(); } void m3() { try { m2();
} catch(Exception e) { [Link]("Handled"); } }. Here, the exception occurs in m1(), moves
to m2(), then m3(), and is finally caught in m3(). Java supports unchecked exception propagation
for RuntimeException. Checked exceptions must be either caught or declared using throws.
Propagation ensures that exceptions reach an appropriate handler. This mechanism allows
separation of exception-handling logic from core business logic. Thus, exception propagation is an
important feature of Java’s robust error-handling model.
8. Differentiate among String, StringBuilder and StringBuffer.
String, StringBuilder, and StringBuffer differ mainly in mutability and thread safety. A String is
immutable, meaning once created, its value cannot change. Any modification creates a new object,
which can lead to memory overhead in repeated operations. StringBuilder is mutable and allows
modification without creating new objects. It is faster and preferred for string concatenation in
single-threaded programs. StringBuffer is also mutable but thread-safe because its methods are
synchronized. This makes it slower than StringBuilder but safer in multithreaded environments. For
example, String s = "Hello" creates an immutable object. StringBuilder sb = new
StringBuilder("Hello"); [Link]("World"); modifies the same object. StringBuffer works similarly
but ensures thread safety. Therefore, use String when immutability is desired, StringBuilder for
high-performance modifications, and StringBuffer for thread-safe operations. These three classes
offer flexibility depending on performance and concurrency needs.
9. Explain the thread life cycle in Java.
A thread in Java goes through several stages in its life cycle. The first stage is New, where the
thread is created but not yet started. When the start() method is called, the thread enters the
Runnable state, where it is ready to run but waiting for CPU scheduling. When the thread scheduler
picks it, the thread enters the Running state and executes its run() method. During execution, the
thread may enter the Blocked or Waiting states if it needs resources or waits for another thread. It
may also enter Timed Waiting if it is paused for a specific time using sleep() or wait(timeout). After
completing its execution, the thread enters the Terminated state, where it cannot be restarted.
These stages ensure organized and predictable thread behavior. Understanding the life cycle helps
in developing multithreaded programs and synchronizing shared resources effectively.
10. Write a program in Java to read two integers and print their sum using
Scanner class.
A Java program to read two integers and print their sum using the Scanner class is simple. The
Scanner class from [Link] package allows reading user input. Example: import [Link].*; class
Sum { public static void main(String[] args) { Scanner sc = new Scanner([Link]);
[Link]("Enter two numbers:"); int a = [Link](); int b = [Link](); int sum = a + b;
[Link]("Sum = " + sum); } }. The program first creates a Scanner object. It reads two
integers using nextInt() and stores them in variables. Then, it calculates their sum and prints the
result. Scanner simplifies input handling for console-based programs. It supports reading different
data types and makes interactive programs easier to build. Closing the scanner after use is good
practice. This program demonstrates basic input-output operations and user interaction in Java
applications.