Document From Bujji
Document From Bujji
Part-A
1.Explain how command line arguments work in Java.
Command line arguments in Java provide a way to pass information to your program when
it's launched. This data can be accessed within your Java application and used to modify its
behavior.
args: The main method in Java has a parameter String[] args, which holds the
command-line arguments.
args.length: This gives the number of arguments passed.
Looping through args: You can iterate over the args array to process each argument
individually.
Definition: Declared with the static keyword within a class but outside any method or
constructor.
Memory Allocation: Allocated once per class, shared among all instances of the class.
Access: Can be accessed directly using the class name without creating an instance.
For example, ClassName.staticVariable.
Use Case: Used for constants or data that is common to all instances (e.g., a counter
for the number of objects created from a class).
Instance Variables
Definition: Declared inside a class but outside any method, constructor, or block,
without the static keyword.
Memory Allocation: Allocated each time a new instance of the class is created.
Access: Accessed through objects; each object has its own copy of the instance
variable. For example, objectName.instanceVariable.
Use Case: Used for data that is unique to each instance of the class (e.g., attributes
like name, age, etc. for an Employee class).
3.What is the difference between = and == in Java
The difference between = and == in Java is essential to understand for avoiding common
pitfalls in coding:
= (Assignment Operator)
Purpose: Used to assign a value to a variable.
Example:
int a = 10; // Assigns the value 10 to the variable a
Usage: Assigns the value on the right to the variable on the left.
== (Equality Operator)
Purpose: Used to compare two values for equality.
Example:
int a = 10;
int b = 10;
if (a == b) {
System.out.println("a and b are equal");
}
Usage: Checks if the two operands on either side are equal.
PART:B
1.What are the key principles of Object-Oriented Programming? Explain each briefly.
Answer:
Object means a real world entity such as pen, chair, table etc.Object-Oriented
Programming is a methodology or paradigm to design a program using classes and
objects. It simplifies the software development and maintenance by providing some
concepts:
o Object
o Class
o Inheritance
o Polymorphism
o Abstraction
o Encapsulation
Object:
Example: A dog is an object because it has states like colour, name, breed, etc. as well as
behaviours like wagging the tail, barking, eating, etc.
Class:
Inheritance:
Polymorphism:
Encapsulation:
A java class is the example of encapsulation. JavaBeans is the fully encapsulated class
because all the data members are private here.
1. Arithmetic Operators
Used for basic mathematical operations.
Addition (+):
int a = 5;
int b = 3;
int sum = a + b; // sum is 8
Subtraction (-):
int diff = a - b; // diff is 2
Multiplication (*):
int product = a * b; // product is 15
Division (/):
int quotient = a / b; // quotient is 1
Modulus (%):
int remainder = a % b; // remainder is 2
2. Relational Operators
Used for comparison between two values.
Equal to (==):
boolean isEqual = (a == b); // isEqual is false
Not equal to (!=):
boolean isNotEqual = (a != b); // isNotEqual is true
Greater than (>):
boolean isGreater = (a > b); // isGreater is true
Less than (<):
boolean isLess = (a < b); // isLess is false
Greater than or equal to (>=):
boolean isGreaterOrEqual = (a >= b); // isGreaterOrEqual is true
Syntax:
int max = (a > b) ? a : b; // max is 5
These are the foundational operators in Java that you'll use to manipulate data and control
the flow of your programs.
3.a.What are the different data types available in Java? Classify them into primitive
and non-primitive types.
Datatype specifies the size and types of values that a variable hold.Java is rich in it’s data
types.
Primitive Data Types: A primitive data type specifies the size and type of variable values,
andithas no additional methods.
Thereareeight primitivedatatypesinJava:
Note1:Note that you should end the value of float with an "f"
Note2:Note that you should end the value of double with a"d"
Example:
Intnum =5;
float num1 = 5.99f;
double num3=5.7896d;
Charch='D';
boolean status = true;
Stringname="sai";
System.out.println("Value inside integer type variable " + num);System.out.println("Value
inside float type variable " + num1);
System.out.println("Value inside double type variable " +
num1);System.out.println("Value inside character type variable " +
ch);System.out.println("Value inside boolean type variable " +
status);System.out.println("Valueinsidestring typevariable"+name);
Non-PrimitiveDataTypes:
Non-primitivedatatypesarecalledreference types becausetheyrefertoobjects.
Themaindifferencebetween primitiveandnon-primitivedatatypesare:
1. Primitive types are predefined (already defined) in Java. Non-primitive
types are created by the programmer and is not defined by Java
(exceptforString).
2. Non-primitive types can be used to call methods to perform certain
operations,whileprimitivetypes cannot.
3. A primitivetype has always a value,while non-primitive types can be
null.
4. A primitive type starts with a lowercase letter, while non-primitive
typesstartswith an uppercaseletter.
5. The size of a primitive type depends on the data type, while non-
primitivetypeshaveall the samesize.
Example:
String greet = "Hello World";
System.out.println(greet);
Example:
int num = 100;
double doubleNum = num; // Implicit casting from int to double
System.out.println("Double value: " + doubleNum); // Outputs: 100.0
Key Differences:
Implicit Casting:
No need for explicit conversion.
Happens automatically when converting a smaller data type to a larger one.
Safe and no data loss.
Explicit Casting:
Requires explicit conversion using the cast operator.
Happens when converting a larger data type to a smaller one.
Potential for data loss.
The scope of a variable refers to the region of the code where the variable is accessible and
can be used. The scope of a variable is determined by where the variable is declared. Java
has several types of variable scopes, including:
A local variable is declared within a method, constructor, or block (such as an `if` statement
or a loop). Its scope is limited to the block in which it is declared.
Local variables are accessible only within the method, constructor, or block where they are
defined. Once the method or block exits, the local variable is no longer accessible, and its
memory is reclaimed.
Example:
public void myMethod() {
int localVar = 10; // local variable
if (localVar > 5) {
int blockVar = 20; // local variable within an if block
System.out.println(blockVar);
}
// System.out.println(blockVar); // Error: blockVar cannot be resolved
}
An instance variable is declared inside a class but outside of any method, constructor, or
block. It is associated with an instance of the class (i.e., an object).
Instance variables are accessible to all methods, constructors, and blocks within the class.
They can be accessed directly by other methods of the same instance or using the object
reference.
Example:
public class MyClass {
private int instanceVar; // instance variable
public void setInstanceVar(int value) {
this.instanceVar = value; // Accessing instance variable
}
public int getInstanceVar() {
return this.instanceVar; // Accessing instance variable
}
}
3. Class Variable Scope:
A class variable, also known as a static variable, is declared with the `static` keyword inside
a class but outside of any method, constructor, or block. It is shared among all instances of
the class.
Class variables are accessible to all methods, constructors, and blocks within the class. They
can also be accessed directly using the class name.
Example:
public class MyClass {
public static int classVar; // class variable
Example:
public void myMethod(int param) { // param is a parameter variable
System.out.println(param); // Accessing parameter variable
}
- Access Modifiers: The scope also interacts with access modifiers (`public`, `protected`,
`private`, and package-private) that control the visibility of class members outside their
class.
Understanding variable scope is crucial for managing data access and ensuring that variables
are used correctly within their intended context in Java.
5.
a. Discuss the operator precedence and associativity in java with examples
The operator precedence represents how two expressions are bind together. In an
expression, it determines the grouping of operators with operands and decides how an
expression will evaluate.
While solving an expression two things must be kept in mind the first is a precedence and
the second is associativity.
Precedence
Precedence is the priority for grouping different types of operators with their operands. It is
meaningful only if an expression has more than one operator with higher or lower
precedence. The operators having higher precedence are evaluated first. If we want to
evaluate lower precedence operators first, we must group operands by using parentheses and
then evaluate.
Advertisement
Associativity
We must follow associativity if an expression has more than two operators of the same
precedence. In such a case, an expression can be solved either left-to-right or right-to-
left, accordingly.
() Parentheses
15 [] Array subscript Left to Right
· Member selection
++ Unary post-increment
14 Right to left
-- Unary post-decrement
++ Unary pre-increment
-- Unary pre-decrement
+ Unary plus
13 - Unary minus Right to left
! Unary logical negation
~ Unary bitwise complement
(type) Unary type cast
* Multiplication
12 / Division Left to right
% Modulus
+ Addition
11 Left to right
- Subtraction
== Relational is equal to
8 Left to right
!= Relational is not equal to
= Assignment
+= Addition assignment
-= Subtraction assignment
1 Right to left
*= Multiplication assignment
/= Division assignment
%= Modulus assignment
1. 1 + 5 * 3
You might be thinking that the answer would be 18 but not so. Because the multiplication (*)
operator has higher precedence than the addition (+) operator. Hence, the expression first
evaluates 5*3 and then evaluates the remaining expression i.e. 1+15. Therefore, the answer
will be 16.
2. x + y * z / k
In the above expression, * and / operations are performed before + because of precedence. y
is multiplied by z before it is divided by k because of associativity.
b) Describe the role of the static keyword in Java? Explain with an example
program.
The static keyword in Java is used to indicate that a particular member (variable, method, or
nested class) belongs to the class itself, rather than instances of the class. Here's the
breakdown:
Static Variables
Role: Shared among all instances of a class. If one instance modifies the static
variable, the change is reflected across all instances.
Use Case: Often used for constants or to keep track of state shared by all objects.
Static Methods
Role: Can be called without creating an instance of the class. Typically used for utility
or helper methods that don't depend on instance variables.
Use Case: Useful for operations that don't require any data from an instance of the
class.
Static Blocks
Role: Used for static initialization of a class. Executed when the class is loaded.
Use Case: Often used for initializing static variables.
Example Program
Here's an example that demonstrates the use of static variables and methods:
Explanation:
Static Variable: count is shared among all instances of StaticExample. Since it is
static, we can access it using the class name.
Static Method: incrementCount() modifies the static variable count. We call it directly
using the class name.
Example:
int i = 0;
do {
System.out.println("Iteration " + i);
i++;
} while (i < 5);
4. for-each Loop
The for-each loop is used to iterate over elements in an array or a collection.
Syntax:
for (type element : array/collection) {
// code to be executed
}
Example:
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
System.out.println("Number: " + num);
}
Key Differences:
7.
a.Differentiate the primitive data types and wrapper classes in Java.
In Java, primitive data types and wrapper classes serve different purposes and have distinct
characteristics. Here’s a detailed explanation of their differences:
1. Definition: Primitive data types are the basic data types provided by Java. They are not
objects and are used to store simple values.
2. Types: Java has eight primitive data types:
- `byte` (8-bit integer)
- `short` (16-bit integer)
- `int` (32-bit integer)
- `long` (64-bit integer)
- `float` (32-bit floating-point)
- `double` (64-bit floating-point)
- `char` (16-bit Unicode character)
- `boolean` (true or false)
3. Characteristics:
- Efficiency: Primitive types are more efficient in terms of memory and performance since
they are stored directly in memory locations and do not involve the overhead of objects.
- Default Values: Each primitive type has a default value (e.g., `0` for numeric types,
`false` for `boolean`, and `'\u0000'` for `char`).
- Operations: Arithmetic and logical operations on primitive types are performed directly
by the CPU.
4. Usage: Primitive types are often used when performance is critical or when simple values
need to be stored and manipulated.
Wrapper Classes:
1. Definition: Wrapper classes are part of the `java.lang` package and provide an object
representation for each primitive data type. They allow primitives to be used in contexts that
require objects, such as collections.
3. Characteristics:
- Object-Oriented: Wrapper classes allow primitives to be treated as objects. They provide
methods to perform operations, such as parsing strings into numbers or converting numbers
to binary strings.
- Default Values: Wrapper classes have a default value of `null` if they are not initialized.
- Boxing and Unboxing: Java supports automatic conversion between primitives and their
corresponding wrapper objects. This process is called autoboxing (primitives to wrapper
objects) and unboxing (wrapper objects to primitives).
4. Usage:
- Collections: Wrapper classes are used in Java collections (e.g., `ArrayList`, `HashMap`)
since collections can only store objects.
- Utility Methods: They provide utility methods for converting and manipulating data. For
example, `Integer.parseInt(String s)` can convert a string to an integer.
Key Differences:
- Memory and Performance: Primitive types are more memory-efficient and faster because
they are stored directly in memory, while wrapper classes involve additional overhead for
object management and boxing/unboxing operations.
- Default Values: Primitives have predefined default values, while wrapper class instances
default to `null`.
- Use in Collections: Primitive types cannot be used directly in Java collections, while
wrapper classes can.
- Utility Methods: Wrapper classes offer methods and constants that can be useful for
conversions and other operations, which primitives do not have.
In summary, primitives are fundamental and efficient for basic data storage, while wrapper
classes offer object-oriented features and compatibility with Java's object-based APIs and
collections.
b) Write a Java program that checks if a number is even or odd using if -else
statement
Java program to check if a number is even or odd using an if-else statement:
import java.util.Scanner;
public class EvenOddChecker {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter a number: ");
int number = scanner.nextInt();
if (number % 2 == 0) {
System.out.println(number + " is even.");
} else {
System.out.println(number + " is odd.");
}
scanner.close();
}
}
Explanation:
Scanner: Used to read input from the user.
if-else statement: Checks if the number is divisible by 2 (number % 2 == 0). If true,
the number is even; otherwise, it’s odd.
Output:
Prints whether the number is even or odd.
8.
a.What does the final keyword signify when used with variables, methods, and classes in
Java?
The final keyword is used to signify that something cannot be modified after it is initially
assigned. Its use with variables, methods, and classes has distinct implications:
1. Final Variables
When a variable is declared with the final keyword, its value cannot be changed once it has
been initialized. For primitive data types, this means that the value is constant after
assignment. For reference types (objects), it means that the reference itself cannot be
changed, though the object it points to can still be modified if its class is mutable.
Example:
2. Final Methods
Example:
When a class is declared as final, it cannot be subclassed or extended. This means that no
other class can inherit from a final class. Declaring a class as final is a way to ensure that its
implementation remains unchanged and to prevent the creation of subclasses.
Example:
The final keyword in Java is a versatile tool used to enforce immutability and prevent
modification. It ensures that variables cannot be reassigned, methods cannot be overridden,
and classes cannot be subclassed.
b.How does the switch statement work in Java? Provide an example that uses switch to
select a day of the week.
Switch statements are similar to if-else-if statements. The switch statement contains multiple
blocks of code called cases and a single case is executed based on the variable which is
being switched. The switch statement is easier to use instead of if-else-if statements. It also
enhances the readability of the program.
o The case variables can be int, short, byte, char, or enumeration. String type is also
supported since version 7 of Java
o Cases cannot be duplicate
o Default statement is executed when any of the case doesn't match the value of
expression. It is optional.
o Break statement terminates the switch block when the condition is satisfied.
It is optional, if not used, next case is executed.
o While using switch statements, we must notice that the case expression will be of the
same type as the variable. However, it will also be a constant value.
switch (expression){
case value1:
statement1;
break;
.
.
.
case valueN:
statementN;
break;
default:
default statement;
}
Consider the following example to understand the flow of the switch statement.
Student.java
Output:
While using switch statements, we must notice that the case expression will be of the same
type as the variable. However, it will also be a constant value. The switch permits only int,
string, and Enum type variables to be used.
import java.util.Scanner;
PART:A
The this keyword in Java serves multiple essential purposes, providing a way for an object to
refer to itself within instance methods or constructors.
Here’s why it’s useful:
Distinguishing Instance Variables:When local variables and instance variables have
the same name, this helps differentiate between them.
Calling Other Constructors:this can be used to call another constructor within the
same class, promoting constructor chaining.
Returning the Current Class Instance:Often used in method chaining, where methods
return the current object to allow successive method calls on the same instance.
this is a versatile keyword that enhances clarity, maintains consistency, and supports
more sophisticated object-oriented design patterns in Java.
2.Define constructor and how does it differ from a regular method?
Constructor
A constructor in Java is a special method that is called when an object of a class is
instantiated. It initializes the new object and sets up its initial state.
Characteristics:
Name: The constructor's name must be the same as the class name.
No Return Type: Constructors do not have a return type, not even void.
Automatic Invocation: Constructors are automatically called when a new instance of
the class is created using the new keyword.
Differences from a Regular Method:
Purpose:
Constructor: None.
Method: Must specify a return type or be void.
Invocation:
PART:B
1.Demonstrate the access modifiers in Java with example programs.
Access modifiers help to restrict the scope of a class, constructor, variable, method, or data
member. It provides security, accessibility, etc to the user depending upon the access
modifier used with the element. Let us learn about Java Access Modifiers, their types, and
the uses of access modifiers in this article.
When no access modifier is specified for a class, method, or data member – It is said to be
having the default access modifier by default. The data members, classes, or methods that
are not declared using any access modifiers i.e. having default access modifiers are
accessible only within the same package.
In this example, we will create two packages and the classes in the packages will be having
the default access modifiers and we will try to access a class from one package from a class
of the second package.
Program 1:
// Java program to illustrate default modifier
packagep1;
// Class Geek is having Default access modifier
classGeek
{
voiddisplay()
{
System.out.println("Hello World!");
}
}
Program 2:
Java
// Java program to illustrate error while
// using class from different package with
// default modifier
packagep2;
importp1.*;
obj.display();
}
}
Output:
Compile time error
The private access modifier is specified using the keyword private. The methods or data
members declared as private are accessible only within the class in which they are
declared.
Any other class of the same package will not be able to access these members.
Top-level classes or interfaces can not be declared as private because
o private means “only visible within the enclosing class”.
o protected means “only visible within the enclosing class and any subclasses”
Hence these modifiers in terms of application to classes, apply only to nested classes and
not on top-level classes
In this example, we will create two classes A and B within the same package p1. We will
declare a method in class A as private and try to access this method from class B and see
the result.
// Private Modifier
packagep1;
// Class A
classA{
privatevoiddisplay()
{
System.out.println("GeeksforGeeks");
}
}
// Class B
classB{
publicstaticvoidmain(Stringargs[])
{
Aobj=newA();
// Trying to access private method
// of another class
obj.display();
}
}
Output:
error: display() has private access in A
obj.display();
The methods or data members declared as protected are accessible within the same
package or subclasses in different packages.
In this example, we will create two packages p1 and p2. Class A in p1 is made public, to
access it in p2. The method display in class A is protected and class B is inherited from
class A and this protected method is then accessed by creating an object of class B.
Program 1:
// Java Program to Illustrate
// Protected Modifier
packagep1;
// Class A
publicclassA{
protectedvoiddisplay()
{
System.out.println("GeeksforGeeks");
}
}
Program 2:
// Class B is subclass of A
classBextendsA{
publicstaticvoidmain(Stringargs[])
{
Bobj=newB();
obj.display();
}
}
Output:
GeeksforGeeks
Program 1:
// Java program to illustrate
// public modifier
packagep1;
publicclassA
{
publicvoiddisplay()
{
System.out.println("GeeksforGeeks");
}
}
Program 2:
packagep2;
importp1.*;
classB{
publicstaticvoidmain(Stringargs[])
{
Aobj=newA();
obj.display();
}
}
Output:
GeeksforGeeks
Important Points:
If other programmers use your class, try to use the most restrictive access level that
makes sense for a particular member. Use private unless you have a good reason not to.
Avoid public fields except for constants.
2.
a. Explain the concept of classes and objects in Object-Oriented Programming (OOP).
ANSWER:
Class:
A Java class is the template from which objects are created. It is a blueprint for an object. A
class is created using the keyword class.
Classes can contain methods, which are actions that the class can perform, and fields, which
are variables that contain data used by the class. When we create a new object, we create an
instance of a class.
Declaring a class:
The name of the class should be followed by the keyword class. The body of the class is
enclosed within curly braces {}. All the data members and member functions of the class are
declared inside the body of the class.
Syntax
Code example
publicclass Person {
// fields
String name;
// methods
voidprintName() {
System.out.println(name);
}
}
This Java class has the name Person. The keyword public is an access modifier, which
determines who can access this class. In this case, the class is accessible by any other class.
Inside the body of the class, we can declare fields and methods.
Fields:
Fields are variables that contain data. In the example above, we have a field named name.
Fields are usually declared at the top of the class before any methods.
Methods:
Methods are functions that perform actions. In the example above, we have a method
named printName(), which prints the value of the name field to the screen. Methods are
usually declared after the fields in a class.
Creating an object:
To use a class, we need to create an instance of the class. To do this, we use the
keyword new. For example, if we want to create an instance of the Person class, we would
use the following code:
This creates an object called myObj, which is an instance of the Person class.
We can then access the fields and methods of this object using the dot notation, like this:
This set the name field to "John Doe" and then call the printName() method, which print the
value of the name field to the screen.
class Person {
// fields
String name;
// methods
voidprintName() {
System.out.println(name);
}
}
class Main {
publicstaticvoidmain( String args[] ) {
Person myObj =newPerson();
myObj.name ="John Doe";
myObj.printName();
}
}
In the code above, we create a class named Person that has a field name and a
method printName().
In the main() method, we create an object of the class and assign a value to the name
field.
Finally, we invoke the printName() method on the object to print the value of the
name.
ANSWER:
In Java, all arguments are passed by value, which means that when a method is called, a copy
of the argument’s value is passed. This can sometimes be confused with passing by reference
because of how objects and their references work. Here’s the breakdown:
Passing by Value
Primitives: When you pass a primitive data type to a method, a copy of the value is passed.
Changes to the parameter inside the method do not affect the original value.
int a = 5;
modifyPrimitive(a);
Output:
After modifyPrimitive: 5
When you pass an object to a method, what gets passed is the value of the reference to the
object (not the actual object itself). This means the method can change the object’s state but
cannot change the object’s reference.
class MyObject {
int value
MyObject(int value) {
this.value = value;
}
public class PassByValueExample {
modifyObject(obj);
Output:
After modifyObject: 10
Key Points:
3.Define nested classes and explain their types (static nested classes and inner classes).
ANSWER:
Inner class refers to the class that is declared inside class or interface.
There are certain advantages associated with inner classes are as follows:
It can access any private instance variable of the outer class. Like any other instance
variable, we can have access modifier private, protected, public, and default modifier. Like
class, an interface can also be nested and can have access specifiers.
Example 1A
// Class 1
// Helper classes
classOuter{
// Class 2
// Simple nested inner class
classInner{
// Print statement
System.out.println("In a nested class method");
}
}
}
// Class 2
// Main class
classMain{
Output
In a nested class method
Note: We can not have a static method in a nested inner class because an inner class is
implicitly associated with an object of its outer class so it cannot define any static method
for itself. For example, the following program doesn’t compile. But Since JAVA Version 16
we can have static members in our inner class also.
Example 1B
// Class 1
// Outer class
classOuter{
// Print statement
System.out.println("inside outerMethod");
}
// Class 2
// Inner class
classInner{
An interface can also be nested and nested interfaces have some interesting properties. We
will be covering nested interfaces in the next post.
Example 1
// Java Program to Illustrate Inner class can be
// declared within a method of outer class
// Class 1
// Outer class
classOuter{
// Print statement
System.out.println("inside outerMethod");
// Class 2
// Inner class
// It is local to outerMethod()
classInner{
// Class 3
// Main class
classGFG{
Output
inside outerMethod
inside innerMethod
Method Local inner classes can’t use a local variable of the outer method until that local
variable is not declared as final. For example, the following code generates a compiler
error.
Note: “x” is not final in outerMethod() and innerMethod() tries to access it.
Example 2
Java
classOuter{
voidouterMethod(){
intx=98;
System.out.println("inside outerMethod");
classInner{
voidinnerMethod(){
System.out.println("x= "+x);
}
}
Innery=newInner();
y.innerMethod();
}
}
classMethodLocalVariableDemo{
publicstaticvoidmain(String[]args){
Outerx=newOuter();
x.outerMethod();
}
}
Output
inside outerMethod
x= 98
Note: Local inner class cannot access non-final local variable till JDK 1.7. Since JDK 1.8,
it is possible to access the non-final local variable in method local inner class.
But the following code compiles and runs fine (Note that x is final this time)
Example 3
Java
classOuter{
voidouterMethod(){
finalintx=98;
System.out.println("inside outerMethod");
classInner{
voidinnerMethod(){
System.out.println("x = "+x);
}
}
Innery=newInner();
y.innerMethod();
}
}
classMethodLocalVariableDemo{
publicstaticvoidmain(String[]args){
Outerx=newOuter();
x.outerMethod();
}
}
Output
inside outerMethod
x = 98
The main reason we need to declare a local variable as a final is that the local variable lives
on the stack till the method is on the stack but there might be a case the object of the inner
class still lives on the heap.
Method local inner class can’t be marked as private, protected, static, and transient but can
be marked as abstract and final, but not both at the same time.
Static nested classes are not technically inner classes. They are like a static member of
outer class.
Example
// Class 1
// Outer class
classOuter{
// Method
privatestaticvoidouterMethod()
{
// Print statement
System.out.println("inside outerMethod");
}
// Class 2
// Static inner class
staticclassInner{
publicstaticvoiddisplay()
{
// Print statement
System.out.println("inside inner class Method");
// Class 3
// Main class
classGFG{
// Calling method static display method rather than an instance of that class.
Outer.Inner.display();
}
}
Output
inside inner class Method
inside outerMethod
Anonymous inner classes are declared without any name at all. They are created in two
ways.
As a subclass of the specified type
As an implementer of the specified interface
Way 1: As a subclass of the specified type
Example:
Java
// Java Program to Illustrate Anonymous Inner classes
// Declaration Without any Name
// As a subclass of the specified type
// Class 1
// Helper class
classDemo{
// Class 2
// Main class
classFlavor1Demo{
// Print statement
System.out.println("i am in Flavor1Demo class");
}
};
// Method 2
// Main driver method
publicstaticvoidmain(String[]args)
{
// Calling show() method inside main() method
d.show();
}
}
Output
i am in show method of super class
i am in Flavor1Demo class
In the above code, we have two classes Demo and Flavor1Demo. Here demo act as a super-
class and the anonymous class acts as a subclass, both classes have a method show(). In
anonymous class show() method is overridden.
Encapsulation: Inner classes can access private variables and methods of the outer
class. This helps to achieve encapsulation and improves code readability.
Code Organization: Inner classes allow you to group related code together in one
place. This makes your code easier to understand and maintain.
Better Access Control: Inner classes can be declared as private, which means that
they can only be accessed within the outer class. This provides better access control
and improves code security.
Callbacks: Inner classes are often used for implementing callbacks in event-driven
programming. They provide a convenient way to define and implement a callback
function within the context of the outer class.
Polymorphism: Inner classes can be used to implement polymorphism. You can
define a class hierarchy within the outer class and then create objects of the inner
classes that implement the different subclasses.
Reduced Code Complexity: Inner classes can reduce the complexity of your code
by encapsulating complex logic and data structures within the context of the outer
class.
4.Discuss the purpose of this keyword in Java with its usage with example.
ANSWER:
The this keyword is a reference variable that refers to the current object. It is primarily used
to differentiate between instance variables and parameters, access class methods, and for
constructor chaining. Here are the main scenarios in which this is used:
When the parameter name is the same as the instance variable name, this helps to clarify that
you are referring to the instance variable.
Example:
java
Copy code
publicclassDog {
private String name;
publicDog(String name) {
this.name = name; // 'this.name' refers to the instance variable
}
}
In this example, this.name refers to the instance variable name, while the parameter name is
the one passed to the constructor.
You can use this to call methods of the current object. This can be particularly useful when
method names might be ambiguous.
Example:
java
Copy code
publicclassDog {
publicvoidbark() {
System.out.println("Woof!");
}
publicvoidperformAction() {
this.bark(); // Calls the bark method of the current object
}
}
3. Constructor Chaining
this can be used to call one constructor from another constructor in the same class. This is
known as constructor chaining, which allows you to reuse constructor code.
Example:
java
Copy code
publicclassDog {
private String name;
private String breed;
publicDog(String name) {
this(name, "Unknown"); // Calling another constructor
}
publicDog(String name, String breed) {
this.name = name;
this.breed = breed;
}
}
In this example, the first constructor calls the second constructor using this(name,
"Unknown").
You can return the current object from a method using this, which can be useful in method
chaining.
Example:
java
Copy code
publicclassDog {
private String name;
// Usage
Dogdog=newDog().setName("Buddy");
A constructor is a special method that is called when an object of a class is created. Its
primary role is to initialize the newly created object, setting its initial state by assigning
values to its fields.
1. Same Name as Class: A constructor must have the same name as the class.
2. No Return Type: Constructors do not have a return type, not even void.
3. Can Be Overloaded: You can have multiple constructors in a class with different
parameter lists, which is known as constructor overloading.
Role of Constructors in Object Initialization
Constructors are crucial for initializing an object’s state when it is created. They allow you to
set initial values for instance variables and perform any setup necessary before the object is
used.
Example of a Constructor:
publicclassDog {
String name;
String breed;
// Constructor
publicDog(String name, String breed) {
this.name = name; // Initialize instance variables
this.breed = breed;
}
}
// Creating an object
DogmyDog=newDog("Buddy", "Golden Retriever");
In this example, when myDog is created, the constructor initializes its name and breed fields.
Overloaded Constructors
Constructor overloading allows a class to have more than one constructor, each with a
different parameter list. This enables you to create objects in different ways, depending on the
arguments passed.
publicclassDog {
String name;
String breed;
int age;
6.
a.Discuss the concept of method overloading in Java.
ANSWER:
Method overloading in Java is a feature that allows a class to have more than one method
with the same name, provided that the methods have different parameter lists. This means
that the methods can differ in the number of parameters, the types of parameters, or both.
Method overloading enhances the readability and usability of the code.
1. Same Method Name: All overloaded methods share the same name.
2. Different Parameter Lists: They must have different parameter types, numbers, or
both. The return type can be different, but it alone does not differentiate overloaded
methods.
3. Compile-Time Polymorphism: Method overloading is a compile-time
polymorphism, meaning the method to be invoked is determined at compile time
based on the method signatures.
1. Improved Code Readability: Using the same name for related methods makes the
code easier to read and understand.
2. Enhanced Flexibility: It allows methods to handle different types and numbers of
inputs, making the code more versatile.
3. Simplified Maintenance: Having a unified method name can simplify code
maintenance and refactoring.
publicclassMathOperations {
// Usage
publicclassMain {
publicstaticvoidmain(String[] args) {
MathOperationsmath=newMathOperations();
1. Different Parameter Types: Overloaded methods must have at least one parameter
that differs in type.
2. Different Number of Parameters: Overloaded methods can have a different number
of parameters, regardless of their types.
3. Return Type: The return type alone is not sufficient to overload methods; the
parameter list must differ.
Method overriding is a feature in Java that allows a subclass (child class) to provide a
specific implementation of a method that is already defined in its superclass (parent class).
This allows the subclass to modify or extend the behavior of that method while maintaining
the same method signature (name, return type, and parameters).
1. Same Method Signature: The overridden method in the subclass must have the same
name, return type, and parameter list as the method in the superclass.
2. Inheritance: Method overriding can only occur in a class hierarchy. The subclass
must inherit from the superclass.
3. Dynamic Polymorphism: Method overriding is a way to achieve runtime
polymorphism in Java. The method that gets executed is determined at runtime based
on the object type.
4. Use of the @Override Annotation: While not required, it is a good practice to use
the @Override annotation above the overridden method. This helps in verifying that
the method is indeed overriding a superclass method, providing compile-time
checking.
classAnimal {
publicvoidsound() {
System.out.println("Animal makes a sound");
}
}
classDogextendsAnimal {
@Override
publicvoidsound() { // Overriding the sound method
System.out.println("Dog barks");
}
}
classCatextendsAnimal {
@Override
publicvoidsound() { // Overriding the sound method
System.out.println("Cat meows");
}
}
publicclassMain {
publicstaticvoidmain(String[] args) {
AnimalmyDog=newDog();
AnimalmyCat=newCat();
myDog.sound(); // Output: Dog barks
myCat.sound(); // Output: Cat meows
}
}
1. Access Modifiers: The overriding method must have the same or a more accessible
visibility modifier. For example, a protected method in the superclass can be
overridden as protected or public in the subclass, but not as private.
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 (this is known
as covariant return types).
3. Non-static Methods: Only instance methods can be overridden; static methods
cannot be overridden (they can be hidden).
4. Final Methods: A method declared as final in the superclass cannot be overridden in
any subclass.
5. Abstract Methods: If the superclass has an abstract method, the subclass must
provide an implementation for that method unless the subclass is also abstract.
7.
Define recursive methods and discuss their use cases.
ANSWER:
Recursive Methods
A recursive method is a method that calls itself in order to solve a problem. This technique
is often used to break down complex problems into simpler subproblems. Each recursive call
works toward a base case, which stops the recursion to prevent infinite loops.
1. Base Case: A condition under which the recursion stops. This prevents the method
from calling itself indefinitely.
2. Recursive Case: The part of the method where the function calls itself with modified
arguments, gradually moving toward the base case.
Here’s a simple example that calculates the factorial of a number using recursion:
publicclassFactorial {
publicstaticvoidmain(String[] args) {
Factorialfact=newFactorial();
intresult= fact.factorial(5); // 5! = 5 * 4 * 3 * 2 * 1 = 120
System.out.println("Factorial: " + result);
}
}
Advantages of Recursion
Simplicity: Recursive solutions can be simpler and more intuitive than their iterative
counterparts, making them easier to write and understand.
Reduced Code Size: Recursive methods can lead to shorter code because the same
logic can be expressed in fewer lines.
Disadvantages of Recursion
Performance: Recursive methods can lead to high memory usage due to call stack
growth, especially if the recursion depth is significant.
Risk of Stack Overflow: If the base case is not defined correctly or the recursion
goes too deep, it can lead to a stack overflow error.
8.Explain the roles of final and static keywords when applied to methods.
ANSWER:
The final and static keywords serve distinct purposes when applied to methods. Here’s a
detailed explanation of their roles:
final Keyword
When a method is declared as final, it cannot be overridden by subclasses. This has several
implications:
Prevent Modification: Marking a method as final ensures that its implementation remains
unchanged in any subclass. This is useful for methods that provide essential functionality that
should not be altered.
1. Security: By preventing overriding, final methods can help maintain the integrity of a
class’s behavior, particularly in sensitive or critical sections of code.
2. Performance Optimization: The Java compiler can make certain optimizations for
final methods since it knows they cannot be overridden.
Example:
classBaseClass {
publicfinalvoiddisplay() {
System.out.println("This method cannot be overridden.");
}
}
classSubClassextendsBaseClass {
// The following would cause a compile-time error:
// public void display() {
// System.out.println("Attempting to override.");
// }
}
static Keyword
When a method is declared as static, it belongs to the class rather than any instance of the
class. This means that it can be called without creating an instance of the class.
Roles of static Methods
1. Class-Level Accessibility: Static methods can be called on the class itself, without
needing an object. This is useful for utility or helper methods that don't rely on
instance variables.
2. Memory Management: Since static methods are associated with the class, they can
help save memory by not requiring an instance of the class for invocation.
3. No Access to Instance Variables: Static methods cannot access instance variables or
instance methods directly. They can only access static variables and methods.
4. Method Overriding: Static methods can be hidden but not overridden. If a static
method in a subclass has the same name and parameters as a static method in the
superclass, it is considered hidden, not overridden.
Example:
classUtility {
publicstaticvoidprintMessage() {
System.out.println("This is a static method.");
}
}
// Calling a static method
Utility.printMessage(); // No need to create an instance of Utility
UNIT-III
1.What is a dynamic array, and how can you change the size of an array dynamically in Java?
Dynamic array
A dynamic array is an array with a big improvement: automatic resizing. One limitation of arrays
is that they're fixed size, meaning you need to specify the number of elements your array will
hold ahead of time. A dynamic array expands as you add more elements. So you don't need to
determine the size ahead of time.
Java allows us to change the array size dynamically during the execution of the program. In this process
the array destroyed along with the values of elements. In the following program, the array contains 5
elements. It is again defined with 10 elements with the same array name.
• Similar to Arrays, vectors are another kind of data structure that is used for storing
information.
• Using vector, we can implement a dynamic array.
• The following are the vector constructors:
• Vector() creates a default vector having an initial size of 10.
• Vector(int size) creates a vector whose initial capacity is specified by size.
• Example
Vector vec = new Vector(5); // declaring with initial size of 5
• Vector(int size, int incr) creates a vector with initial capacity specified by size and
increment is specified by incr.
• The increment is the number of elements added in each reallocation cycle.
3.What is the universal superclass in Java, and why is it called that?
Universal Super Class : “ Object ” Class
Object class is a special class and it is at the top of the class hierarchy tree.
It is the parent class or super class of all in Java.
Hence, it is called Universal super class.
Object is at the root of the tree and every other class can be directly or indirectly
derived from the Object class.
4. How can you prevent a class from being inherited in Java?
To prevent inheritance, use the keyword "final" when creating the class. The designers of the
String class realized that it was not a candidate for inheritance and have prevented it from being
extended.
5.What are default methods in interfaces, and why are they used?
• The enhancement in Java 8 allowing the interface to have full definition of default methods and static
methods that are implicitly inherited by the class implementing the interface.
• Java allows only one super class, by using default methods in interface java allows that interface
behaves just like an abstract super-class.
• New functionality can be added to the interface, which is inherited by classes implementing the
interface.
Interfaces can inherit from one or more interfaces. The derived interface inherits the members from its
base interfaces. A class that implements a derived interface must implement all members in the derived
interface, including all members of the derived interface's base interfaces.
PART-B
An array is a structure consisting of a group of elements of the same type. When a large number of data
values of the same type are to be processed, it can be done efficiently by declaring an array of the data
type.
The complete data gets represented by a single object with a single name in the computer memory. An
array is a sequence of objects of the same data type. The type of data that the array holds becomes the
type of the array, which is also called base type of the array.
If the array elements have values in whole numbers, that is, of type int, the type of array is also int. If it
is a sequence of characters, the type of array is char;
If it is an array of floating point numbers of type float, the type of array is also float.An array can hold
objects of a class but cannot be a mixture of different data types.
initialization of Arrays: An array may be initialized by mentioning the values in braces and separated by
commas.
import java.util.Scanner;
class BinarySearch
{
public static void main(String args[])
{
boolean b =false;
int[] array = {15, 20, 43, 45, 76, 80, 86, 88, 90, 94, 96, 98};
int length= array.length;
Scanner in = new Scanner(System.in);
System.out.println("Enter the number which you want to search");
int key = in.nextInt();
int beginning,end,mid;
beginning =0;
end = length-1;
while( beginning <=end)
{
if(beginning == end && array[end]!=key)
{
System.out.println("Your number is not in the array");
break;
}
mid = (beginning +end )/2;
if(array[mid]==key)
{
System.out.println("Your number is in the array at index = " + mid);
break;
}
else if(array[mid]<key)
beginning = mid+1;
else
end = mid-1;
}
}
}
Output:
C:\>javac BinarySearch.java
C:\>java BinarySearch
Enter the number which you want to search
45
Your number is in the array at index = 3
C:\>java BinarySearch
Enter the number which you want to search
96
Your number is in the array at index = 10
C:\>java BinarySearch
Enter the number which you want to search
783
Your number is not in the array
2.
Two-dimensional Arrays
• If the elements of an array are one-dimensional arrays, the array becomes a two-dimensional array.
• A two-dimensional array is treated as an array of arrays, and each of these arrays may have a different
number of elements.
class TwoDimArray
for(int[] y : num2D)
for(int x : y)
System.out.println();
Output:
123
456
789
import java.util.Scanner;
Output;
Enter number of rows in first matrix: 3
Enter number of columns in first matrix: 2
Enter number of rows in second matrix: 2
Enter number of columns in second matrix: 4
Matrix multiplication is :
29 32 35 38
65 72 79 86
101 112 123 134
INTERFACE;
• An interface represents an encapsulation of constants, classes, interfaces, and one or more abstract
methods that are implemented by a class.
• Only headers are declared with the parameter list that is followed by a semicolon.
• The class that implements the interface has to have full definitions of all the abstract methods in the
interface.
• An interface can be implemented by any number of classes with their own definitions of the methods
of the interface
Functional Interfaces
• In Java SE8, a new package java.util.function on functional interfaces has been introduced for writing
Lambda functions.
• However, a functional interface can have more than one static and default methods.
• By adding the above annotation, it can be helpful in detecting compile time errors.
• If the functional interface contains more than one abstract method, the compiler will throw an error.
Nested Interfaces
• In the capacity of a class member, it can have the attributes that are applicable to otherclassmembers.
• In other cases, an interface can only be declared as public or with default (no-access modifier) access
Example: NestedInterface.java
interface OuterX
{
int x = 10;
public interface InnerY
{
int y = 20;
}
}
class A implements OuterX, OuterX.InnerY
{
void display()
{
System.out.println("Class-A Method : x = "+ x + " y = " + y);
}
}
class NestedInterface
{
public static void main(String args[])
{
//calling class-A method
A objA = new A();
objA.display();
}
}
Output:
C:\ >javac NestedInterface.java
C:\ >java NestedInterface
Class-A Method : x = 10 y = 20
4.
It is implemented through super class reference. A super class reference can refer to an object of its
subclass.
A base class pointer can refer to derived class object. There may be many subclasses inherited from
a super class.
Each subclass has its own version or definition of the overridden method.
The dynamic method dispatch chooses the right version of the method corresponding to the object
reference.
The value of subclass object is assigned to the variable and the overridden method is called by the
super class reference.
1. class Animal {
2. void makeSound() {
3. System.out.println("Generic Animal Sound");
4. }
5. }
6. class Dog extends Animal {
7. @Override
8. void makeSound() {
9. System.out.println("Bark");
10. }
11. }
12. class Cat extends Animal {
13. @Override
14. void makeSound() {
15. System.out.println("Meow");
16. }
17. }
18. public class DynamicMethod {
19. public static void main(String[] args) {
20. Animal[] animals = {new Dog(), new Cat()};
21. for (Animal animal : animals) {
22. animal.makeSound();
23. }
24. }
25. }
Output:
Bark
Meow
5.
a.What is inheritance? List out the advantages of Inheritance. Discuss the types
Introduction
It is the mechanism by which a class can acquire properties and methods of another
class.
Using inheritance, an already tested and debugged class program can be reused for some other
application.
Super class This is the existing class from which another class, that is, the subclass is enerally
derived.
In Java, several derived classes can have the same super class.
• It allows the reuse of already developed and debugged class program without any modification.
• A large program may be divided into suitable classes and subclasses that may be developed by
separate teams of programmers.
6.
a.Discuss the advantages of the Interface.
There are certain features added to Interfaces in JDK 8 update mentioned below:
1. Prior to JDK 8, the interface could not define the implementation. We can now add
default implementation for interface methods. This default implementation has a special
use and does not affect the intention behind interfaces.
2. Suppose we need to add a new function to an existing interface. Obviously, the old
code will not work as the classes have not implemented those new functions. So with
the help of default implementation, we will give a default body for the newly added
functions. Then the old codes will still work.
7.
Super keyword in Java helps create a bridge between child and parent class. Today in this blog,
we will discuss the super keyword in detail and will critically examine the super keyword in Java
Super keyword in Java is a reference variable used to refer to the immediate parent
class(superclass) object. The super keyword in Java is used when we want to acquire a
superclass member and use it in a derived class. When an instance of the child class is created,
an instance of the superclass is also created.
class ParentClass{
int num = 120;
}
/*
sub class childClass extending parentClass
*/
class ChildClass extends ParentClass{
int num = 100;
void display(){
// Printing the num without use of super keyword
System.out.println("Value of Num in child class: " + num);
You can also try this code with Online Java Compiler
Run Code
Output
Value of Num in child class: 100
Value of Num in parent class: 120
b) Write a java program to find the minimum and maximum value present in an array.
class GFG {
// Driver code
public static void main(String[] args)
{
int arr[] = { 12, 1234, 45, 67, 1 };
int n = arr.length;
System.out.println("Minimum element of array: " + getMin(arr, n));
System.out.println("Maximum element of array: " + getMax(arr, n));
}
}
Output
Minimum element of array: 1
Maximum element of array: 1234
8.
a)Explain the concept of arrays of varying lengths and arrays as vectors.
variable length arrays (VLAs) are also known as runtime-sized or variable-sized arrays. The
size of such arrays is defined at run-time.
Variably modified types include variable-length arrays and pointers to variable-length arrays.
Variably changed types must be declared at either block scope or function prototype scope.
Variable length arrays are a feature where we can allocate an auto array (on stack) of variable
size. It can be used in a typedef statement. C supports variable-sized arrays from the C99
standard. For example, the below program compiles and runs fine in C.
Syntax of VLAs in C
void fun(int size)
{
int arr[size];
// code
}
b) Write a Java program to find the area and perimeter of square and circle using
interface.
interface Shape {
double calculateArea();
double calculatePerimeter();
}
Circle(double radius) {
this.radius = radius;
}
public double calculateArea() {
return Math.PI * radius * radius;
}
Square(double side) {
this.side = side;
}
Part-a
The Object class in Java is the grandparent of all classes. Every class you create
implicitly inherits from Object, which means it contains some essential methods that
are universally available.
Key Methods:
hashCode(): Returns a hash code value for the object. Useful in hashing-based
collections like HashMap.
toString(): Returns a string representation of the object, which you can override to
provide a custom string output.
finalize(): Called by the garbage collector when the object is being cleaned up, but
using this method is generally discouraged.
Access control in Java packages is all about defining what can be accessed from where,
providing a layer of protection and organization. It helps in encapsulating and
safeguarding the data. There are four levels of access control in Java:
Public: Members (fields, methods, etc.) declared as public are accessible from any other
class. If a class is public, it can be accessed from any other class irrespective of the
package it resides in.
Protected: Members declared as protected can be accessed within the same package
and by subclasses, even if they are in different packages. It offers a balance between
visibility and encapsulation.
Private: Members declared as private are accessible only within the class they are
declared in. This is the most restrictive level of access control.
3. Write the differences between checked and unchecked exceptions?
Checked and unchecked exceptions in Java are categorized based on the compile-time
checking they undergo:
Checked Exceptions:
Compile-Time Checked: The compiler ensures that these exceptions are handled, either
with a try-catch block or by declaring them with a throws clause.
Unchecked Exceptions:
Runtime Checked: These exceptions are not checked at compile time. They only get
checked at runtime.
4. How does the finally block work, and when should it be used?
The finally block in Java is a part of exception handling and is used to ensure that a
specific block of code executes regardless of whether an exception occurs or not. It's
often used for cleanup activities, such as closing resources (e.g., files, database
connections) that need to be executed no matter what happens in the try or catch blocks.
The Java I/O API, short for Input/Output API, is a collection of classes and interfaces that
allow programs to read from and write to different data sources (like files, networks, and
other types of I/O streams).
Significance:
Flexibility: The API allows handling various data formats and I/O devices in a uniform
manner.
Error Handling: With exception mechanisms in place, it ensures robust handling of I/O
errors.
Scalability: Supports both blocking and non-blocking I/O operations, making it suitable
for a range of applications from simple file handling to complex network
communications.
6. How can you read and write text files using Java I/O classes?
Reading and writing text files in Java is pretty straightforward, thanks to the FileReader
and FileWriter classes for basic I/O operations, and BufferedReader and BufferedWriter
for more efficient, buffered I/O.
FileReader and FileWriter are used to read and write characters to a file.
BufferedReader and BufferedWriter provide efficient reading and writing by buffering the
input and output.
The try-with-resources statement ensures that resources (like file streams) are closed
automatically.
Part b
1.
a) How to define a package? How to access, import a package? Explain with
examples.
Creating and using packages in Java helps organize your code into modular, reusable
pieces. Let's break it down:
Defining a Package:
You define a package at the very top of your Java file using the package keyword:
Sntyax;
package com.example.myapp;
public class MyClass {
// class content
}
Importing a Package:
To use a class from another package, you import it using the import keyword:
import com.example.myapp.MyClass;
public class Test {
public static void main(String[] args) {
MyClass obj = new MyClass();
}
}
Importing a Package:
To use a class from another package, you import it using the import keyword:
import com.example.myapp.*;
Example:
// File: Utils.java
package com.myapp.utils;
public class Utils {
public static void printMessage(String message) {
System.out.println(message);
}
}
// File: Main.java
import com.myapp.utils.Utils;
public class Main {
public static void main(String[] args) {
Utils.printMessage("Hello from Utils!");
}
}
The Throwable class in Java is the superclass for all errors and exceptions in the
language. Let's create a simple program to illustrate its use:
System.out.println("Stack Trace:");
for (StackTraceElement element : t.getStackTrace()) {
System.out.println(element);
}
Explanation:
The catch block catches the exception and prints its message.
2.
a) Give the syntax to create a package in Java. How to set the path and class path
variables? Explain.
Syntax
package com.example.myapp;
public class MyClass {
// class content
}
PATH: This environment variable tells the operating system where to look for
executable files. Typically, you include the JDK/bin directory in the PATH to run
Java commands from any directory.
On Windows:
set CLASSPATH=C:\myfolder\myclasses;%CLASSPATH%
Wrapper classes in Java are objects that encapsulate primitive data types in order to
provide object-oriented features. Each primitive type (like int, char, boolean, etc.) has a
corresponding wrapper class (Integer, Character, Boolean, etc.).
Key Features:
Nullability: Unlike primitives, wrapper classes can hold null values, which is
useful for representing the absence of a value.
Examples:
3.
a Write the differences between the following classes Date, Calendar and Gregorian
Calendar and usage of time package.
Date Class
Purpose: Represents a specific instant in time, with millisecond precision.
Usage: Used mainly for working with date and time in a simple way.
Example:
Date date = new Date();
System.out.println(date);
Limitations: Lacks many methods for date manipulation. Mostly deprecated and replaced
by the Calendar class.
Calendar Class
Purpose: Abstract class for manipulating dates and times.
Usage: Provides methods for setting and getting specific parts of a date (like year,
month, day).
Example:
Calendar calendar = Calendar.getInstance();
calendar.set(2024, Calendar.OCTOBER, 28);
Date date = calendar.getTime();
System.out.println(date);
GregorianCalendar Class
Purpose: Concrete subclass of Calendar that implements the Gregorian calendar system.
Example:
GregorianCalendar gCal = new GregorianCalendar(2024, Calendar.OCTOBER, 28);
Date date = gCal.getTime();
System.out.println(date);
java.time Package
Purpose: Introduced in Java 8, it provides a more comprehensive date and time API.
Usage: Offers a fluent API for handling date and time with immutability and thread-safety.
Example:
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
The java.time package is highly recommended for modern applications due to its
enhanced functionality and ease of use compared to the older Date and Calendar
classes.
The java.lang package is the core package in Java, containing fundamental classes that
are essential for the language’s design and functionality. It's automatically imported into
every Java program, so you don't need to import it explicitly.
Key Classes:
Object: The root class from which all other classes inherit. Provides basic
methods like toString(), equals(), hashCode(), and clone().
Class: Represents classes and interfaces in a running Java application. You can
use Class objects to get information about fields, methods, and constructors.
System: Provides access to system resources like standard input and output, and
methods for copying arrays and interacting with the garbage collector.
Throwable, Exception, Error: These are the classes for exception handling in Java.
Throwable is the superclass for all exceptions and errors, Exception is for
conditions that a reasonable application might want to catch, and Error represents
serious problems that an application should not attempt to catch.
Runtime: Enables the application to interface with the environment in which the
application is running. It provides methods to execute processes, read system
properties, and interact with the garbage collector.
Boolean, Byte, Character, Double, Float, Integer, Long, Short: These are wrapper
classes for the respective primitive types, allowing primitive values to be treated
as objects.
Enum: Base class for all enumeration types in Java, providing methods to retrieve
enumeration constants and their names.
Examples:
String Manipulation:
Math Operations:
5
a. a) What is an exception? In what an exception differs from error?Distinguish between
user defined and built-in exceptions.
Exception: Represents conditions that a program should catch and handle. Examples
include IOException, SQLException, and ArithmeticException.
Error: Represents serious issues that are typically outside the scope of the program's
control and usually signal fundamental problems with the JVM, like OutOfMemoryError
and StackOverflowError. Generally, these should not be caught as they denote serious
issues.
Built-in Exceptions: These are predefined in Java’s standard library and include:
Difference in Usage:
Java's file handling mechanisms offer a comprehensive way to read, write, and
manipulate files. Let’s break it down:
Reading Files
Using FileReader and BufferedReader
Writing Files
Example:
import java.io.*;
public class FileIO {
try {
in = new FileReader("C:\\Raja\\Input-File.txt");
out = new FileWriter("C:\\Raja\\Output-File.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
System.out.println("Reading and Writing in a file is done!!!");
}
catch(Exception e) {
System.out.println(e);
}
finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
6.
a.Write short notes on i) wrapper classes ii) Temporal adjusters class iii)throws clause
i) Wrapper Classes
Wrapper classes in Java are used to convert primitive data types (like int, char, boolean,
etc.) into objects. Each primitive has a corresponding wrapper class (e.g., Integer for int,
Character for char). They are useful because many utility methods and collections in
Java work with objects, not primitives.
For example:
LocalDate next
Sunday=LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
For example:
7.
a)Describe the Hierarchy of Java exception classes with a neat sketch.
Hierarchy Overview:
At the top of the hierarchy is the Throwable class, which is the superclass for all
exceptions and errors. Under Throwable, there are two main branches: Exception and
Error.
Throwable:
Exception:
Represents exceptions that can occur during the normal operation of the Java
Virtual Machine.
Subclasses:
NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException, etc.
Error:
Imagine it as a tree diagram, with Throwable at the top, branching out into
Exception and Error, and further branching into more specific exception types.
b. Explain nested try statements and multiple catch blocks with a suitable program
Nested try statements and multiple catch blocks are useful for handling different types of
exceptions within different blocks of code. Here's an example to demonstrate both:
Example Program
try {
int result = 10 / 0; // This will throw ArithmeticException
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Caught an ArithmeticException: " + e.getMessage());
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Caught an ArrayIndexOutOfBoundsException: " +
e.getMessage());
} catch (Exception e) {
System.out.println("Caught a general exception: " + e.getMessage());
}
System.out.println("Program continues...");
}
}
Explanation
Key Points:
Nested try-catch: Inner try block can handle exceptions specific to its scope.
Multiple catch: Different exception types are caught by different catch blocks,
making error handling more precise and informative.
8.
a)Discuss about Byte stream and Character streams in detail.
Byte Streams
Byte streams in Java are used for handling raw binary data. They are useful when
working with data such as images, audio, or any kind of file where character encoding
isn't an issue. The core classes for byte stream are InputStream and OutputStream.
Key Classes:
InputStream: Abstract superclass for all byte input streams. Subclasses include
FileInputStream, BufferedInputStream, DataInputStream.
OutputStream: Abstract superclass for all byte output streams. Subclasses include
FileOutputStream, BufferedOutputStream, DataOutputStream.
Example:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
Key Classes:
Reader: Abstract superclass for all character input streams. Subclasses include
FileReader, BufferedReader, InputStreamReader.
Writer: Abstract superclass for all character output streams. Subclasses include
FileWriter, BufferedWriter, OutputStreamWriter.
Example:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
The Scanner class in Java, part of the java.util package, is a versatile tool for parsing
input and simplifying data extraction from various input sources like strings, files, and
input streams (such as System.in).
Key Functionalities:
Reading from Standard Input:
nextInt(), nextDouble(), etc.: Reads the next token as an int, double, etc.
Uses methods similar to those for standard input but with a File object as the source.
Delimiters:
Example Program:
Here's a program demonstrating how to use Scanner to read input from the console and
a file:
import java.util.Scanner;
System.out.println("Hello, " + name + ". You are " + age + " years old.");
scanner.close();
}
}
Unit-5
PART-A(SHORT QUESTIONS AND ANSWERS)
The CharSequence is a readable sequence of char values, providing a standardized way to work
with different types of character sequences. It defines methods to access and manipulate a
sequence of characters.
Implementations of CharSequence
2. Explain how you can search for a substring within a string in Java.
In Java, you can search for a substring within a string using several built-in methods provided by the
String class. Here are some commonly used approaches:
class string
{
System.out.println(sb.charAt(2));
System.out.println(sb.indexOf("J"));
System.out.println(sb.lastIndexOf("a"));
3. What is the String class in Java, and how is it different from other objects?
String is a sequence of characters. But in Java, string is an object that represents a sequence of
characters. The java.lang.String class is used to create a string object. String is an immutable and
provides various methods for string manipulation.
1. By string literal
2. By new keyword
1) String Literal
1. String s="welcome";
2. String s1="Welcome"; String s2="Welcome";//It doesn't create a new instance
By new keyword
In such case, JVM will create a new string object in normal (non-pool) heap memory, and the
literal "Welcome" will be placed in the string constant pool. The variable s will refer to the
object in a heap (non-pool).
wait()
notify()
notifyAll()
wait() method
The wait() method causes current thread to release the lock and wait until either another thread
invokes the notify() method or the notifyAll() method for this object, or a specified amount of
time has elapsed.
notify() method
The notify() method wakes up a single thread that is waiting on this object's monitor. If any
threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary
and occurs at the discretion of the implementation.
Syntax:
notifyAll() method
Syntax:
6. What are the methods for suspending, resuming, and stopping threads in Java?
You can develop a multithreaded program which can be suspended, resumed, or stopped completely
based on your requirements. There are various static methods which you can use on thread objects to
control their behavior.
This method puts a thread in the suspended state and can be resumed
public void suspend() using resume() method.
public void stop() This method stops a thread completely.
This method resumes a thread, which was suspended using
public void resume()
suspend() method.
1a) Write a program to implement producer and consumer problem by using Multithreading.
class Q
{
int n;
boolean valueSet = false;
synchronized int get()
{
while(!valueSet)
try {
wait();
}
catch(InterruptedException e)
{
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
} //end of the get() method
synchronized void put(int n)
{
while(valueSet)
try {
wait();
}
catch(InterruptedException e)
{
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
} //end of the put method
} //end of the class Q
class Producer implements Runnable
Q q;
Producer(Q q)
{
this.q = q;
new Thread(this, "Producer").start();
}
public void run()
{
int i = 0;
while(true)
{
q.put(i++);
}
}
} //end of Producer
class Consumer implements Runnable
{
Q q;
Consumer(Q q)
{
this.q = q;
new Thread(this, "Consumer").start();
}
public void run()
{
while(true)
{
q.get();
}
}
}//end of Consumer
class PCFixed
{
public static void main(String args[])
{
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
Output:
Put : 1
Got:1
Put:2
Got:2
Put:3
Got:3
------
------
------
Put:1000
Got :1000
Press ctr1+c to stop
1b) What are the states in the lifecycle of a thread? Explain with a neat diagram.
Thread States (Life-Cycle of a Thread): The life cycle of a thread contains several states. At any time
the thread falls into any one of these states.
Threads exist in several states. A thread can be running. It can be ready to run as soon as it gets CPU
time. A running thread can be suspended, which temporarily suspends its activity. A suspended
thread can then be resumed, allowing it to pick up where it left off. A thread can be blocked when
waiting for a resource. At any time, a thread can be terminated, which halts its execution
immediately. Once terminated, a thread cannot be resumed.
The thread that was just created is in the new state.
The thread remains in this state until the threads start method is called. This causes the
thread to enter the ready state.
The highest priority ready thread enters the running state when system assigns a processor
to the thread i.e., the thread begins executing.
When a running thread calls wait state, then thread enters into a waiting state for the
particular object on which wait was called. Every thread in the waiting state for a given
object becomes ready on a call to notify all by another thread associated with that object.
When a sleep method is called in a running thread that thread enters into the suspended
(sleep) state. A sleeping thread becomes ready after the designated sleep time expires. A
sleeping thread cannot use a processor even if one is available.
A thread enters the terminate state when its run() method completes for any reason. A
terminated thread is eventually be disposed of by the system.
One common way for a running thread to enter the blocked state is when the thread issues
an input or output request. In this case a blocked thread becomes ready when the input or
output waits for completes. A blocked thread can’t use a processor even if one is available.
Creation of threads
We are following different ways to create a new thread by using methods and constructors of the
Thread class.
By inheriting the Thread class
By implementing the Runnable interface.
Declaring a class:Any new class can be declared to extend the Thread class, thus inheriting all the
functionalities of the Thread class.
Class NewThread extends Thread
{
---------
---------
---------
}
Here, we have a new type of thread, named as ‘New Thread’.
Overriding the run() method: The run method has to be overridden by writing codes required for
the thread. The thread behaves as per this code segment . A typical run() method like as below:
public void run()
{
------
// code segment providing the functionality of thread
-------
}
Starting New Thread: The start() method, which is required to create and initiate an instance of our
Thread Class.’
NewThread thread1= new NewThread();
thread1.start();
The first line creates an instance of the class NewThread, where the object is just created. The thread
here is in newborn state.
Second line which calls start() method, moves the thread to runnable state, where the Java Runtime
will schedule the thread to run by invoking the run() method. Now the thread is said to be in running
state.
Example1:- Creating a thread using the Thread Class.
class One extends Thread{
public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
One t1=new One();
t1.start();
}
}
Output:thread is running...
Example2:- Creating a thread using the Thread Class.
class Mythread extends Thread
{
public void run()
{
for(int i=0;i<=10;i++)
{
System.out.println("child Thread");
}
}
}
class ThreadDemoO
{
public static void main(String args[])
{
Mythread t=new Mythread();
t.start();
for(int i=0;i<=10;i++)
{
System.out.println("Main Thread");
}
}
2a) Explain the String class and its key methods for manipulating strings.
The String class in Java is one of the most commonly used classes and is used to represent sequences
of characters. It is part of the java.lang package and provides various methods for manipulating
strings. Strings in Java are immutable, meaning once a String object is created, its value cannot be
changed. Any operation that seems to modify a string actually creates a new String object.
some of the key methods provided by the String class:
length()
Returns the number of characters in the string.
Example:
String str = "Hello, World!";
int length = str.length();
charAt(int index)
trim()
Removes leading and trailing whitespace from the string.
equals() checks if two strings have the same content, considering case.
equalsIgnoreCase() checks if two strings are equal, ignoring case differences.
indexOf() returns the index of the first occurrence of the specified substring.
lastIndexOf() returns the index of the last occurrence.
If the substring is not found, these methods return -1.
2b) Discuss thread priority in Java and its impact on thread scheduling
THREAD PRIORITY: Each thread has a set priority, which helps the scheduler to decide the order
of sequence of thread execution,i.e) which thread should run when?. By default the threads created,
carry the same priority due to which the java scheduler schedules them for processor on first come
first serve basis. It is to be noted that java follows preemptive scheduling policy, like as an operating
system. When a high priority thread becomes ready for execution, the currently low-priority thread
will be stopped. Low priority thread has to wait until the high priority thread is dead or blocked
because of some reason or other. The reason for this can be any one of the following:
Thread stops as soon as it exits run()
It sleeps (by using sleep())
It waits (by using wait() or join())
Once it resumes from the blocked state, it will again preempt the low priority thread to which it had
relinquished its control earlier, thus forcing the low priority to move to the Runnable state from the
running state.
As shown in the below table, the Thread class has a method setPriority(), responsible for setting the
priority of thread by programmer. The signature of the method is:
final void setPriority(int x)
Where x specifies the value used to signify the thread’s priority. Thread class define several
predefined priority constants(as static final variables) as under, Table: Priority constants and their
corresponding value for threads
Thus priorities can be set from 1 to 10. If any is not created (assigned externally, by default it is set to
NORM_PRIORITY i.e) 5 for threads.
A thread’s current priority can be obtained by the getpriority() method of thread class which returns
an integer value.
import java.util.Arrays;
import java.util.Scanner;
scanner.close();
}
}
4a) Write a java program that prints numbers from 1 to10 line by line after every 5 seconds.
Output:
1
(wait for 5 seconds)
2
(wait for 5 seconds)
3
(wait for 5 seconds)
4
(wait for 5 seconds)
5
(wait for 5 seconds)
6
(wait for 5 seconds)
7
(wait for 5 seconds)
8
(wait for 5 seconds)
9
(wait for 5 seconds)
10
1. isAlive():
Program:
System.out.println("Thread is running...");
});
thread.start();
System.out.println("Is the thread alive? " + thread.isAlive()); // Checks if the thread is alive
2. join():
Makes the current thread wait until the specified thread has completed its execution.
Helps ensure that one thread completes before others continue, especially if the result
of one thread is needed by another.
Variants include join(milliseconds) to specify a wait time.
Program:
});
thread.start();
try {
} catch (InterruptedException e) {
e.printStackTrace();
3. sleep():
Pauses the execution of the current thread for a set time (in milliseconds).
Throws InterruptedException if the thread is interrupted while sleeping.
Often used to control timing or delay operations in a thread.
Program:
System.out.println("Message 1");
try {
Thread.sleep(3000); // Pause for 3 seconds
} catch (InterruptedException e) {
e.printStackTrace();
4. main():
Program:
System.out.println(arg);
}
5. Explain the difference between String, String Buffer and String Builder classes.
1. String
Description: String is an immutable class, meaning once a String object is created, it cannot be
modified. If any changes are made, a new String object is created in memory.
Mutability: Immutable – does not allow modification of the existing object.
Thread-Safety: Safe for multi-threading because it’s immutable.
Performance: Slower when performing many string manipulations (e.g., concatenations), as
new objects are created for each modification.
Usage: Suitable for scenarios where the string value does not change frequently, such as
constants and simple messages.
Example:
str = str + " World"; // A new "Hello World" object is created in memory
2. StringBuffer
3. StringBuilder
Description: Similar to StringBuffer but without thread-safety. It is also mutable and designed
for use in single-threaded scenarios where frequent modifications to strings are needed.
Mutability: Mutable – allows modification without creating new objects.
Thread-Safety: Not thread-safe, as it lacks synchronization, making it faster in single-threaded
environments.
Performance: Faster than both String and StringBuffer for single-threaded cases with frequent
modifications.
Usage: Best suited for single-threaded applications where strings are modified often, such as
in loops or intensive string processing tasks.
Example
6) In how many ways a thread can be implemented? Demonstrate any one technique with
suitable example.
You can create a new thread by creating a class that extends the Thread class and overriding its
run() method. This method contains the code that will execute when the thread starts.
Alternatively, you can create a thread by implementing the Runnable interface. This involves
creating a class that implements the Runnable interface and overriding the run() method. The
Runnable instance is then passed to a Thread object.
@Override
try {
} catch (InterruptedException e) {
e.printStackTrace();
1. Extend Thread Class: The MyThread class extends Thread and overrides the run() method. The
run() method contains the code that will be executed by the thread.
2. Create Instances: In the main method, two instances of MyThread are created.
3. Start Threads: The start() method is called on each thread instance, which invokes the run()
method in a new thread of execution.
4. Output: Each thread prints its name and a count from 1 to 5, pausing for 1 second between
each count.
Thread synchronization is a mechanism that ensures that multiple threads do not simultaneously
execute critical sections of code that can lead to data inconsistency. This is particularly important
in a multithreading environment where shared resources are accessed by multiple threads.
In this example, we will demonstrate thread synchronization using a shared bank account where
multiple threads attempt to withdraw money simultaneously.
class BankAccount {
try {
} catch (InterruptedException e) {
e.printStackTrace();
balance -= amount;
} else {
this.account = account;
@Override
account.withdraw(700);
}
}
thread1.start();
thread2.start();
1. BankAccount Class: This class contains a synchronized method withdraw(), which ensures that
only one thread can execute this method at a time. This prevents simultaneous modifications
to the balance variable.
2. WithdrawThread Class: This class extends Thread and represents a thread that attempts to
withdraw money from the shared bank account. The run() method calls the withdraw()
method of the BankAccount instance.
3. Synchronization Mechanism: The synchronized keyword in the withdraw() method ensures
that when one thread is executing this method, any other thread that tries to execute it will
be blocked until the first thread finishes its execution.
4. Creating and Starting Threads: In the main() method, we create an instance of BankAccount
and two WithdrawThread instances, each attempting to withdraw money from the same
account. Both threads are started, which means they will execute concurrently.
Sample Output
The output will vary, but it will show how synchronization prevents the two threads from
modifying the shared balance at the same time:
In multithreaded programming, deadlock and race conditions are two common problems that can
lead to unexpected behavior and application failures. Here's a detailed explanation of both concepts:
1. Deadlock
Definition: A deadlock occurs when two or more threads are blocked forever, each waiting for a
resource that the other thread holds. This situation creates a cycle of dependencies that cannot be
resolved, effectively halting the execution of the threads involved.
Causes of Deadlock:
Deadlocks typically arise from the following conditions, often referred to as the Coffman conditions:
1. Mutual Exclusion: At least one resource must be held in a non-shareable mode. Only one
thread can use the resource at any given time.
2. Hold and Wait: A thread holding at least one resource is waiting to acquire additional
resources that are currently being held by other threads.
3. No Preemption: Resources cannot be forcibly taken from threads holding them; they must
voluntarily release them.
4. Circular Wait: A circular chain of threads exists, where each thread is waiting for a resource
that the next thread in the chain holds.
Example Program:
class Resource {
private final String name;
public Resource(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class DeadlockExample implements Runnable {
private final Resource resource1;
private final Resource resource2;
public DeadlockExample(Resource resource1, Resource resource2) {
this.resource1 = resource1;
this.resource2 = resource2;
}
@Override
public void run() {
synchronized (resource1) {
System.out.println(Thread.currentThread().getName() + " locked " + resource1.getName());
try {
// Simulate some work with resource1
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource2) {
System.out.println(Thread.currentThread().getName() + " locked " + resource2.getName());
}
}
}
public static void main(String[] args) {
Resource resourceA = new Resource("Resource A");
Resource resourceB = new Resource("Resource B");
Thread thread1 = new Thread(new DeadlockExample(resourceA, resourceB), "Thread 1");
Thread thread2 = new Thread(new DeadlockExample(resourceB, resourceA), "Thread 2");
thread1.start();
thread2.start();
}
}
Output
The output will show that both threads are locked, waiting indefinitely for each other, causing a
deadlock.
2. Race Conditions
Definition: A race condition occurs when two or more threads access shared data and try to change it
at the same time. If the threads are not synchronized properly, the final value of the shared data may
depend on the sequence or timing of how the threads are scheduled, leading to unpredictable results.
Causes of Race Conditions
Race conditions occur primarily due to:
Lack of synchronization when accessing shared resources.
The non-atomic operations on shared variables.
Example Program:
class Counter {
private int count = 0;
public void increment() {
count++; // Non-atomic operation
}
public int getCount() {
return count;
}
}
class RaceConditionExample implements Runnable {
private final Counter counter;
public RaceConditionExample(Counter counter) {
this.counter = counter;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
}
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread thread1 = new Thread(new RaceConditionExample(counter));
Thread thread2 = new Thread(new RaceConditionExample(counter));
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Final Count: " + counter.getCount()); // Expected: 2000
}
}
Output
The output may not always show Final Count: 2000 due to the race condition, demonstrating that the
final count may vary depending on the timing of thread execution.