0% found this document useful (0 votes)
16 views68 pages

Java Module 2

BCS306A OOPS WITH JAVA

Uploaded by

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

Java Module 2

BCS306A OOPS WITH JAVA

Uploaded by

abduljabbar.k
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 68

MODULE 2

 Introducing Classes: Class Fundamentals,


Declaring Objects, Assigning Object Reference
Variables, Introducing Methods, Constructors, The
this Keyword, Garbage Collection.
 Methods and Classes: Overloading Methods,
Objects as Parameters, Argument Passing, Returning
Objects, Recursion, Access Control, Understanding
static, Introducing final, Introducing Nested and
Inner Classes.
Class Fundamentals

 Class defines a new data type


 Class can be used to create objects of that type.
 Class is a template for an object, and an object
is an instance of a class.
 Class is declared by use of the class keyword
 The data, or variables, defined within a class
are called instance variables
 The code is contained within methods
 Methods and variables defined within a class
are called members of the class
The General Form of a Class

class classname {
type instance-variable1;
type instance-variable2;
...
type instance-variableN;

type methodname1(parameter-list)
{ body of method }

type methodname2(parameter-list)
{ body of method }
...
type methodnameN(parameter-list)
{ body of method }
}
A Simple Class
class Box
{
double width;
double height;
double depth;
}
To create a Box object,
Box mybox = new Box();
 To access class variables, dot (.) operator is used.
 The dot operator links the name of the object with the name of an
instance variable
 For example, mybox.width = 100;
/* A program that uses the Box class.
Call this file BoxDemo.java*/
class Box {
double width;
double height;
double depth;
}
// This class declares an object of type Box.
class BoxDemo {
public static void main(String args[]) {
Box mybox = new Box();
double vol;
// assign values to mybox's instance variables
mybox.width = 10;
mybox.height = 20;
mybox.depth = 15;
// compute volume of box
vol = mybox.width * mybox.height * mybox.depth;
System.out.println("Volume is " + vol);
}
}
// This program declares two Box objects.
class Box {
double width;
double height;
double depth; }

class BoxDemo2 {
public static void main(String args[]) {
Box mybox1 = new Box();
Box mybox2 = new Box();
double vol;
mybox1.width = 10; //assign values to mybox1's instance variables
mybox1.height = 20;
mybox1.depth = 15;
mybox2.width = 3; //assign values to mybox1's instance variables
mybox2.height = 6;
mybox2.depth = 9;
// compute volume of first box
vol = mybox1.width * mybox1.height * mybox1.depth;
System.out.println("Volume is " + vol);
// compute volume of second box
vol = mybox2.width * mybox2.height * mybox2.depth;
System.out.println("Volume is " + vol);
} }
Declaring Objects
 Obtaining objects of a class is a two-step process.
 First, you must declare a variable of the class type.
 This variable does not define an object.
 It is simply a variable that can refer to an object.
 Second, you must acquire an actual, physical copy of the object and
assign it to that variable using new operator.
 The new operator dynamically allocates (that is, allocates at run time)
memory for an object and returns a reference to it.
 This reference is then stored in the variable
 Box mybox; // declare reference to object
 mybox = new Box(); // allocate a Box object
 We can combine both statements
Box mybox = new Box();
Assigning Object Reference Variables
 What do you think the following fragment does?
Box b1 = new Box();
Box b2 = b1;
What happens here ?
Box b1 = new Box();
Box b2 = b1;
// ...
b1 = null;
Introducing Methods
 General form of a method:
type name(parameter-list)
{
// body of method
}
 type specifies the type of data returned by the method
 any valid type, including class types that you create
 If the method does not return a value, its return type must be void
 The name of the method is specified by name
 The parameter-list is a sequence of type and identifier pairs separated
by commas
 If the method has no parameters, then the parameter list will be empty.
 To return a value to the calling routine using return statement can be
used.
 Eg:- return value;
