History of Java
History of Java
Java programming language was originally developed by Sun Microsystems which was initiated by James
Gosling and released in 1995 as core component of Sun Microsystems' Java platform (Java 1.0 [J2SE]).
History of even naming of the Java is very interesting. It went under many names.
James Gosling was leading a team named as 'Green' team. Target of this team was to create a new project
which can. Initially C++ was the original choice to develop the project. James Gosling wanted to enhance
C++ to achieve the target but due to high memory usage, that idea was rejected and team started with a
new language initially named as GreenTalk. The file extension used as .gt. Later this language was termed
as Oak and finally to Java.
Oak
James Gosling renamed language to Oak. There was an Oak tree in front of his office. James Gosling used
this name as Oak represents solidarity and Oak tree is the national tree of multiple countries like USA,
France, Romania etc. But Oak technologies already had Oak as a trademark and James team had to
brainstorm another title for the language.
Java
Team put multiple names like DNA, Silk, Ruby and Java. Java was finalized by the team. James Gosling
tabled Java title based on type of espresso coffee bean. Java is an island in Indonesia where new coffee
was discovered termed as Java coffee. As per James Gosling, Java was among the top choice along with
Silk. Finally, Java was selected as it was quite unique and represented the essence of being dynamic,
revolutionary and fun to say.
Sun released the first public implementation as Java 1.0 in 1995. It promised Write Once, Run
Anywhere (WORA), providing no-cost run-times on popular platforms.
On 13 November, 2006, Sun released much of Java as free and open-source software under the terms of
the GNU General Public License (GPL).
On 8 May, 2007, Sun finished the process, making all of Java's core code free and open-source, aside from
a small portion of code to which Sun did not hold the copyright.
The latest release of the Java Standard Edition is Java SE 21. With the advancement of Java and its
widespread popularity, multiple configurations were built to suit various types of platforms. For example:
J2EE for Enterprise Applications, J2ME for Mobile Applications.
23 Jan
2 JDK 1.0 A stable variant JDK 1.0.2 was termed as JDK 1
1996
19 Feb Major features like JavaBeans, RMI, JDBC, inner classes were added in
3 JDK 1.1
1997 this release.
8 Dec Swing, JIT Compiler, Java Modules, Collections were introduced to JAVA
4 JDK 1.2
1998 and this release was a great success.
8 May HotSpot JVM, JNDI, JPDA, JavaSound and support for Synthetic proxy
5 JDK 1.3
2000 classes were added.
JDK 1.5 or 30 Sep Various new features were added to the language like foreach, var-args,
7
J2SE 5 2004 generics etc.
11 Dec notation was dropped to SE and upgrades done to JAXB 2.0, JSR 269
8 JAVA SE 6
2006 support and JDBC 4.0 support added.
21 Sep
11 JAVA SE 9 Module system introduced which can be applied to JVM platform.
2017
17 Mar Feature added - Records, a new class type for modelling, Pattern Matching
16 JAVA SE 14
2020 for instanceof, Intuitive NullPointerException handling.
15 Sep Feature added - Sealed Classes, Hidden Classes, Foreign Function and
17 JAVA SE 15
2020 Memory API (Incubator).
16 Mar Feature added as preview - Records, Pattern Matching for switch, Unix
18 JAVA SE 16
2021 Domain Socket Channel (Incubator) etc.
20 Sep Feature added - Record pattern, Vector API (Fourth incubator), Structured
21 JAVA SE 19
2022 Concurrency (Incubator) etc.
1. Object Oriented: In Java, everything is an Object. Java can be easily extended since it is based
on the Object model. As a language that has the Object-Oriented feature, Java supports the
following fundamental concepts of OOPs: Polymorphism, Inheritance, Encapsulation, Abstraction,
Classes, Objects, Instance, Method, Message Passing
2. Platform Independent: Unlike many other programming languages including C and C++, when
Java is compiled, it is not compiled into platform specific machine, rather into platform
independent byte code. This byte code is distributed over the web and interpreted by the Java
Virtual Machine (JVM) on whichever platform it is being run on. Java is designed in Write Once,
Run Anywhere (WORA) way. Code written in Java is not directly dependent on the type of machine
it is running. A code is Java is compiled in ByteCode which is platform independent. Java Virtual
Machine, JVM can understand the byte code. Java provides platform specific JVMs. It is the
responsibility of platform specific JVM to interpret the byte code correctly thus developers are
free to write code without worrying about platforms like windows, linux, unix, Mac etc. This
feature makes Java a platform neutral language. As byte code can be distributed over the web and
interpreted by the Virtual Machine (JVM) on whichever platform it is being run on. It makes java
code highly portable and useful for application running on multiple platforms.
3. Simple: Java is designed to be easy to learn. If you understand the basic concept of OOP Java, it
would be easy to master. Java is very easy to learn. It inherits many features from C, C++ and
removes complex features like pointers, operator overloading, multiple inheritance, explicit
memory allocation etc. It provides automatic garbage collection. With a rich set of libraries with
thousands of useful functions, Java makes developers life easy.
4. Secure: With Java's secure feature it enables to develop virus-free, tamper-free systems.
Authentication techniques are based on public-key encryption. Java is by design highly secure as
it is not asking developers to interact with underlying system memory or operation system.
Bytecode is secure and several security flaws like buffer overflow, memory leak are very rare. Java
exception handling mechanism allows developers to handle almost all type of error/exceptions
which can happen during program execution. Automatic garbage collection helps in maintaining
the system memory space utilization in check.
7. Robust: Java makes an effort to eliminate error prone situations by emphasizing mainly on
compile time error checking and runtime checking. Automatic garbage collection, strong memory
management, no pointers, no direct access to system memory, exception handling, error handling
are some of the key features which makes Java a Robust, strong language to rely on.
8. Multithreaded: With Java's multithreaded feature it is possible to write programs that can
perform many tasks simultaneously. This design feature allows the developers to construct
interactive applications that can run smoothly. A multi-threaded program contains two or more
parts that can run concurrently and each part can handle a different task at the same time making
optimal use of the available resources specially when your computer has multiple CPUs. By
definition, multitasking is when multiple processes share common processing resources such as
a CPU. Multithreading extends the idea of multitasking into applications where you can subdivide
specific operations within a single application into individual threads. Each of the threads can run
in parallel. The OS divides processing time not only among different applications, but also among
each thread within an application. Multi-threading enables you to write in a way where multiple
activities can proceed concurrently in the same program.
9. Interpreted: Java byte code is translated on the fly to native machine instructions and is not
stored anywhere. The development process is more rapid and analytical since the linking is an
incremental and light-weight process. JVM sits in between the javac compiler and the underlying
hardware, the javac (or any other compiler) compiler compiles Java code in the Bytecode, which
is understood by a platform specific JVM. The JVM then compiles the Bytecode in binary using JIT
(Just-in-time) compilation, as the code executes.
10. High Performance: With the use of Just-In-Time compilers, Java enables high performance. JVM
uses JIT compiler to improves the execution time of the program. Below are some general
optimizations that are done by the JIT compilers: Method inlining, Dead code elimination,
Heuristics for optimizing call sites, Constant folding
11. Distributed: Java is designed for the distributed environment of the internet.
12. Dynamic: Java is considered to be more dynamic than C or C++ since it is designed to adapt to an
evolving environment. Java programs can carry extensive amount of run-time information that can
be used to verify and resolve accesses to objects on run-time.
Java vs C++
Both Java and C++ are among the most popular programming languages. Both of them have their
advantages and disadvantages. In this tutorial, we shall take a closure look at their characteristic
features which differentiate one from another.
8 virtual Keyword It doesn't have ‘virtual' keyword. It has the ‘virtual' keyword.
It supports documentation
comment (/**.. */) for source code.
Javadoc tool can read the It doesn't support
documentation
14 documentation comments from source documentation comment for
comment
code and generate html based java source code.
documentation based on the
comments.
It uses the 'System' class, i.e System.in It uses 'cin' for input
16 Console Input for input. System.in class can be used operation. cin allows user to
to take input from user on console. enter value in console.
The operations defined inside the spec are given below (Oracle JVM Specs): The 'class' file format, Data
types, Primitive types and values, Reference types and values, Run-time data areas, Frames,
Representation of objects, Floating-point arithmetic, Special methods, Exceptions, Instruction set
summary, Class libraries, Public design, private implementation.
The execution engine comprises the garbage collector and the JIT compiler. The JVM comes in two flavors
− client and server. Both of these share the same runtime code but differ in what JIT is used. We shall learn
more about this later. The user can control what flavor to use by specifying the JVM flags -client or -server.
The server JVM has been designed for long-running Java applications on servers.
1. Class Loader: The JVM manages the process of loading, linking and initializing classes and interfaces in
a dynamic manner. During the loading process, the JVM finds the binary representation of a class and
creates it.
During the linking process, the loaded classes are combined into the run-time state of the JVM so that
they can be executed during the initialization phase. The JVM basically uses the symbol table stored in the
run-time constant pool for the linking process. Initialization consists of actually executing the linked
classes.
2. Linking and Initialization: The linking process consists of the following three steps −
• Verification − This is done by the Bytecode verifier to ensure that the generated .class files (the
Bytecode) are valid. If not, an error is thrown and the linking process comes to a halt.
• Preparation − Memory is allocated to all static variables of a class and they are initialized with the
default values.
• Resolution − All symbolic memory references are replaced with the original references. To
accomplish this, the symbol table in the run-time constant memory of the method area of the
class is used.
Initialization is the final phase of the class-loading process. Static variables are assigned original values and
static blocks are executed.
3. Runtime Data Areas: The JVM spec defines certain run-time data areas that are needed during the
execution of the program. Some of them are created while the JVM starts up. Others are local to threads
and are created only when a thread is created (and destroyed when the thread is destroyed). These are
listed below −
• PC (Program Counter) Register: It is local to each thread and contains the address of the JVM
instruction that the thread is currently executing.
• Stack: It is local to each thread and stores parameters, local variables and return addresses during
method calls. A StackOverflow error can occur if a thread demands more stack space than is
permitted. If the stack is dynamically expandable, it can still throw OutOfMemoryError.
• Heap: It is shared among all the threads and contains objects, classes' metadata, arrays, etc., that
are created during run-time. It is created when the JVM starts and is destroyed when the JVM
shuts down. You can control the amount of heap your JVM demands from the OS using certain
flags (more on this later). Care has to be taken not to demand too less or too much of the memory,
as it has important performance implications. Further, the GC manages this space and continually
removes dead objects to free up the space.
• Method Area: This run-time area is common to all threads and is created when the JVM starts up.
It stores per-class structures such as the constant pool (more on this later), the code for
constructors and methods, method data, etc. The JLS does not specify if this area needs to be
garbage collected, and hence, implementations of the JVM may choose to ignore GC. Further, this
may or may not expand as per the application's needs. The JLS does not mandate anything with
regard to this.
• Run-Time Constant Pool: The JVM maintains a per-class/per-type data structure that acts as the
symbol table (one of its many roles) while linking the loaded classes.
• Native Method Stacks: When a thread invokes a native method, it enters a new world in which the
structures and security restrictions of the Java virtual machine no longer hamper its freedom. A
native method can likely access the runtime data areas of the virtual machine (it depends upon
the native method interface), but can also do anything else it wants.
4. Execution Engine: The execution engine is responsible for executing the bytecode, it has three different
components.
• Garbage Collection: The JVM manages the entire lifecycle of objects in Java. Once an object is
created, the developer need not worry about it anymore. In case the object becomes dead (that
is, there is no reference to it anymore), it is ejected from the heap by the GC using one of the many
algorithms – serial GC, CMS, G1, etc.
• Interpreter: The interpreter Interprets the bytecode. It interprets the code fast but it's slow in
execution.
• JIT Complier: The JIT stands for Just-In-Time. The JIT compiler is a main part of the Java runtime
environment and it compiles bytecodes to machine code at runtime.
5. Java Native Interface (JNI): Java Native Interface (JNI) interacts with the native method libraries which
are essential for the execution.
6. Native Method Libraries: Native method libraries are the collection of C and C++ libraries (native
libraries) which are essential for the execution.
JRE: JRE is a Java Runtime Environment which is the implementation of JVM i.e. the specifications that are
defined in JVM are implemented and create a corresponding environment for the execution of code. JRE
comprises mainly Java binaries and other classes to execute the program like JVM which physically exists.
Along with Java binaries JRE also consists of various technologies of deployment, user interfaces to interact
with code executed, some base libraries for different functionalities, and language and util-based libraries.
JVM: JVM is the abbreviation for Java Virtual Machine which is a specification that provides a runtime
environment in which Java byte code can be executed i.e. it is something that is abstract and its
implementation is independent of choosing the algorithm and has been provided by Sun and other
companies. It is JVM which is responsible for converting Byte code to machine-specific code. It can also
run those programs which are written in other languages and compiled to Java bytecode. The JVM
performs the mentioned tasks: Loads code, Verifies code, Executes code, and Provides runtime
environment.
Following are the important differences between JDK, JRE, and JVM −
Sr.
Key JDK JRE JVM
No.
JDK is platform
dependent i.e for
Platform Like of JDK JRE is also
3 different platforms JVM is platform independent.
Independence platform dependent.
different JDK
required.
1. Standalone Applications: These are traditional desktop applications that run directly on a user’s
machine. They can have either a Command-Line Interface (CLI) or a Graphical User Interface
(GUI). Examples: Text editors, media players, and games.
2. Applets: Small Java programs that are embedded in web pages and run in a web browser. They
are less common today due to security concerns and the rise of more modern web technologies.
Examples: Interactive web applications, animations.
3. Servlets: Java programs that run on a server and handle requests and responses in web
applications. They are used to create dynamic web content. Examples: Online forms, e-
commerce applications.
4. JavaServer Pages (JSP): A technology that allows for the creation of dynamically generated web
pages based on HTML, XML, or other document types. JSPs are compiled into servlets. Examples:
Web portals, content management systems.
6. JavaFX Applications: Used for creating rich internet applications with a modern user interface.
JavaFX is the successor to Swing for building GUI applications. Examples: Media players, data
visualization tools.
7. Mobile Applications: Java is used for developing Android applications. These applications run on
Android devices. Examples: Mobile games, productivity apps.
8. Java Web Start Applications: These are applications that can be launched from a web browser.
They are downloaded and run on the client machine. Examples: Online games, financial
applications.
9. Java Micro Edition (Java ME): A subset of Java used for developing applications for small devices
with limited resources, such as embedded systems and mobile phones. Examples: Mobile games,
embedded systems applications.
*/
• Open a command prompt window and go to the directory where you saved the class. Assume
it's C:\.
• Type 'javac MyFirstJavaProgram.java' and press enter to compile your code. If there is no error in
your code, the command prompt will take you to the next line (Assumption − The path variable is
set. Learn: Java Envionment Setup).
Output
Hello World
This line is creating a new class MyFirstJavaProgram and being public, this class is to be defined in the
same name file as MyFirstJavaProgram.java. This convention helps Java compiler to identify the name of
public class to be created before reading the file content.
2. Comment Section
/* This is my first java program.
*/
These lines being in /* */ block are not considered by Java compiler and are comments. A comment helps
to understand program in a better way and makes code readable and understandable.
This line represents the main method that JVM calls when this program is loaded into memory. This
method is used to execute the program. Once this method is finished, program is finished in single
threaded environment.
4. Keywords Used
• public − defines the scope of the main method. Being public, this method can be called by external
program like JVM.
• static − defines the state of the main method. Being static, this method can be called by external
program like JVM without first creating the object of the class.
• void − defines the return type of the main method. Being void, this method is not returning any
value.
• String []args − arguments passed on command line while executing the java command.
5. System.out.println() Method
System.out represents the primary console and its println() method is taking "Hello World" as input and it
prints the same to the console output.
• Object − Objects have states and behaviors. Example: A dog has states - color, name, breed as well
as behavior such as wagging their tail, barking, eating. An object is an instance of a class.
• Class − A class can be defined as a template/blueprint that describes the behavior/state that the
object of its type supports.
• Methods − A method is basically a behavior. A class can contain many methods. It is in methods
where the logics are written, data is manipulated and all the actions are executed.
• Instance Variables − Each object has its unique set of instance variables. An object's state is created
by the values assigned to these instance variables.
About Java programs, it is very important to keep in mind the following points.
• Case Sensitivity − Java is case sensitive, which means identifier Hello and hello would have
different meaning in Java.
• Class Names − For all class names the first letter should be in Upper Case. If several words are
used to form a name of the class, each inner word's first letter should be in Upper Case.
Example − class MyFirstJavaClass
• Method Names − All method names should start with a Lower-Case letter. If several words are
used to form the name of the method, then each inner word's first letter should be in Upper Case.
Example − public void myMethodName()
• Program File Name − Name of the program file should exactly match the class name. When saving
the file, you should save it using the class name (Remember Java is case sensitive) and append
'.java' to the end of the name (if the file name and the class name do not match, your program
will not compile). But please make a note that in case you do not have a public class present in the
file then file name can be different than class name. It is also not mandatory to have a public class
in the file. Example − Assume 'MyFirstJavaProgram' is the class name. Then the file should be
saved as 'MyFirstJavaProgram.java'
• public static void main(String args[]) − Java program processing starts from the main() method
which is a mandatory part of every Java program.
Java Identifiers
All Java components require names. Names used for classes, variables, and methods are called identifiers.
• All identifiers should begin with a letter (A to Z or a to z), currency character ($) or an underscore
(_).
• After the first character, identifiers can have any combination of characters.
Java Modifiers
Like other languages, it is possible to modify classes, methods, etc., by using modifiers. There are two
categories of modifiers −
Java Variables
Following are the types of variables in Java −
• Local Variables
Java Arrays
Arrays are objects that store multiple variables of the same type. However, an array itself is an object on
the heap. We will look into how to declare, construct, and initialize in the upcoming chapters.
Java Enums
Enums were introduced in Java 5.0. Enums restrict a variable to have one of only a few predefined values.
The values in this enumerated list are called enums. With the use of enums it is possible to reduce the
number of bugs in your code. For example, if we consider an application for a fresh juice shop, it would be
possible to restrict the glass size to small, medium, and large. This would make sure that it would not allow
anyone to order any size other than small, medium, or large.
Example
class FreshJuice {
FreshJuiceSize size;
juice.size = FreshJuice.FreshJuiceSize.MEDIUM ;
Output
Size: MEDIUM
Note − Enums can be declared as their own or inside a class. Methods, variables, constructors can be
defined inside enums as well.
Java Keywords
The following list shows the reserved words in Java. These reserved words may not be used as constant
or variable or any other identifier names.
abstract
1 As per dictionary, abstraction is the quality of dealing with ideas rather than
events.
assert
boolean
break
The break statement in Java programming language has the following two usages −
byte
5 byte datatype is one of the eight primitive datatype supported by Java. It provides
means to create byte type variables which can accept a byte value.
6 case
case keyword is part of switch statement which allows a variable to be tested for
equality against a list of values.
catch
7 An exception (or exceptional event) is a problem that arises during the execution
of a program.
char
8
char datatype is one of the eight primitive datatype supported by Java.
class
9 Java is an Object-Oriented Language. As a language that has the Object-Oriented
feature.
const
10
final keyword is used to define constant value or final methods/classes in Java.
continue
11
The continue keyword can be used in any of the loop control structures.
default
12 default keyword is part of switch statement which allows a variable to be tested for
equality against a list of values.
do
13 A do...while loop is similar to a while loop, except that a do...while loop is
guaranteed to execute at least one time.
double
14
double datatype is one of the eight primitive datatype supported by Java.
if
15 An if statement can be followed by an optional else statement, which executes
when the Boolean expression is false.
enum
16 The Java Enum class is the common base class of all Java language enumeration
types.
extends
17 extends is the keyword used to inherit the properties of a class. Following is the
syntax of extends keyword.
final
18
final keyword is used to define constant value or final methods/classes in Java.
finally
19 finally keyword is used to define a finally block. The finally block follows a try block
or a catch block. A finally block of code always executes, irrespective of occurrence
of an Exception.
float
20 float datatype is one of the eight primitive datatype supported by Java. It provides
means to create float type variables which can accept a float value.
for
21 A for loop is a repetition control structure that allows you to efficiently write a loop
that needs to be executed a specific number of times.
goto
if
23 An if statement consists of a Boolean expression followed by one or more
statements.
24 implements
Generally, the implements keyword is used with classes to inherit the properties of
an interface.
import
25
import keyboard is used in context of packages.
instanceof
26 instanceof keyword is an operator which is used only for object reference
variables.
int
27
int datatype is one of the eight primitive datatype supported by Java.
interface
28 An interface is a reference type in Java. It is similar to class. It is a collection of
abstract methods.
long
29
long datatype is one of the eight primitive datatype supported by Java.
30 native
31 new
package
32 Packages are used in Java in order to prevent naming conflicts, to control access, to
make searching/locating and usage of classes, interfaces, enumerations and
annotations easier, etc.
private
33 Methods, variables, and constructors that are declared private can only be
accessed within the declared class itself.
protected
34
The protected access modifier cannot be applied to class and interfaces.
public
35 A class, method, constructor, interface, etc. declared public can be accessed from
any other class.
36 return
short
37 By assigning different data types to variables, you can store integers, decimals, or
characters in these variables.
static
38 The static keyword is used to create variables that will exist independently of any
instances created for the class.
39 strictfp
super
40
The super keyword is similar to this keyword.
switch
41 A switch statement allows a variable to be tested for equality against a list of
values.
42 synchronized
this
43 this keyword is a very important keyword to identify an object. Following are the
usage of this keyword.
throw
44 If a method does not handle a checked exception, the method must declare it
using the throws keyword.
45 transient
Serialization is a concept using which we can write the state of an object into a
byte stream so that we can transfer it over the network (using technologies like JPA
and RMI).
try
46
A method catches an exception using a combination of the try and catch keywords.
47 void
48 volatile
while
49 A while loop statement in Java programming language repeatedly executes a target
statement as long as a given condition is true.
Comments in Java
Java supports single-line and multi-line comments very similar to C and C++. All characters available
inside any comment are ignored by Java compiler.
Example
*/
System.out.println("Hello World");
Output
Hello World
Using Blank Lines
A line containing only white space, possibly with a comment, is known as a blank line, and Java totally
ignores it.
Inheritance
In Java, classes can be derived from classes. Basically, if you need to create a new class and here is already
a class that has some of the code you require, then it is possible to derive your new class from the already
existing code.
This concept allows you to reuse the fields and methods of the existing class without having to rewrite the
code in a new class. In this scenario, the existing class is called the superclass and the derived class is called
the subclass.
Interfaces
In Java language, an interface can be defined as a contract between objects on how to communicate with
each other. Interfaces play a vital role when it comes to the concept of inheritance.
An interface defines the methods, a deriving class (subclass) should use. But the implementation of the
methods is totally up to the subclass.
Java Variable
A variable provides us with named storage that our programs can manipulate. Each variable in Java has a
specific type, which determines the size and layout of the variable's memory; the range of values that can
be stored within that memory; and the set of operations that can be applied to the variable.
Here data type is one of Java's data types and variable is the name of the variable. To declare more than
one variable of the specified type, you can use a comma-separated list.
• Local variables are created when the method, constructor or block is entered and the variable will
be destroyed once it exits the method, constructor, or block.
• Local variables are visible only within the declared method, constructor, or block.
• There is no default value for local variables, so local variables should be declared and an initial
value should be assigned before the first use.
• Instance variables are declared in a class, but outside a method, constructor or any block.
• When a space is allocated for an object in the heap, a slot for each instance variable value is
created.
• Instance variables are created when an object is created with the use of the keyword 'new' and
destroyed when the object is destroyed.
• Instance variables hold values that must be referenced by more than one method, constructor or
block, or essential parts of an object's state that must be present throughout the class.
• The instance variables are visible for all methods, constructors and block in the class. Normally, it
is recommended to make these variables private (access level). However, visibility for subclasses
can be given for these variables with the use of access modifiers.
• Instance variables have default values. For numbers, the default value is 0, for Booleans it is
false, and for object references it is null. Values can be assigned during the declaration or within
the constructor.
• Instance variables can be accessed directly by calling the variable name inside the class.
However, within static methods (when instance variables are given accessibility), they should be
called using the fully qualified name. ObjectReference.VariableName.
• There would only be one copy of each class variable per class, regardless of how many objects
are created from it.
• Static variables are rarely used other than being declared as constants. Constants are variables
that are declared as public/private, final, and static. Constant variables never change from their
initial value.
• Static variables are stored in the static memory. It is rare to use static variables other than
declared final and used as either public or private constants.
• Static variables are created when the program starts and destroyed when the program stops.
• Visibility is similar to instance variables. However, most static variables are declared public since
they must be available for users of the class.
• Default values are same as instance variables. For numbers, the default value is 0; for Booleans,
it is false; and for object references, it is null. Values can be assigned during the declaration or
within the constructor. Additionally, values can be assigned in special static initializer blocks.
• Static variables can be accessed by calling with the class name ClassName.VariableName.
• When declaring class variables as public static final, then variable names (constants) are all in
upper case. If the static variables are not public and final, the naming syntax is the same as
instance and local variables.
Java Primitive Data Types: Primitive data types are predefined by the language and named by a keyword.
There are eight primitive data types supported by Java. Below is the list of the primitive data types:
• Default value is 0
• Byte data type is used to save space in large arrays, mainly in place of integers, since a byte is
four times smaller than an integer.
• Short data type can also be used to save memory as byte data type. A short is 2 times
smaller than an integer
• Default value is 0.
• Integer is generally used as the default data type for integral values unless there is a concern
about memory.
• Default value is 0L
• Float data type is never used for precise values such as currency
• This data type is generally used as the default data type for decimal values, generally the
default choice
• Double data type should never be used for precise values such as currency
• This data type is used for simple flags that track true/false conditions
The reference data types are created using defined constructors of the classes. They are used to access
objects. These variables are declared to be of a specific type that cannot be changed. For example,
Employee, Puppy, etc.
Class objects and various types of array variables come under reference datatype. The default value of any
reference variable is null. A reference variable can be used to refer to any object of the declared type or
any compatible type.
Java Type Casting (Type Conversion)
Type casting is a technique that is used either by the compiler or a programmer to convert one data type to
another. For example, converting int to double, double to int, short to int, etc. Type typing is also known
as Type conversion.
1. Widening Type Casting: Widening Type Casting is also known as implicit type casting in which a
smaller type is converted into a larger type, it is done by the compiler automatically.
byte > short > char > int > long > float > double
The compiler plays a role in the type conversion but not the programmers. It changes the type of
the variables at the compile time. Also, type conversion occurs from the small data type to large data type
only.
Example: In the example below, we created the num1 and num2 variables as same in the first example.
We store the sum of both numbers in the sum variable of double type. In the output, we can observe the
sum of double type.
package import
// show output
System.out.println("The sum of " + num1 + " and " + num2 + " is " + sum);
Output
Syntax
Below is the syntax for narrowing type casting i.e., to manually type conversion:
The above code statement will convert the variable to double type.
Example: In the example below, we define the num variable of integer type and initialize it with the value.
Also, we define the doubleNum variable of double type and store the num variable's value after converting
it to the double.
Next, We created the 'convertedInt' integer type variable and stored the double value after type casting
to int. In the output, we can observe the value of the double and int variables.
package import;
// show output
System.out.println("The value of " + num + " after converting to the double is " + doubleNum);
// show output
System.out.println("The value of " + doubleNum + " after converting to the int again is " +
convertedInt);
Output
The value of 5004 after converting to the double is 5004.0
Java Tokens
In Java, Tokens are the smallest elements of a program that is meaningful to the compiler. They are also
known as the fundamental building blocks of the program. Tokens can be classified as follows:
1. Keyword: Keywords are pre-defined or reserved words in a programming language. Each keyword is
meant to perform a specific function in a program. Since keywords are referred names for a compiler,
they can’t be used as variable names because by doing so, we are trying to assign a new meaning to the
keyword which is not allowed. Java language supports the following keywords:
abstract assert boolean
break byte case
catch char class
const continue default
do double else
enum exports extends
final finally float
for goto if
implements import instanceof
int interface long
module native new
open opens package
private protected provides
public requires return
short static strictfp
super switch synchronized
this throw throws
to transient transitive
try uses void
volatile while with
2. Identifiers: Identifiers are used as the general terminology for naming of variables, functions and arrays.
These are user-defined names consisting of an arbitrarily long sequence of letters and digits with either a
letter or the underscore (_) as a first character. Identifier names must differ in spelling and case from any
keywords. You cannot use keywords as identifiers; they are reserved for special use. Once declared, you
can use the identifier in later program statements to refer to the associated value. A special kind of
identifier, called a statement label, can be used in goto statements. Examples of valid identifiers:
MyVariable
3. Constants/Literals: Constants are also like normal variables. But the only difference is, their values
cannot be modified by the program once they are defined. Constants refer to fixed values. They are also
called as literals. Constants may belong to any of the data type. Syntax:
4. Special Symbols: The following special symbols are used in Java having some special meaning and thus,
cannot be used for some other purpose. [] () {}, ; * =
• Brackets[]: Opening and closing brackets are used as array element reference. These indicate
single and multidimensional subscripts.
• Parentheses(): These special symbols are used to indicate function calls and function parameters.
• Braces{}: These opening and ending curly braces marks the start and end of a block of code
containing more than one executable statement.
• comma (, ): It is used to separate more than one statements like for separating parameters in
function calls.
• semi colon : It is an operator that essentially invokes something called an initialization list.
5. Operators: Java provides many types of operators which can be used according to the need. They are
classified based on the functionality they provide. Some of the types are-
Arithmetic Operators, Unary Operators, Assignment Operator, Relational Operators, Logical Operators,
Ternary Operator, Bitwise Operators, Shift Operators, instance of operator, Precedence and Associativity
6. Comments: In Java, Comments are the part of the program which are ignored by the compiler while
compiling the Program. They are useful as they can be used to describe the operation or methods in the
program. The Comments are classified as follows:
• Multiline Comments
7. Separators: Separators are used to separate different parts of the codes. It tells the compiler about
completion of a statement in the program. The most commonly and frequently used separator in java is
semicolon (;).
Arrays in Java
Java provides a data structure called the array, which stores a fixed-size sequential collection of elements
of the same data type. An array is used to store a collection of data, but it is often more useful to think of
an array as a collection of variables of the same type.
Instead of declaring individual variables, such as number0, number1, ..., and number99, you declare one
array variable such as numbers and use numbers[0], numbers[1], and ..., numbers[99] to represent
individual variables.
Declaring Array Variables: To use an array in a program, you must declare a variable to reference the array,
and you must specify the type of array the variable can reference. Here is the syntax for declaring an array
variable −
Syntax
dataType[] arrayRefVar; // preferred way. Or dataType arrayRefVar[]; // works but not preferred way.
Example
double[] myList; // preferred way. Or double myList[]; // works but not preferred way.
• It assigns the reference of the newly created array to the variable arrayRefVar.
Declaring an array variable, creating an array, and assigning the reference of the array to the variable can
be combined in one statement, as shown below −
Alternatively
The array elements are accessed through the index. Array indices are 0-based; that is, they start from 0
to arrayRefVar.length-1.
Example
Following statement declares an array variable, myList, creates an array of 10 elements of double type
and assigns its reference to myList −
Following picture represents array myList. Here, myList holds ten double values and the indices are from
0 to 9.
Processing Arrays: When processing array elements, we often use either for loop or foreach loop because
all of the elements in an array are of the same type and the size of the array is known.
double total = 0;
total += myList[i];
Output
1.9
2.9
3.4
3.5
Total is 11.7
Max is 3.5
foreach Loops with Arrays: JDK 1.5 introduced a new for loop known as foreach loop or enhanced for
loop, which enables you to traverse the complete array sequentially without using an index variable.
System.out.println(element);
Output
1.9
2.9
3.4
3.5
Passing Arrays to Methods: Just as you can pass primitive type values to methods, you can also pass arrays
to methods. For example, the following method displays the elements in an int array −
Example
public static void printArray(int[] array) {
You can invoke it by passing an array. For example, the following statement invokes the printArray method
to display 3, 1, 2, 6, 4, and 2 −
Returning an Array from a Method: A method may also return an array. For example, the following
method returns an array that is the reversal of another array −
Example
result[j] = list[i];
return result;
Arrays Class: The java.util.Arrays class contains various static methods for sorting and searching arrays,
comparing arrays, and filling array elements. These methods are overloaded for all primitive types.
Searches the specified array of Object ( Byte, Int , double, etc.) for the specified value
1 using the binary search algorithm. The array must be sorted prior to making this call.
This returns index of the search key, if it is contained in the list; otherwise, it returns
( – (insertion point + 1)).
4 Sorts the specified array of objects into an ascending order, according to the natural
ordering of its elements. The same method could be used by all other primitive data
types ( Byte, short, Int, etc.)
Java operators
Java operators are the symbols that are used to perform various operations on variables and values. By
using these operators, we can perform operations like addition, subtraction, checking less than or greater
than, etc.
There are different types of operators in Java, we have listed them below −
Show Examples
A + B will
+ (Addition) Adds values on either side of the operator.
give 30
A - B will
- (Subtraction) Subtracts right-hand operand from left-hand operand.
give -10
A * B will
* (Multiplication) Multiplies values on either side of the operator.
give 200
B / A will
/ (Division) Divides left-hand operand by right-hand operand.
give 2
B%A
Divides left-hand operand by right-hand operand and
% (Modulus) will give
returns remainder.
0
B++ gives
++ (Increment) Increases the value of operand by 1.
21
B-- gives
-- (Decrement) Decreases the value of operand by 1.
19
2. Java Relational Operators: Assume variable A holds 10 and variable B holds 20, then −
a = 0011 1100
b = 0000 1101
~a = 1100 0011
& (bitwise Binary AND Operator copies a bit to the (A & B) will give 12 which is
and) result if it exists in both operands. 0000 1100
^ (bitwise Binary XOR Operator copies the bit if it is (A ^ B) will give 49 which is
XOR) set in one operand but not both. 0011 0001
4. Java Logical Operators: Assume Boolean variables A holds true and variable B holds false, then −
5. Assignment Operators
C=A+B
Simple assignment operator. Assigns values from right side will assign
=
operands to left side operand. value of A
+ B into C
C += A is
Add AND assignment operator. It adds right operand to the left equivalent
+=
operand and assign the result to left operand. to C = C +
A
C -= A is
Subtract AND assignment operator. It subtracts right operand from equivalent
-=
the left operand and assign the result to left operand. to C = C −
A
C *= A is
Multiply AND assignment operator. It multiplies right operand with equivalent
*=
the left operand and assign the result to left operand. to C = C *
A
C /= A is
Divide AND assignment operator. It divides left operand with the equivalent
/=
right operand and assign the result to left operand. to C = C /
A
C %= A is
Modulus AND assignment operator. It takes modulus using two equivalent
%=
operands and assign the result to left operand. to C = C %
A
C <<= 2 is
<<= Left shift AND assignment operator. same as C
= C << 2
C >>= 2 is
>>= Right shift AND assignment operator. same as C
= C >> 2
C &= 2 is
&= Bitwise AND assignment operator. same as C
=C&2
C ^= 2 is
^= bitwise exclusive OR and assignment operator. same as C
=C^2
C |= 2 is
|= bitwise inclusive OR and assignment operator. same as C
=C|2
If the object referred by the variable on the left side of the operator passes the IS-A check for the
class/interface type on the right side, then the result will be true. Following is an example −
Example: we're creating a String variable name and then using instanceof operator we've checking the
name is of String or not.
System.out.println( result );
Output
true
This operator will still return true, if the object being compared is the assignment compatible with the
type on the right.
For example, x = 7 + 3 * 2; here x is assigned 13, not 20 because operator * has higher precedence than +,
so it first gets multiplied with 3 * 2 and then adds into 7.
Here, operators with the highest precedence appear at the top of the table, those with the lowest appear
at the bottom. Within an expression, higher precedence operators will be evaluated first.
Control Statements
Loops
There may be a situation when you need to execute a block of code several number of times. In general,
statements are executed sequentially: The first statement in a function is executed first, followed by the
second, and so on. Programming languages provide various control structures that allow for more
complicated execution paths.
Loop Statement
A loop statement allows us to execute a statement or group of statements multiple times and following is
the general form of a loop statement in most of the programming languages −
Java Loops
while loop
1 Repeats a statement or group of statements while a given condition is true. It tests
the condition before executing the loop body.
for loop
2 Execute a sequence of statements multiple times and abbreviates the code that
manages the loop variable.
do...while loop
3
Like a while statement, except that it tests the condition at the end of the loop body.
break statement
1 Terminates the loop or switch statement and transfers execution to the statement
immediately following the loop or switch.
continue statement
2 Causes the loop to skip the remainder of its body and immediately retest its condition
prior to reiterating.
Decision making structures: Decision making structures have one or more conditions to be evaluated
or tested by the program, along with a statement or statements that are to be executed if the condition is
determined to be true, and optionally, other statements to be executed if the condition is determined to
be false.
Java programming language provides following types of decision making statements. Click the following
links to check their detail.
if statement
1
An if statement consists of a boolean expression followed by one or more statements.
if...else statement
2 An if statement can be followed by an optional else statement, which executes when
the boolean expression is false.
nested if statement
3
You can use one if or else if statement inside another if or else if statement(s).
switch statement
4
A switch statement allows a variable to be tested for equality against a list of values.
The ? : Operator: We have covered conditional operator ? : in the previous chapter which can be used
to replace if...else statements. It has the following general form −
Where Exp1, Exp2, and Exp3 are expressions. Notice the use and placement of the colon.
• If the value of exp1 is true, then the value of Exp2 will be the value of the whole expression.
• If the value of exp1 is false, then Exp3 is evaluated and its value becomes the value of the entire
expression.
Java if-else Statement: In Java, the if else statement is used to execute two code blocks based on the
given condition. A Java if statement executes when the Boolean expression for the if statement is true.
An if statement can be followed by an optional else statement, which executes when the Boolean
expression is false.
if(Boolean_expression) {
}else {
If the boolean expression evaluates to true, then the if block of code will be executed, otherwise else block
of code will be executed.
Example:In this example, we're showing the usage of if else statement. We've created a variable x and
initialized it to 30. Then in the if statement, we're checking x with 20. As if statement is false, the statement
within the else block is executed.
int x = 30;
if( x < 20 ) {
System.out.print("This is if statement");
}else {
Output
Java if-else-if Statement: The if...else if...else statement is used for executing multiple code blocks
based on the given conditions (Boolean expressions).
An if statement can be followed by an optional else if...else statement, which is very useful to test various
conditions using a single if...else if statement.
Points to Remember
When using if-else if- else statements there are a few points to keep in mind.
• An if can have zero or one else's and it must come after any else if's.
• An if can have zero to many else if's and they must come before the else.
• Once an else if succeeds, none of the remaining else if's or else's will be tested.
if(Boolean_expression 1) {
}else if(Boolean_expression 2) {
}else if(Boolean_expression 3) {
}else {
Example 1: In this example, we're showing the usage of if...else if...else statement. We've created a variable
x and initialized it to 30. Then in the if statement, we're checking x with 10. As if statement is false, control
jumps to else if statement checking another value with x and so on.
int x = 30;
if( x == 10 ) {
System.out.print("Value of X is 10");
}else if( x == 20 ) {
System.out.print("Value of X is 20");
}else if( x == 30 ) {
System.out.print("Value of X is 30");
}else {
Output
Value of X is 30
Java Nested if-else Statement: The nested if else statement is used for better decision-making when
other conditions are to be checked when a given condition is true. In the nested if else statement, you
can have an if-else statement block the another if (or, else) block.
if(condition1){
// code block
if(condition2){
//code block
Example: The following examples finds the largest number among three using nested if..else statement.
if(x >= y) {
if(x >= z)
else
} else {
if(y >= z)
else
Output
30 is the largest.
Java switch Statement: The Java switch statement allows a variable to be tested for equality against a
list of values. Each value is called a case, and the variable being switched on is checked for each case.
The switch statement can be used when multiple if-else statements are required. It can have multiple code
blocks along with the case values and executes one of many code blocks based on the matches case value.
Syntax
switch(expression) {
case value :
// Statements
break; // optional
case value :
// Statements
break; // optional
default : // Optional
// Statements
Rules
• The variable used in a switch statement can only be integers, convertable integers (byte, short,
char), strings and enums.
• You can have any number of case statements within a switch. Each case is followed by the value
to be compared to and a colon.
• The value for a case must be the same data type as the variable in the switch and it must be a
constant or a literal.
• When the variable being switched on is equal to a case, the statements following that case will
execute until a break statement is reached.
• When a break statement is reached, the switch terminates, and the flow of control jumps to the
next line following the switch statement.
• Not every case needs to contain a break. If no break appears, the flow of control will fall through to
subsequent cases until a break is reached.
• A switch statement can have an optional default case, which must appear at the end of the switch.
The default case can be used for performing a task when none of the cases is true. No break is
needed in the default case.
Examples: In this example, we're showing use of switch statement where cases are based on a char. We've
created a variable grade. Based on value of grade, each case is checked. if a case is satisfied and break
statement is present then following cases are not checked.
switch(grade) {
case 'A' :
System.out.println("Excellent!");
break;
case 'B' :
case 'C' :
System.out.println("Well done");
break;
case 'D' :
System.out.println("You passed");
case 'F' :
break;
default :
System.out.println("Invalid grade");
Output
Well done
Your grade is C
The default Keyword: The default keyword is used to specify a code block when no case value is matched.
The default keyword is optional, but it should be used in the switch case statement.
Java for Loop: A for loop is a repetition control structure that allows you to efficiently write a loop that
needs to be executed a specific number of times.
A for loop is useful when you know how many times a task is to be repeated. Just like the while loop,
the for loop is also an entry control loop where the given condition executes first.
// Statements
Parts of Java For Loop: In Java, the for loop is constructed (implemented) using three parts. The following
are the parts of a for loop in Java -
• Initialization - Contains the initialization statement (s) of the loop counter.
• Body - Contains the statements to be iterated till the given Boolean expression is true, also to
update the loop counter.
• The initialization step is executed first, and only once. This step allows you to declare and initialize
any loop control variables and this step ends with a semi colon (;).
• Next, the Boolean expression is evaluated. If it is true, the body of the loop is executed. If it is false,
the body of the loop will not be executed and control jumps to the next statement past the for
loop.
• After the body of the for loop gets executed, the control jumps back up to the update statement.
This statement allows you to update any loop control variables. This statement can be left blank
with a semicolon at the end.
• The Boolean expression is now evaluated again. If it is true, the loop executes and the process
repeats (body of loop, then update step, then Boolean expression). After the Boolean expression
is false, the for loop terminates.
Example 1:
In this example, we're showing the use of a for loop to print numbers starting from 10 to 19. Here we've
initialized an int variable x with a value of 10 within initialization blook of for loop. Then in expression
block, we're checking x as less than 20, and in the end under update block, we're incrementing x by 1.
Within body of for loop, we're printing the value of x. For loop will run until x becomes 20. Once x is 20,
loop will stop execution and program exits.
System.out.print("value of x : " + x );
System.out.print("\n");
Output
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
Nested for Loop in Java: A nested for loop is a for loop containing another for loop inside it.
Example: Print Tables from 1 to 10 Using Nested for Loop
int num = 1;
int i = 1;
// printing table
System.out.println();
}
}
Output
Table of 1 is : 1 2 3 4 5 6 7 8 9 10
Table of 2 is : 2 4 6 8 10 12 14 16 18 20
Table of 3 is : 3 6 9 12 15 18 21 24 27 30
Table of 4 is : 4 8 12 16 20 24 28 32 36 40
Table of 5 is : 5 10 15 20 25 30 35 40 45 50
Table of 6 is : 6 12 18 24 30 36 42 48 54 60
Table of 7 is : 7 14 21 28 35 42 49 56 63 70
Table of 8 is : 8 16 24 32 40 48 56 64 72 80
Table of 9 is : 9 18 27 36 45 54 63 72 81 90
Table of 10 is : 10 20 30 40 50 60 70 80 90 100
Java for each Loop: A for each loop is a special repetition control structure that allows you to efficiently
write a loop that needs to be executed a specific number of times.
A for each loop is useful even when you do not know how many times a task is to be repeated.
Syntax
for(declaration : expression) {
// Statements
Execution Process
• Declaration − The newly declared block variable, is of a type compatible with the elements of the
array you are accessing. The variable will be available within the for block and its value would be
the same as the current array element.
• Expression − This evaluates to the array you need to loop through. The expression can be an array
variable or method call that returns an array.
Examples: In this example, we're showing the use of a foreach loop to print contents of an List of Integers.
Here we're creating an List of integers as numbers and initialized it some values. Then using foreach loop,
each number is printed.
import java.util.Arrays;
import java.util.List;
for(Integer x : numbers ) {
System.out.print( x );
System.out.print(",");
Output
Java while Loop: A while loop statement in Java programming language repeatedly executes a code
block as long as a given condition is true.
The while loop is an entry control loop, where condition is checked before executing the loop's body.
while(Boolean_expression) {
// Statements
Here, statement(s) may be a single statement or a block of statements. The condition may be any
expression, and true is any non zero value.
When executing, if the boolean_expression result is true, then the actions inside the loop will be
executed. This will continue as long as the expression result is true.
When the condition becomes false, program control passes to the line immediately following the loop.
Here, key point of the while loop is that the loop might not ever run. When the expression is tested and
the result is false, the loop body will be skipped and the first statement after the while loop will be
executed.
int x = 10;
while( x < 20 ) {
System.out.print("value of x : " + x );
x++;
System.out.print("\n");
Output
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
Java do while Loop: A do while loop is similar to a while loop, except that a do while loop is
guaranteed to execute at least one time.
The do-while loop is an exit control loop, where the condition is checked after executing the loop's body.
// Statements
}while(Boolean_expression);
Notice that the Boolean expression appears at the end of the loop, so the statements in the loop execute
once before the Boolean is tested.
If the Boolean expression is true, the control jumps back up to do statement, and the statements in the
loop execute again. This process repeats until the Boolean expression is false.
Example 1: In this example, we're showing the use of a while loop to print numbers starting from 10 to
19. Here we've initialized an int variable x with a value of 10. Then in do while loop, we're checking x as
less than 20 after do while loop body.In do while loop body we're printing the value of x and incrementing
the value of x by 1. While loop will run until x becomes 20. Once x is 20, loop will stop execution and
program exits.
int x = 10;
do {
System.out.print("value of x : " + x );
x++;
System.out.print("\n");
}while( x < 20 );
Output
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
Java break Statement: The break statement in Java programming language has following two usages −
• When the break statement is encountered inside a loop, the loop is immediately terminated and
the program control resumes at the next statement following the loop.
Syntax
break;
Example 1: In this example, we're showing the use of a break statement to break a while loop to print
numbers starting from 10 to 14 which will otherwise print element till 19. Here we've initialized an
int variable x with a value of 10. Then in while loop, we're checking x as less than 20 and within while loop,
we're printing the value of x and incrementing the value of x by 1. While loop will run until x becomes 15.
Once x is 15, break statement will break the while loop and program exits.
int x = 10;
while( x < 20 ) {
if(x == 15){
break;
System.out.print("value of x : " + x );
x++;
System.out.print("\n");
Output
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
Java continue Statement: The continue statement can be used in any of the loop control structures. It
causes the loop to immediately jump to the next iteration of the loop.
• In a for loop, the continue keyword causes control to immediately jump to the update statement.
• In a while loop or do/while loop, control immediately jumps to the Boolean expression.
Syntax
continue;
Examples: In this example, we're showing the use of a continue statement to skip an element 15 in a while
loop which is used to print element from 10 to 19. Here we've initialized an int variable x with a value of
10. Then in while loop, we're checking x as less than 20 and within while loop, we're printing the value of
x and incrementing the value of x by 1. While loop will run until x becomes 15. Once x is 15, continue
statement will jump the while loop while skipping the execution of the body and loop continues.
int x = 10;
while( x < 20 ) {
x++;
if(x == 15){
continue;
System.out.print("value of x : " + x );
System.out.print("\n");
Output
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 16
value of x : 17
value of x : 18
value of x : 19
value of x : 20
• Classes
• Objects
• Inheritance
• Polymorphism
• Encapsulation
• Abstraction
• Instance
• Method
• Message Passing
Java Classes: A class is a blueprint from which individual objects are created (or, we can say a class is
a data type of an object type). In Java, everything is related to classes and objects. Each class has
its methods and attributes that can be accessed and manipulated through the objects.
For example, if you want to create a class for students. In that case, "Student" will be a class, and student
records (like student1, student2, etc) will be objects.
We can also consider that class is a factory (user-defined blueprint) to produce objects.
• A class is just like a real-world entity, but it is not a real-world entity. It's a blueprint where we
specify the functionalities.
• Classes follow all of the rules of OOPs such as inheritance, encapsulation, abstraction, etc.
• Local variables − Variables defined inside methods, constructors or blocks are called local
variables. The variable will be declared and initialized within the method and the variable will be
destroyed when the method has completed.
• Instance variables − Instance variables are variables within a class but outside any method. These
variables are initialized when the class is instantiated. Instance variables can be accessed from
inside any method, constructor or blocks of that particular class.
• Class variables − Class variables are variables declared within a class, outside any method, with
the static keyword.
To create (declare) a class, you need to use access modifiers followed by class keyword and class_name.
data members;
constructors;
methods;
...;
Example of a Java Class: In this example, we are creating a class "Dog". Where, the class attributes
are breed, age, and color. The class methods are setBreed(), setAge(), setColor(), and printDetails().
class Dog {
String breed;
int age;
String color;
this.breed = breed;
this.age = age;
this.color = color;
System.out.println("Dog detials:");
System.out.println(this.breed);
System.out.println(this.age);
System.out.println(this.color);
Java Objects: An object is a variable of the type class, it is a basic component of an object-oriented
programming system. A class has the methods and data members (attributes), these methods and data
members are accessed through an object. Thus, an object is an instance of a class.
If we consider the real world, we can find many objects around us, cars, dogs, humans, etc. All these
objects have a state and a behavior.
If we consider a dog, then its state is - name, breed, and color, and the behavior is - barking, wagging the
tail, and running.
If you compare the software object with a real-world object, they have very similar characteristics.
Software objects also have a state and a behavior. A software object's state is stored in fields and behavior
is shown via methods. So, in software development, methods operate on the internal state of an object,
and the object-to-object communication is done via methods.
As mentioned previously, a class provides the blueprints for objects. So basically, an object is created from
a class. In Java, the new keyword is used to create new objects.
• Initialization − The 'new' keyword is followed by a call to a constructor. This call initializes the new
object.
Note: parameters are optional and can be used while you're using constructors in the class.
Example: In this example, we are creating an object named obj of Dog class and accessing its methods.
class Dog {
String breed;
int age;
String color;
this.breed = breed;
this.age = age;
this.color = color;
}
// method to print all three values
System.out.println("Dog detials:");
System.out.println(this.breed);
System.out.println(this.age);
System.out.println(this.color);
obj.setBreed("Golden Retriever");
obj.setAge(2);
obj.setColor("Golden");
// Printing values
obj.printDetails();
Output
Dog detials:
Golden Retriever
Golden
Instance variables and methods are accessed via created objects. To access an instance variable,
following is the fully qualified path −
ObjectReference.variableName;
ObjectReference.MethodName();
Example
In this example, We've created a class named Puppy. In Puppy class constructor, puppy name is printed so
that when the object is created, its name is printed. An instance variable puppyAge is added and using
getter/setter method, we can manipulate the age. In main method, an object is created using new
operator. Age is updated using setAge() method and using getAge(), the age is printed.
int puppyAge;
puppyAge = age;
return puppyAge;
/* Object creation */
myPuppy.setAge( 2 );
myPuppy.getAge( );
/* You can access instance variable as follows as well */
Output
Puppy's age is :2
Variable Value :2
Let's now look into the source file declaration rules (to use the Java classes & objects approach). These
rules are essential when declaring classes, import statements, and package statements in a source file.
• The public class name should be the name of the source file as well which should be appended
by .java at the end. For example − the class name is public class Employee{} then the source file
should be as Employee.java.
• If the class is defined inside a package, then the package statement should be the first statement
in the source file.
• If import statements are present, then they must be written between the package statement and
the class declaration. If there are no package statements, then the import statement should be
the first line in the source file.
• Import and package statements will imply to all the classes present in the source file. It is not
possible to declare different import and/or package statements to different classes in the source
file.
Classes have several access levels and there are different types of classes; abstract classes, final classes,
etc.
Apart from the above mentioned types of classes, Java also has some special classes called Inner classes
and Anonymous classes.
Example: The Employee class has four instance variables - name, age, designation and salary. The class has
one explicitly defined constructor, which takes a parameter.
import java.io.*;
int age;
String designation;
double salary;
this.name = name;
age = empAge;
designation = empDesig;
salary = empSalary;
System.out.println("Name:"+ name );
System.out.println("Age:" + age );
System.out.println("Designation:" + designation );
System.out.println("Salary:" + salary);
}
As mentioned previously in this tutorial, processing starts from the main method. Therefore, in order for
us to run this Employee class there should be a main method and objects should be created. We will be
creating a separate class for these tasks.
Example 2: Following is the EmployeeTest class, which creates two instances of the class Employee and
invokes the methods for each object to assign values for each variable.
import java.io.*;
empOne.empAge(26);
empOne.empSalary(1000);
empOne.printEmployee();
empTwo.empAge(21);
empTwo.empDesignation("Software Engineer");
empTwo.empSalary(500);
empTwo.printEmployee();
Output
Now, compile both the classes and then run EmployeeTest to see the result as follows −
Name:James Smith
Age:26
Designation:Senior Software Engineer
Salary:1000.0
Name:Mary Anne
Age:21
Designation:Software Engineer
Salary:500.0
Java class attributes are the variables that are bound in a class i.e., the variables which are used to define
a class are class attributes.
A class attribute defines the state of the class during program execution. A class attribute is accessible
within class methods by default.
For example, there is a class "Student" with some data members (variables) like roll_no, age, and name.
These data members are considered class attributes.
To create (declare) a class attribute, use the access modifier followed by the data type and attribute
name. It's similar to declaring a variable.
Syntax
String breed;
int age;
String color;
void barking() {
void hungry() {
void sleeping() {
}
In above class, we've fields like breed, age, and color which are also known as class attributes.
To access the class attribute, you need to create an object first and then use the dot (.) operator with the
object name. Class attributes can be also called within the class methods directly.
Syntax
object_name.attribute_name;
class Dog {
int age = 2;
System.out.println(obj.breed);
System.out.println(obj.age);
System.out.println(obj.color);
Output
German Shepherd
Black
Syntax
object_name.attribute_name = new_value;
class Dog {
int age = 2;
System.out.println("Before modifying:");
System.out.println(obj.breed);
System.out.println(obj.age);
System.out.println(obj.color);
obj.age = 3;
obj.color = "Golden";
// Printing
System.out.println("\nAfter modifying:");
System.out.println(obj.breed);
System.out.println(obj.age);
System.out.println(obj.color);
}
Output
Before modifying:
German Shepherd
Black
After modifying:
Golden Retriever
Golden
You can also make the class attributes read-only by using the final keyword after the access modifier
while declaring an attribute.
Syntax
In the below example, the name attribute is set to read-only using the final keyword. Now this attribute
can not be modified and JVM will complain if we try to modify this attribute.
class Dog {
System.out.println(dog.name);
}
Output
Compile and run Tester. This will produce the following result −
The class methods are methods that are declared within a class. They perform specific operations and
can access, modify the class attributes.
Class methods declaration is similar to the user-defined methods declaration except that class methods
are declared within a class.
The class methods are declared by specifying the access modifier followed by the return
type, method_name, and parameters list.
Syntax
// method body
• modifier − It defines the access type of the method and it is optional to use.
• nameOfMethod − This is the method name. The method signature consists of the method name
and the parameter list.
• Parameter List − The list of parameters, it is the type, order, and number of parameters of a
method. These are optional, method may contain zero parameters.
• method body − The method body defines what the method does with the statements.
Example: Here is the source code of the above defined method called minimum(). This method takes
two parameters n1 and n2 and returns the minimum between the two −
class Util {
min = n2;
else
min = n1;
return min;
To access a class method (public class method), you need to create an object first, then by using the
object you can access the class method (with the help of dot (.) operator).
Syntax
object_name.method_name([parameters]);
Example: To demonstrate how to define class method and how to access it. Here, We've created an
object of Util class and call its minimum() method to get minimum value of given two numbers −
class Util {
int min;
min = n2;
else
min = n1;
return min;
int a = 11;
int b = 6;
Output
Minimum value = 6
Note − The keyword this is used only within instance methods or constructors
• Differentiate the instance variables from local variables if they have same names, within a
constructor or a method.
class Student {
int age;
Student(int age) {
this.age = age;
• Call one type of constructor (parametrized constructor or default) from other in a class. It is known
as explicit constructor invocation.
class Student {
int age
Student() {
this(20);
}
Student(int age) {
this.age = age;
Here is an example that uses this keyword to access the members of a class. Copy and paste the following
program in a file with the name, Tester.java.
Tester() {
Tester(int num) {
this();
this.num = num;
this.greet();
obj1.print();
obj2.print();
Output
Hi Welcome to Tutorialspoint
Hi Welcome to Tutorialspoint
There are two types of class methods public and static class method. The public class methods are
accessed through the objects whereas, the static class methods are accessed are accesses without an
object. You can directly access the static methods.
Example
The following example demonstrates the difference between public and static class methods:
fun1();
obj.fun2();
Output
It is possible to define a method that will be called just before an object's final destruction by the garbage
collector. This method is called finalize( ), and it can be used to ensure that an object terminates cleanly.
For example, you might use finalize( ) to make sure that an open file owned by that object is closed.
To add a finalizer to a class, you simply define the finalize( ) method. The Java runtime calls that method
whenever it is about to recycle an object of that class.
Inside the finalize( ) method, you will specify those actions that must be performed before an object is
destroyed.
Here, the keyword protected is a specifier that prevents access to finalize( ) by code defined outside its
class.
This means that you cannot know when or even if finalize( ) will be executed. For example, if your
program ends before garbage collection occurs, finalize( ) will not execute.
Java Constructors
Java constructors are special types of methods that are used to initialize an object when it is created. It
has the same name as its class and is syntactically similar to a method. However, constructors have no
explicit return type.
Typically, you will use a constructor to give initial values to the instance variables defined by the class or
to perform any other start-up procedures required to create a fully formed object.
All classes have constructors, whether you define one or not because Java automatically provides a default
constructor that initializes all member variables to zero. However, once you define your constructor, the
default constructor is no longer used.
• The name of the constructors must be the same as the class name.
• Java constructors do not have a return type. Even do not use void as a return type.
• There can be multiple constructors in the same class, this concept is known as constructor
overloading.
• The access modifiers can be used with the constructors, use if you want to change the
visibility/accessibility of constructors.
• Java provides a default constructor that is invoked during the time of object creation. If you create
any type of constructor, the default constructor (provided by Java) is not invoked.
Syntax
class ClassName {
ClassName() {
// Creating a constructor
Main() {
System.out.println("Hello, World!");
Hello, World!
• No-Args Constructor
• Parameterized Constructor
1. Default Constructor
If you do not create any constructor in the class, Java provides a default constructor that initializes the
object.
In this example, there is no constructor defined by us. The default constructor is there to initialize the
object.
int num1;
int num2;
Output
num1 : 0
num2 : 0
int num1;
int num2;
Main() {
num1 = -1;
num2 = -1;
Output
num1 : -1
num2 : -1
3. Parameterized Constructor
Most often, you will need a constructor that accepts one or more parameters. Parameters are added to a
constructor in the same way that they are added to a method, just declare them inside the parentheses
after the constructor's name.
int num2;
Main(int a, int b) {
num1 = a;
num2 = b;
System.out.println("obj_x");
System.out.println("obj_y");
Output
obj_x
num1 : 10
num2 : 20
obj_y
num1 : 100
num2 : 200
Example 2: Parameterized Constructor
// A simple constructor.
class MyClass {
int x;
MyClass(int i ) {
x = i;
Output
10 20
class Student {
String name;
int age;
// no-args constructor
Student() {
this.name = "Unknown";
this.age = 0;
Student(String name) {
this.name = name;
this.age = 0;
this.name = name;
this.age = age;
// Printing details
System.out.println("std1...");
std1.printDetails();
System.out.println("std2...");
std2.printDetails();
System.out.println("std3...");
std3.printDetails();
Output
td1...
Name : Unknown
Age : 0
std2...
Name : Jordan
Age : 0
std3...
Name : Paxton
Age : 25
The lifecycle of a Java object is managed by the JVM. Once an object is created by the programmer, we
need not worry about the rest of its lifecycle. The JVM will automatically find those objects that are not in
use anymore and reclaim their memory from the heap.
You cannot deallocate an object programmatically in Java as you can do in non-GC languages like C and
C++. Therefore, you cannot have dangling references in Java. However, you may have null references
(references that refer to an area of memory where the JVM won't ever store objects). Whenever a null
reference is used, the JVM throws a NullPointerException.
Note that while it is rare to find memory leaks in Java programs thanks to the GC, they do happen. We will
create a memory leak at the end of this chapter.
• Throughput collector
• CMS collector
• G1 collector
Each of the above algorithms does the same task - finding objects that are no longer in use and reclaiming
the memory that they occupy in the heap. One of the naïve approaches to this would be to count the
number of references that each object has and free it up as soon as the number of references turn 0 (this
is also known as reference counting). Why is this naïve? Consider a circular linked list. Each of its nodes
will have a reference to it, but the entire object is not being referenced from anywhere, and should be
freed, ideally.
Memory Coalescing
The JVM not only frees the memory, but also coalesces small memory chucks into bigger ones it. This is
done to prevent memory fragmentation.
The GC has to stop application threads while it is running. This is because it moves the objects around
when it runs, and therefore, those objects cannot be used. Such stops are called "stop-the-world" pauses
and minimizing the frequency and duration of these pauses is what we aim while tuning our GC.
Most JVMs divide the heap into three generations – the young generation (YG), the old generation (OG)
and permanent generation (also called tenured generation).
We shall look into a simple example. The String class in Java is immutable. This means that every time you
need to change the contents of a String object, you have to create a new object altogether. Let us suppose
you make changes to the string 1000 times in a loop as shown in the below code –
}
In each loop, we create a new string object, and the string created during the previous iteration becomes
useless (that is, it is not referenced by any reference). T lifetime of that object was just one iteration –
they’ll be collected by the GC in no time. Such short-lived objects are kept in the young generation area of
the heap. The process of collecting objects from the young generation is called minor garbage collection,
and it always causes a “stop-the-world” pause.
As the young generation gets filled up, the GC does a minor garbage collection. Dead objects are discarded,
and live objects are moved to the old generation. The application threads stop during this process.
Here, we can see the advantages that such a generation design offers. The young generation is only a small
part of the heap and gets filled up quickly. But processing it takes a lot lesser time than the time taken to
process the entire heap. So, the "stop-the-world" pauses in this case are much shorter, although more
frequent. We should always aim for shorter pauses over longer ones, even though they might be more
frequent.
The young generation is divided into two spaces − eden and survivor space. Objects that have survived
during the collection of eden are moved to survivor space, and those who survive the survivor space are
moved to the old generation. The young generation is compacted while it is collected.
As objects are moved to the old generation, it fills up eventually, and has to be collected and compacted.
Different algorithms take different approaches to this. Some of them stop the application threads (which
leads to a long "stop-the-world" pause since the old generation is quite big in comparison to the young
generation), while some of them do it concurrently while the application threads keep running. This
process is called full GC. Two such collectors are CMS and G1.
Following are the areas which we can configure based on the situations:
Let's understand each in detail while understanding their impact. We'll also discuss the recommendations
based on available memory, CPU configurations and other relevant factors.
Further, increasing the heap size has a severe penalty on the underlying OS. Using paging, the OS makes
our application programs see much more memory than is actually available. The OS manages this by using
some swap space on the disk, copying inactive portions of the programs into it. When those portions are
needed, the OS copies them back from the disk to the memory.
You can decide on how much of the heap do you want to allocate to the YG, and how much of it you want
to allocate to the OG. Both of these values affect the performance of our applications in the following way.
If the size of the YG is very large, then it would be collected less frequently. This would result in lesser
number of objects being promoted to the OG. On the other hand, if you increase OG's size too much, then
collecting and compacting it would take too much time and this would lead to long STW pauses. Thus, the
user has to find a balance between these two values.
class Calculator{
return a + b;
return a + b + c;
}
When you invoke the add() method based on the parameters you pass respective method body gets
executed.
class Calculator{
return a + b;
return a + b + c;
}
}
System.out.println(Calculator.add(20, 40));
Output
60
150
class Calculator{
return a + b;
return a + b + c;
System.out.println(calculator.add(20, 40));
}
Output
60
150
class Calculator{
return a + b;
return a + b;
System.out.println(calculator.add(20, 40));
System.out.println(calculator.add(20.0, 40.0));
Output
60
60.0
For example, the Thread class has 8 types of constructors. If we do not want to specify anything about a
thread then we can simply use the default constructor of the Thread class, however, if we need to specify
the thread name, then we may call the parameterized constructor of the Thread class with a String args
like this:
Consider the following implementation of a class Box with only one constructor taking three arguments.
// constructor overloading.
class Box
// specified
width = w;
height = h;
depth = d;
double volume()
As we can see that the Box() constructor requires three parameters. This means that all declarations of
Box objects must pass three arguments to the Box() constructor.
For example, the following statement is currently invalid:
Since Box() requires three arguments, it’s an error to call it without them. Suppose we simply wanted a
box object without initial dimension, or want to initialize a cube by specifying only one value that would
be used for all three dimensions. From the above implementation of the Box class, these options are not
available to us. These types of problems of different ways of initializing an object can be solved by
constructor overloading.
// Constructor Overloading
class Box {
// specified
width = w;
height = h;
depth = d;
// specified
}
// Driver code
// constructors
double vol;
vol = mybox1.volume();
vol = mybox2.volume();
vol = mycube.volume();
Output
// Constructor Overloading
int boxNo;
// boxNo specified
width = w;
height = h;
depth = d;
boxNo = num;
Box()
// an empty box
Box(int num)
this();
boxNo = num;
System.out.println(box1.width);
Output
0.0
As we can see in the above program we called Box(int num) constructor during object creation using only
box number. By using this() statement inside it, the default constructor(Box()) is implicitly called from it
which will initialize the dimension of Box with 0.
Note : The constructor calling should be first statement in the constructor body.
For example, the following fragment is invalid and throws compile time error.
Box(int num)
boxNo = num;
statement in a constructor */
this(); /*ERROR*/
• If we have defined any parameterized constructor, then the compiler will not create a default
constructor. and vice versa if we don’t define any constructor, the compiler creates the default
constructor(also known as no-arg constructor) by default during compilation
this Keyword
The this is a keyword in Java which is used as a reference to the object of the current class, with in an
instance method or a constructor. Using this you can refer the members of a class such as constructors,
variables and methods.
• Differentiate the instance variables from local variables if they have same names, within a
constructor or a method.
class Student {
int age;
Student(int age) {
this.age = age;
• Call one type of constructor (parametrized constructor or default) from other in a class. It is
known as explicit constructor invocation.
class Student {
int age
Student() {
this(20);
Student(int age) {
this.age = age;
Example
public class This_Example {
This_Example() {
This_Example(int num) {
this();
this.num = num;
this.greet();
obj2.print();
Output
Hi Welcome to Tutorialspoint
Recursion in Java
In Java, Recursion is a process in which a function calls itself directly or indirectly is called recursion and
the corresponding function is called a recursive function. Using a recursive algorithm, certain problems
can be solved quite easily. A few Java recursion examples are Towers of Hanoi
(TOH), Inorder/Preorder/Postorder Tree Traversals, DFS of Graph, etc.
In the recursive program, the solution to the base case is provided and the solution to the bigger problem
is expressed in terms of smaller problems.
int fact(int n)
{
if (n < = 1) // base case
return 1;
else
return n*fact(n-1);
}
In the above example, the base case for n < = 1 is defined and the larger value of a number can be solved
by converting it to a smaller one till the base case is reached.
Working of Recursion
The idea is to represent a problem in terms of one or more smaller sub-problems and add base conditions
that stop the recursion. For example, we compute factorial n if we know the factorial of (n-1). The base
case for factorial would be n = 0. We return 1 when n = 0.
1. Factorial Using Recursion: 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 numbers between 1 and N. The below-given
code computes the factorial of the numbers: 3, 4, and 5.
• 3= 3 *2*1 (6)
• 4= 4*3*2*1 (24)
• 5= 5*4*3*2*1 (120)
class GFG {
// recursive method
int fact(int n)
int result;
if (n == 1)
return 1;
result = fact(n - 1) * n;
return result;
// Driver Class
class Recursion {
// Main function
public static void main(String[] args)
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));
}
Output
Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 5 is 120
2. Fibonacci Series: Fibonacci Numbers are the numbers is the integer sequence where Fib(N) = Fib(N-2)
+ Fib(N-1). Below is the example to find 3,4,5.
// Fibonacci Series
import java.io.*;
// Driver Function
class GFG {
{
if (N == 0 || N == 1)
return N;
// Main function
// Fibonacci of 3
// Fibonacci of 4
// Fibonacci of 5
Output
Fibonacci of 3 2
Fibonacci of 4 3
Fibonacci of 5 5
Stack Overflow error: If the base case is not reached or not defined, then the stack overflow problem
may arise. Let us take an example to understand this.
int fact(int n)
{
// wrong base case (it may cause
// stack overflow).
if (n == 100)
return 1;
else
return n*fact(n-1);
}
If fact(10) is called, it will call fact(9), fact(8), fact(7) and so on but the number will never reach 100. So,
the base case is not reached. If the memory is exhausted by these functions on the stack, it will cause a
stack overflow error.
When any function is called from main(), the memory is allocated to it on the stack. A recursive function
calls itself, the memory for the called function is allocated on top of memory allocated to the calling
function and a different copy of local variables is created for each function call. When the base case is
reached, the function returns its value to the function by whom it is called and memory is de-allocated
and the process continues.
// working of recursion
class GFG {
if (test < 1)
return;
else {
// Statement 2
printFun(test - 1);
return;
int test = 3;
printFun(test);
}
Output
321123
When printFun(3) is called from main(), memory is allocated to printFun(3), a local variable test is
initialized to 3, and statements 1 to 4 are pushed on the stack as shown below diagram. It first prints ‘3’.
In statement 2, printFun(2) is called and memory is allocated to printFun(2), a local variable test is
initialized to 2, and statements 1 to 4 are pushed in the stack.
Similarly, printFun(2) calls printFun(1) and printFun(1) calls printFun(0). printFun(0) goes to if statement
and it return to printFun(1).
The remaining statements of printFun(1) are executed and it returns to printFun(2) and so on. In the
output, values from 3 to 1 are printed and then 1 to 3 are printed.
• Some problems are inherently recursive like tree traversals, Tower of Hanoi, etc. For such
problems, it is preferred to write recursive code.
• A variable or method declared without any access control modifier is available to any other class
in the same package. The fields in an interface are implicitly public static final and the methods in
an interface are by default public.
• Example of Default Access Modifiers: Variables and methods can be declared without any
modifiers, as in the following examples −
boolean processOrder() {
return true;
• Methods, variables, and constructors that are declared private can only be accessed within the
declared class itself.
• Private access modifier is the most restrictive access level. Class and interfaces cannot be private.
• Variables that are declared private can be accessed outside the class, if public getter methods are
present in the class.
• Using the private modifier is the main way that an object encapsulates itself and hides data from
the outside world.
return this.format;
this.format = format;
Here, the format variable of the Logger class is private, so there's no way for other classes to
retrieve or set its value directly.
So, to make this variable available to the outside world, we defined two public
methods: getFormat(), which returns the value of format, and setFormat(String), which sets its
value.
• Example 2
In this example, the data members and class methods of the Logger class are private. We are trying
to access those class methods in another class Main.
class Logger {
return this.format;
this.format = format;
// Creating an object
log.setFormat("Text");
System.out.println(log.getFormat());
Output
^2 errors
3. Protected Access Modifier
• Variables, methods, and constructors, which are declared protected in a superclass can be
accessed only by the subclasses in other package or any class within the package of the protected
members' class.
• The protected access modifier cannot be applied to class and interfaces. Methods, fields can be
declared protected, however methods and fields in a interface cannot be declared protected.
• Protected access gives the subclass a chance to use the helper method or variable, while
preventing a nonrelated class from trying to use it.
The following parent class uses protected access control, to allow its child class
override openSpeaker() method −
class AudioPlayer {
// implementation details
// implementation details
Here, if we define openSpeaker() method as private, then it would not be accessible from any
other class other than AudioPlayer. If we define it as public, then it would become accessible to
all the outside world. But our intention is to expose this method to its subclass only, that's why we
have used protected modifier.
• Example 1
// Class One
class One {
}
}
obj.printOne();
Output
• A class, method, constructor, interface, etc. declared public can be accessed from any other class.
Therefore, fields, methods, blocks declared inside a public class can be accessed from any class
belonging to the Java Universe.
• However, if the public class we are trying to access is in a different package, then the public class
still needs to be imported. Because of class inheritance, all public methods and variables of a class
are inherited by its subclasses.
• Syntax
// ...
The main() method of an application has to be public. Otherwise, it could not be called by a Java
interpreter (such as java) to run the class.
// Class One
class One {
obj.printOne();
Output
• Methods declared protected in a superclass must either be protected or public in subclasses; they
cannot be private.
• Methods declared private are not inherited at all, so there is no rule for them.
• The following table shows the summary of the accessibility in the same/different classes (or,
packages) based on the access modifiers.
In this example, we've created a class with a private variable age and a variable with default scope
as name. Using setter/getter method, we're updating age and getting value and name is updated
directly.
String name;
public Puppy() {
this.age = age;
return age;
myPuppy.setAge( 2 );
myPuppy.name = "Tommy";
Output
requirements than the iterative program as all functions will remain in the stack until the base
case is reached.
It also has greater time requirements because of function calls and returns overhead.
Note: Both recursive and iterative programs have the same problem-solving powers, i.e., every recursive
program can be written iteratively and vice versa is also true.
There are certain advantages associated with inner classes are as follows:
• Private methods of the outer class can be accessed, so bringing a new dimension and making it
closer to the real world.
We do use them often as we go advance in java object-oriented programming where we want certain
operations to be performed, granting access to limited classes.
Type 1: Nested Inner Class - 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
class Outer {
// Class 2
class Inner {
// Print statement
// Class 2
// Main class
class Main {
// main()
in.show();
Output
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
Java
// Class 1
// Outer class
class Outer {
// Method defined inside outer class
void outerMethod()
// Print statement
System.out.println("inside outerMethod");
// Class 2
// Inner class
class Inner {
Output:
An interface can also be nested and nested interfaces have some interesting properties. We will be
covering nested interfaces in the next post.
Type 2: Method Local Inner Classes - Inner class can be declared within a method of an outer class
which we will be illustrating in the below example where Inner is an inner class in outerMethod().
Example 1
// Class 1
// Outer class
class Outer {
void outerMethod()
// Print statement
System.out.println("inside outerMethod");
// Class 2
// Inner class
// It is local to outerMethod()
class Inner {
void innerMethod()
// called
System.out.println("inside innerMethod");
y.innerMethod();
}
}
// Class 3
// Main class
class GFG {
// method
x.outerMethod();
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
class Outer {
void outerMethod() {
int x = 98;
System.out.println("inside outerMethod");
class Inner {
void innerMethod() {
System.out.println("x= "+x);
y.innerMethod();
class MethodLocalVariableDemo {
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
class Outer {
void outerMethod() {
System.out.println("inside outerMethod");
class Inner {
void innerMethod() {
System.out.println("x = "+x);
}
}
y.innerMethod();
class MethodLocalVariableDemo {
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.
Type 3: Static Nested Classes - Static nested classes are not technically inner classes. They are like a static
member of outer class.
import java.util.*;
// Class 1
// Outer class
class Outer {
// Method
{
// Print statement
System.out.println("inside outerMethod");
// Class 2
// Print statement
outerMethod();
// Class 3
// Main class
class GFG {
// Calling method static display method rather than an instance of that class.
Outer.Inner.display();
Output
inside outerMethod
Type 4: Anonymous Inner Classes
Anonymous inner classes are declared without any name at all. They are created in two ways.
import java.util.*;
// Class 1
// Helper class
class Demo {
void show()
// Print statement
System.out.println(
// Class 2
// Main class
class Flavor1Demo {
// Method 1
// show() method
void show()
super.show();
// Print statement
};
// Method 2
d.show();
Output
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.
// Interface
interface Hello {
void show();
// Main class
class GFG {
// Method 1
// Print statement
};
// Method 2
h.show();
Output
i am in anonymous class
Output explanation: In the above code, we create an object of anonymous inner class but this anonymous
inner class is an implementer of the interface Hello. Any anonymous inner class can implement only one
interface at one time. It can either extend a class or implement an interface at a time.
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.
Overall, the use of inner classes can lead to more modular, maintainable, and flexible code.