Adding a Method to the Box Class
class Box { double width;
double height;
double depth;
void volume() {
System.out.print("Volume is ");
System.out.println(width * height * depth);
}}
class BoxDemo3 {
public static void main(String args[]) {
Box mybox1 = new Box();
Box mybox2 = new Box();
mybox1.width = 10; // assign values to mybox1's instance variables
mybox1.height = 20;
mybox1.depth = 15;
mybox2.width = 3; /*assign different values to mybox2’s instance variables*/
mybox2.height = 6;
mybox2.depth = 9;
mybox1.volume(); // display volume of first box
mybox2.volume(); // display volume of second box
Returning a Value
class Box { double width;

double height;

double depth;

double volume() // compute and return volume

{ return width * height * depth; } }

class BoxDemo4 {

public static void main(String args[]) {

Box mybox1 = new Box();

Box mybox2 = new Box();

double vol;

mybox1.width = 10; // assign values to mybox1's instance variables

mybox1.height = 20;

mybox1.depth = 15;

mybox2.width = 3; /* assign different values to mybox2’s instance variables */

mybox2.height = 6;

mybox2.depth = 9;

vol = mybox1.volume(); // get volume of first box

System.out.println("Volume is " + vol);

vol = mybox2.volume(); // get volume of second box

System.out.println("Volume is " + vol);

} }
Method That Takes Parameters
class Box {
double width;
double height;
double depth;
double volume() {
return width * height * depth; }
void setDim(double w, double h, double d) {
width = w;
height = h;
depth = d; } }
class BoxDemo5 {
public static void main(String args[]) {
Box mybox1 = new Box();
Box mybox2 = new Box();
double vol;
mybox1.setDim(10, 20, 15);
mybox2.setDim(3, 6, 9);
vol = mybox1.volume();
System.out.println("Volume is " + vol);
vol = mybox2.volume();
System.out.println("Volume is " + vol);
Constructors

 setDim( ) is used to initialize the objects


 Because the requirement for initialization is so common, Java
allows objects to initialize themselves when they are created
 Automatic initialization is performed through the use of a
constructor.
 A constructor initializes an object immediately upon creation
 It has the same name as the class in which it resides and is
syntactically similar to a method
 A constructor is automatically called immediately after the object is
created
 It doesn’t have return type, not even void.
class Box {
double width;
double height;
double depth;
Box()
// This is the constructor for Box.
{ System.out.println("Constructing Box");
width = 10;
height = 10;
depth = 10; }
double volume() {
return width * height * depth; } }
class BoxDemo6 {
public static void main(String args[]) {
Box mybox1 = new Box(); // declare, allocate, and initialize Box objects
Box mybox2 = new Box();
double vol;
vol = mybox1.volume(); // get volume of first box
System.out.println("Volume is " + vol);
vol = mybox2.volume(); // get volume of second box
Default constructor
 Default constructor is a no-argument constructor that is automatically
provided by the Java compiler if no constructors are explicitly defined in a
class.
 Its purpose is to initialize objects of the class.
 If no constructor is defined in a class, Java automatically provides a
default constructor.
 If a constructor is defined, the default constructor is not provided
automatically anymore.
 Characteristics of the default constructor:
 It has no parameters.
 It typically assigns default values to object attributes
 0 for numeric types
 null for reference types
 false for Boolean
class Car {
String model;
int year;
// Default constructor (automatically created by Java)
}
public class Main {
public static void main(String[] args) {
Car car = new Car(); // Default constructor is called
System.out.println(car.model); // null (default value for String)
System.out.println(car.year); // 0 (default value for int)
}
}
OUTPUT:
null
0
No-Argument Constructor (User-defined)
 A constructor with no parameter that we explicitly define.
 Typically used when you want to perform certain actions upon object
creation, like setting default values.
class Car {
String model;
int year;
// No-argument constructor (user-defined)
Car() {
model = "Unknown";
year = 2024;
} }
public class Main {
public static void main(String[] args) {
Car car = new Car(); // Calls the no-argument
constructor
System.out.println(car.model); // Outputs "Unknown"
System.out.println(car.year); // Outputs 2024
} }
Parameterized Constructors
 A constructor that takes one or more arguments
 Used to initialize objects with specific values when created.
class Car {
String model;
int year;
// Parameterized constructor
Car(String model, int year) {
this.model = model;
this.year = year;
} }
public class Main {
public static void main(String[] args) {
Car car = new Car("Tesla", 2024); // Calls parameterized constructor
System.out.println(car.model); // Outputs "Tesla"
System.out.println(car.year); // Outputs 2024
} }
Copy Constructor
 A constructor that creates an object by copying the attributes from another object of the
same class.
 Java doesn’t provide a built-in copy constructor, but we can create one manually.
class Car {
String model;
int year;
Car(String model, int year) // Parameterized constructor
{ this.model = model;
this.year = year; }
Car(Car otherCar) // Copy constructor
{ this.model = otherCar.model;
this.year = otherCar.year;
} }
public class Main {
public static void main(String[] args) {
Car car1 = new Car("Tesla", 2024); // Calls parameterized constructor
Car car2 = new Car(car1); // Calls copy constructor
System.out.println(car2.model); // Outputs "Tesla"
System.out.println(car2.year); // Outputs 2024
} }
 Summary of Constructor Types:
1. Default Constructor: Automatically provided if no other
constructors exist.
2. No-Argument Constructor: Explicitly defined without
parameters.
3. Parameterized Constructor: Takes arguments to initialize
fields.
4. Copy Constructor: Initializes an object using another object
of the same class.
this keyword
 this keyword is a reference variable that
refers to the current object.
 i.e., the object on which the method or
constructor is being called.
 It is widely used in various contexts to
differentiate between instance variables and
parameters, call constructors, or return the
current object.
class Car {
String model;
int year;
// Constructor with parameters having the same name as instance variables
Car(String model, int year) {
this.model = model; // 'this.model' refers to the instance variable
this.year = year; } // 'year' on the right is the parameter
void displayInfo() {
System.out.println("Model: " + this.model);
System.out.println("Year: " + this.year);
} }
public class Main {
public static void main(String[] args) {
Car car1 = new Car("Tesla", 2024);
car1.displayInfo();
} }
OUTPUT:
Model: Tesla
Year: 2024
Passing the Current Object as an Argument
 we can pass the current object (the object the method is being called on) as an
argument to another method or constructor using this keyword
class Car {
String model;
int year;
Car(String model, int year) {
this.model = model;
this.year = year; }
void printCarInfo(Car car) {
System.out.println("Model: " + car.model + ", Year: " + car.year);
}
void display() {
printCarInfo(this); // Passing current object to printCarInfo()
method
} }
public class Main {
public static void main(String[] args) {
Car car = new Car("Tesla", 2024);
car.display(); // Outputs: Model: Tesla, Year: 2024
Returning the Current Object
 this keyword can be used to return the current object from a method.
class Car {
String model;
int year;
Car setModel(String model)
{ this.model = model;
return this; // Return the current object
}
Car setYear(int year)
{ this.year = year;
return this; // Return the current object
}
void displayInfo()
{ System.out.println("Model: " + model + ", Year: " + year);
} }
public class Main {
public static void main(String[] args) {
Car car = new Car();
// Method chaining using 'this'

car.setModel("Tesla").setYear(2024).displayInfo(); // Outputs: Model: Tesla, Year: 2024


 Method Chaining in Java is a technique where multiple methods are
called in a single line of code, one after the other, by returning the current
object (using this) from each method. This pattern is commonly used in
Java to write concise and readable code, particularly when multiple
operations are to be performed on the same object.
 Key Idea:
 Each method returns the current instance (using this) so that another
method can be called on it immediately. This results in a chain of method
calls, hence the term "method chaining."
Garbage Collection
 Java manages memory automatically, so developers don't need to
explicitly free memory as in languages like C or C++
 Garbage Collection (GC) in Java is the process by which the Java Virtual
Machine (JVM) automatically reclaims memory by removing objects that
are no longer being used or referenced by a program.
 This allows developers to manage memory indirectly, as the JVM takes
care of freeing up unused memory, preventing memory leaks
 The JVM uses sophisticated algorithms to free up memory, allowing
applications to run smoothly without excessive memory consumption.
The finalize( ) Method
 finalize() method provides a mechanism to perform cleanup before the
object is destroyed by the garbage collector. It can be used to release
resources like file handles, database connections, etc.
 The garbage collector calls the finalize() method on an object when
it determines that there are no more references to the object, and it is
eligible for garbage collection.
 It is usually overridden to clean up resources (like closing file
streams or releasing database connections)
 The method is called at most once by the garbage collector on an
object.
Overloading Methods
 In Java it is possible to define two or more methods within the same class that
share the same name, with different parameter declarations.
 These methods are said to be overloaded, and the process is referred to as
method overloading.
 Method overloading is one of the ways that Java supports polymorphism.
 When an overloaded method is invoked, Java uses the type and/or number of
arguments to determine which version of the overloaded method to actually
call.
 Overloaded methods must differ in the type and/or number of their
parameters.
 Overloaded methods may have different return types, but the return type alone
is insufficient to distinguish two versions of a method.
 When Java encounters a call to an overloaded method, it simply executes the
version of the method whose parameters match the arguments used in the call.
class OverloadDemo {
void test() {
System.out.println("No parameters"); }
void test(int a) // Overload test for one integer parameter.
{ System.out.println("a: " + a); }
void test(int a, int b) // Overload test for two integer parameters.
{ System.out.println("a and b: " + a + " " + b); }
double test(double a) // overload test for a double parameter
{ System.out.println("double a: " + a);
return a*a; } }
class Overload {
public static void main(String args[]) {
OverloadDemo ob = new OverloadDemo();
double result;
ob.test(); // call all versions of test()
ob.test(10);
ob.test(10, 20);
result = ob.test(123.25);
System.out.println("Result of ob.test(123.25): " + result);
} }
The program generates the following output:
No parameters
a: 10
a and b: 10 20
double a: 123.25
Result of ob.test(123.25): 15190.5625
 When an overloaded method is called, Java looks for a match
between the arguments used to call the method and the method’s
parameters
 This match need not always be exact.
 In some cases, Java’s automatic type conversions can play a role in
overload resolution.
// Automatic type conversions apply to overloading.
class OverloadDemo {
void test() {
System.out.println("No parameters"); }
void test(int a, int b) // Overload test for two integer parameters.
{ System.out.println("a and b: " + a + " " + b); }
void test(double a) // overload test for a double parameter
{ System.out.println("Inside test(double) a: " + a);
} }
class Overload {
public static void main(String args[]) {
OverloadDemo ob = new OverloadDemo();
int i = 88;
ob.test();
ob.test(10, 20);
ob.test(i); // this will invoke test(double)
ob.test(123.2); // this will invoke test(double)
} }
 The program generates the following output:
No parameters
a and b: 10 20
Inside test(double) a: 88
Inside test(double) a: 123.2
Overloading Constructors
 In addition to overloading normal methods, you can
also overload constructor methods.
class Box {
double width;
double height;
double depth;
Box(double w, double h, double d) // constructor used when all dimensions specified
{ width = w;
height = h;
depth = d; }
Box() // constructor used when no dimensions specified
{ width = -1; // use -1 to indicate
height = -1; // an uninitialized
depth = -1; // box }
Box(double len) // constructor used when cube is created
{ width = height = depth = len; }
double volume() // compute and return volume
{ return width * height * depth;
class OverloadCons {
public static void main(String args[]) {
Box mybox1 = new Box(10, 20, 15); // create boxes using the various constructors
Box mybox2 = new Box();
Box mycube = new Box(7);
double vol;
vol = mybox1.volume(); // get volume of first box
System.out.println("Volume of mybox1 is " + vol);
vol = mybox2.volume(); // get volume of second box
System.out.println("Volume of mybox2 is " + vol);
vol = mycube.volume(); // get volume of cube
System.out.println("Volume of mycube is " + vol);
}}
The output produced by this program is shown here:
Volume of mybox1 is 3000.0
Volume of mybox2 is -1.0
Volume of mycube is 343.0
Using Objects as Parameters
 In Java, objects can be passed as parameters to methods in a way
similar to primitive data types.
 One of the most common uses of object parameters
involves constructors.
 If we want to construct a new object so that it is
initially the same as some existing object.
 To do this, you must define a constructor that takes an
object of its class as a parameter.
class Box {

double width;

double height;

double depth;

// Notice this constructor. It takes an object of type Box.

Box(Box ob) {

width = ob.width;

height = ob.height;

depth = ob.depth; }

Box(double w, double h, double d) // constructor used when all dimensions specified

{ width = w;

height = h;

depth = d; }

Box() // constructor used when no dimensions specified

{ width = -1; // use -1 to indicate an uninitialized box

height = -1;

depth = -1; }

Box(double len) // constructor used when cube is created

{ width = height = depth = len; }

double volume() // compute and return volume

{ return width * height * depth; }

}
class OverloadCons2 {
public static void main(String args[]) {
// create boxes using the various constructors
Box mybox1 = new Box(10, 20, 15);
Box mybox2 = new Box();
Box mycube = new Box(7);
Box myclone = new Box(mybox1); // create copy of mybox1
double vol;
// get volume of first box
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
// get volume of second box
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
// get volume of cube
vol = mycube.volume();
System.out.println("Volume of cube is " + vol);
// get volume of clone
vol = myclone.volume();
System.out.println("Volume of clone is " + vol);
}
}
Argument Passing
 There are two ways that a computer language can pass an argument to
a subroutine.
 call-by-value and call-by-reference.
 In call by value approach, it copies the value of an argument into the
formal parameter of the subroutine.
 ie, changes made to the parameter of the subroutine have no effect on
the argument.
 In call by reference approach, a reference to an argument (not the value
of the argument) is passed to the parameter. Inside the subroutine, this
reference is used to access the actual argument specified in the call.
 ie, changes made to the parameter will affect the argument used to call
the subroutine.
 Java uses both approaches, depending upon what is passed.
 when you pass a primitive type to a method, it is passed by value.
 Thus, what occurs to the parameter that receives the argument has no effect
outside the method.
class Test {
void meth(int i, int j) {
i *= 2;
j /= 2;
} }
class CallByValue {
public static void main(String args[]) {
Test ob = new Test();
int a = 15, b = 20;
System.out.println("a and b before call: " +a + " " + b);
ob.meth(a, b);
System.out.println("a and b after call: " +a + " " + b);
} }
a and b before call: 15 20
a and b after call: 15 20
 When you pass an object to a method, it is passed by call-by-
reference
 When you create a variable of a class type, you are only creating
a reference to an object.
 When you pass this reference to a method, the parameter that
receives it will refer to the same object as that referred to by the
argument.
 This means that objects are passed to methods by use of call-by-
reference.
 Changes to the object inside the method do affect the object
used as an argument.
class Test {
int a, b;
Test(int i, int j)
{ a = i;
b = j; }
void meth(Test o) // pass an object
{ o.a *= 2;
o.b /= 2;
} }
class CallByRef {
public static void main(String args[]) {
Test ob = new Test(15, 20);
System.out.println("ob.a and ob.b before call: " +ob.a + " " + ob.b);
ob.meth(ob);
System.out.println("ob.a and ob.b after call: " +ob.a + " " + ob.b);
} }
ob.a and ob.b before call: 15 20
Returning Objects
 A method can return any type of data, including class types that you
create.
 For example, in the following program, the incrByTen( ) method returns
an object in which the value of a is ten greater than it is in the invoking
object.
// Returning an object.
class Test {
int a;
Test(int i)
{
a = i;
}
Test incrByTen()
{
Test temp = new Test(a+10);
return temp;
}
class RetOb
{
public static void main(String args[]) {
Test ob1 = new Test(2);
Test ob2;
ob2 = ob1.incrByTen();
System.out.println("ob1.a: " + ob1.a);
System.out.println("ob2.a: " + ob2.a);
ob2 = ob2.incrByTen();
System.out.println("ob2.a after second increase: "+ ob2.a);
}
}

ob1.a: 2
ob2.a: 12
Recursion
 Java supports recursion.
 Recursion is the process of defining something in terms of
itself.
 Recursion is the attribute that allows a method to call itself.
 A method that calls itself is said to be recursive
 The classic example of recursion is the computation of the
factorial of a number.
 The factorial of a number N is the product of all the whole
numbers between 1 and N.
class Factorial {
int fact(int n) // this is a recursive method
{ int result;
if(n==1) return 1;
result = fact(n-1) * n;
return result;
} }
class Recursion {
public static void main(String args[]) {
Factorial f = new Factorial();
System.out.println("Factorial of 3 is " + f.fact(3));
System.out.println("Factorial of 4 is " + f.fact(4));
System.out.println("Factorial of 5 is " + f.fact(5));
} }
Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 5 is 120
class RecTest {
int values[];
RecTest(int i) {
values = new int[i];
}
// display array -- recursively
void printArray(int i)
{
if(i==0) return;
else printArray(i-1);
System.out.println("[" + (i-1) + "] " + values[i-1]);
} }
class Recursion2
{
public static void main(String args[]) {
RecTest ob = new RecTest(10);
int i;
for(i=0; i<10; i++) ob.values[i] = i;
ob.printArray(10);
} }
[0] 0
[1] 1
[2] 2
[3] 3
[4] 4
[5] 5
[6] 6
[7] 7
[8] 8
[9] 9
Access Control
 Encapsulation provides another important attribute: access control
 Through encapsulation, we can control what parts of a program can
access the members of a class.
 By controlling access, we can prevent misuse.
 Allowing access to data only through a well defined set of methods, you
can prevent the misuse of that data.
 How a member can be accessed is determined by the access specifier
that modifies its declaration.
 Java supplies a rich set of access specifiers. Some aspects of access
control are related mostly to inheritance or packages
Access Control
 Java’s access specifiers are public, private, and protected
 protected applies only when inheritance is involved
 When a member of a class is modified by the public specifier, then that
member can be accessed by any other code.
 When a member of a class is specified as private, then that member can
only be accessed by other members of its class.
 When no access specifier is used, then by default the member of a class is
public within its own package, but cannot be accessed outside of its package.
 An access specifier precedes the rest of a member’s type specification. That
is, it must begin a member’s declaration statement.
 For example:
public int i;
private double j;
private int myMethod(int a, char b) { // ...

 Why main( ) has always been preceded by the public specifier ?


 It is called by code that is outside the program—that is, by the Java run-time
system.
/* This program demonstrates the difference between public and private */
class Test {
int a; // default access
public int b; // public access
private int c; // private access
void setc(int i) // methods to access c
{ // set c's value
c = i; }
int getc() // get c's value
{ return c; } }
class AccessTest {
public static void main(String args[]) {
Test ob = new Test();
ob.a = 10; // These are OK, a and b may be accessed directly
ob.b = 20;
// ob.c = 100; // This is not OK and will cause an error // Error!
// You must access c through its methods
ob.setc(100); // OK
System.out.println("a, b, and c: " + ob.a + " " +ob.b + " " + ob.getc());
} }
Understanding static
 Normally, a class member must be accessed only in conjunction with an
object of its class.
 But it is possible to create a member that can be used by itself, without
reference to a specific instance.
 To create such a member, precede its declaration with the keyword static.
 When a member is declared static, it can be accessed before any objects of
its class are created, and without reference to any object.
 You can declare both methods and variables to be static.
 The most common example of a static method is main( ).
 main( ) is declared as static because it must be called before any objects
exist.
Understanding static
 Instance variables declared as static are global variables.
 When objects of its class are declared, no copy of a static variable is
made.
 Instead, all instances of the class share the same static variable.
 Methods declared as static have several restrictions:
 They can only call other static methods
 They must only access static data.
 They cannot refer to this or super in any way.
 If you need to do computation in order to initialize your static variables,
you can declare a static block that gets executed exactly once, when
the class is first loaded.
class UseStatic {
static int a = 3;
static int b;
static void meth(int x)
{ System.out.println("x = " + x);
System.out.println("a = " + a);
System.out.println("b = " + b); }
static {
System.out.println("Static block initialized.");
b = a * 4; }
public static void main(String args[]) {
meth(42);
} }
Static block initialized.
x = 42
a = 3
 Outside of the class in which they are defined, static methods and
variables can be used independently of any object.
 We need only specify the name of their class followed by the dot operator.
 For example, if you wish to call a static method from outside its class, you
can do so using the following general form:
 classname.method( )
 classname is the name of the class in which the static method is declared.
class StaticDemo {
static int a = 42;
static int b = 99;
static void callme() {
System.out.println("a = " + a);
} }
class StaticByName {
public static void main(String args[]) {
StaticDemo.callme();
System.out.println("b = " + StaticDemo.b);
}
}
output:
a = 42
b = 99
Introducing final
 A variable can be declared as final. This prevents its contents from being
modified. This means that you must initialize a final variable when it is
declared.
 For example:
final int FILE_NEW = 1;
final int FILE_OPEN = 2;
final int FILE_SAVE = 3;
final int FILE_SAVEAS = 4;
final int FILE_QUIT = 5;
 Later parts of our program, we can use FILE_OPEN, etc., as if they were
constants.
 It is a common coding convention to choose all uppercase identifiers for
final variables.
 Variables declared as final do not occupy memory on a per-instance basis.
 final variable is essentially a constant.
Nested and Inner Classes

 It is possible to define a class within another class; such classes are known
as nested classes.
 The scope of a nested class is bounded by the scope of its enclosing class.
 If class B is defined within class A, then B does not exist independently of
A.
 A nested class has access to the members, including private members, of
the class in which it is nested.
 The enclosing class does not have access to the members of the nested
class.
 A nested class that is declared directly within its enclosing class scope is a
member of its enclosing class.
 It is also possible to declare a nested class that is local to a block.
Nested and Inner Classes
 There are two types of nested classes: static and non-
static.
 A static nested class is one that has the static modifier
applied.
 Because it is static, it must access the members of its
enclosing class through an object. That is, it cannot refer to
members of its enclosing class directly.
 Because of this restriction, static nested classes are seldom
used.
 An inner class is a non-static nested class.
 It has access to all of the variables and methods of its outer
class and may refer to them directly in the same way that
other non-static members of the outer class do.
// Demonstrate an inner class.
class Outer {
int outer_x = 100;
void test() {
Inner inner = new Inner();
inner.display(); }
// this is an inner class
class Inner {
void display() {
System.out.println("display: outer_x = " + outer_x);
} } }
class InnerClassDemo {
public static void main(String args[]) {
Outer outer = new Outer();
outer.test();
} }

display: outer_x = 100


Arrays Revisited
 In Java, arrays have a special field called length that stores the number of
elements in the array.
 It is not a method but a property that you can access directly.
 This property applies only to arrays.
 The value of length has nothing to do with the number of elements that
are actually in use. It only reflects the number of elements that the array is
designed to hold.
// This program demonstrates the length array member.
class Length {
public static void main(String args[]) {
int a1[] = new int[10];
int a2[] = {3, 5, 7, 1, 8, 99, 44, -10};
int a3[] = {4, 3, 2, 1};
System.out.println("length of a1 is " + a1.length);
System.out.println("length of a2 is " + a2.length);
System.out.println("length of a3 is " + a3.length);
}
}
length of a1 is 10
length of a2 is 8
length of a3 is 4
String Class
 String is the most commonly used class in Java’s class library.
 Every string we create is actually an object of type String.
 Even string constants are actually String objects For example, in the statement
System.out.println("This is a String, too");
 the string “This is a String, too” is a String constant.
 The objects of type String are immutable, ie, once a String object is created,
its contents cannot be altered.
 Java defines a peer class of String, called StringBuffer, which allows strings
to be altered.
 Java defines one operator for String objects: +. It is used to concatenate two
strings.
 For example, this statement
String myString = "I" + " like " + "Java.";
 The String class contains several methods:
 equals( ) - You can test two strings for equality
 length( )- You can obtain the length of a string
 charAt( )- You can obtain the character at a specified index within a string
class StringDemo2 {

public static void main(String args[]) {

String strOb1 = "First String";

String strOb2 = "Second String";

String strOb3 = strOb1;

System.out.println("Length of strOb1: " +

strOb1.length());

System.out.println("Char at index 3 in strOb1: " +

strOb1.charAt(3));

if(strOb1.equals(strOb2))

System.out.println("strOb1 == strOb2");

else

System.out.println("strOb1 != strOb2");

if(strOb1.equals(strOb3))

System.out.println("strOb1 == strOb3");

Else

System.out.println("strOb1 != strOb3");

} }

Length of strOb1: 12

Char at index 3 in strOb1: s

strOb1 != strOb2

strOb1 == strOb3
Command-Line Arguments
 In Java, command-line arguments allow you to pass data to your
program when you run it from the command line.
 These arguments are passed to the main method as an array of string
object.
public static void main(String[] args)
 The args array contains the command-line arguments.
 The number of arguments is determined by args.length
 Each argument is accessed through args[index]
public class CommandLineArguments {
public static void main(String[] args) {
// Check if any arguments are passed
if (args.length > 0) {
System.out.println("Command-line arguments:");
// Loop through the arguments and print each one
for (int i = 0; i < args.length; i++) {
System.out.println("Argument " + i + ": " + args[i]);
}
} else {
System.out.println("No command-line arguments passed.");
} } }
javac CommandLineArguments.java
java CommandLineArguments arg1 arg2 arg3
Command-line arguments:
Argument 0: arg1
Argument 1: arg2
Argument 2: arg3

You might also like