Several editions of Java are available. Each one aims at different use cases. Some of the editions have had numerous name changes over the years; the current names of the editions are as follows:
Java SE
This is the most important edition. When people mention the term “Java,” they usually refer to this edition. This book concentrates solely on the Java SE platform.
This edition is meant to run on desktop machines and servers, and as we will see later, an embedded version is also available and bundled with Raspberry Pi’s Linux distribution.
Java SE is mostly meant to create standalone consoles, desktop GUIs, or headless applications; alternatively, it is used to create external libraries.
Java EE
Java EE builds upon Java SE; therefore, it requires that Java SE is installed. It adds lots of APIs in a lot of categories. Java EE applications usually run inside JVM application servers. This book does not cover Java EE in-depth but will mention it from time to time. This is because it is a very important addition to the Java platform, especially for business developers.
Java ME
Before the days of iOS and Android, Java ME happened to be an important platform for feature phones and early smartphones for games and some basic applications. iOS and Android both never supported Java ME applications, so nowadays it does not play a major role anymore
A class is a user-defined blueprint or prototype from which objects are created. It represents the set of properties or methods that are common to all objects of one type.
syx:
class <classname/logicalname>
{
}
eg: class SavingAccountForm
{
}
An object is nothing but a self-contained component that consists of methods and properties to make a particular type of data useful. Object determines the behavior of the class. When you send a message to an object, you are asking the object to invoke or execute one of its methods.
From a programming point of view, an object can be a data structure, a variable or a function. It has a memory location allocated. The object is designed as class hierarchies.
Syntax:
ClassName ReferenceVariable = new ClassName();
A Java method is a collection of statements that are grouped together to perform an operation. When you call the System.out.println() method, for example, the system actually executes several statements in order to display a message on the console.
Modifier-: Defines access type of the method i.e. from where it can be accessed in your application. In Java, there 4 types of access specifiers.
The return type: The data type of the value returned by the method or void if does not return a value.
Built-in: Build-in methods are part of the compiler package, such as System.out.println() and System.exit(0). |
User-defined: User-defined methods are created by you, the programmer. These methods take-on names that you assign to them and perform tasks that you create. |
public static void main(String[]args) –>Execution will be start from this method only..
ToCompile java Applications we can use
syntax: javac filename.java
ex: javac welcome.java
once compilation is complete
.class file will be generated based on classname
To convert bytecode to executable format
syn:
java classname
ex:
java Welcome
Variables are nothing but reserved memory locations to store values. This means that when you create a variable you reserve some space in the memory.
Based on the data type of a variable, the operating system allocates memory and decides what can be stored in the reserved memory. Therefore, by assigning different data types to variables, you can store integers, decimals, or characters in these variables.
There are two data types available in Java −
boolean: boolean data type represents only one bit of information either true or false, but the size of the boolean data type is virtual machine-dependent.
Syntax:
boolean booleanVar;
Example :
// Java program to demonstrate boolean data type
class Webmobilez{
public static void main(String args[])
{
boolean b = true;
if (b == true)
System.out.println("Hi All");
}
}
Out Put:
Hi All
byte: The byte data type is an 8-bit signed two’s complement integer. The byte data type is useful for saving memory in large arrays.
Syntax:
byte byteVar;
Size:
1 byte ( 8 bits )
Values:
-128 to 127
Default Value:
0
// Java program to demonstrate byte data type in Java
class Webmobilez{
public static void main(String args[])
{
byte a = 126;
// byte is 8 bit value
System.out.println(a);
a++;
System.out.println(a);
// It overflows here because
// byte can hold values from -128 to 127
a++;
System.out.println(a);
// Looping back within the range
a++;
System.out.println(a);
}
}
Out Put:
126
127
-128
-127
short: The short data type is a 16-bit signed two’s complement integer.
short shortVar;
Size:
2 byte ( 16 bits )
Values:
-32, 768 to 32, 767 (inclusive)
Default Value:
0
int: It is a 32-bit signed two’s complement integer
Syntax:
int intVar;
Size:
4 byte ( 32 bits )
Values:
-2, 147, 483, 648 to 2, 147, 483, 647 (inclusive)
Default Value:
0
long: The long data type is a 64-bit two’s complement integer.
Syntax:
long longVar;
Size:
8 byte ( 64 bits )
float: The float data type is a single-precision 32-bit IEEE 754 floating-point. Use a float (instead of double) if you need to save memory in large arrays of floating-point numbers.
Syntax:
float floatVar;
Size:
4 byte ( 32 bits )
Values:
upto 7 decimal digits
Default Value:
0.0
double: The double data type is a double-precision 64-bit IEEE 754 floating-point. For decimal values, this data type is generally the default choice.
Syntax:
double doubleVar;
Size:
8 byte ( 64 bits )
Values:
upto 16 decimal digits
Default Value:
0.0
char: The char data type is a single 16-bit Unicode character.
Syntax:
char charVar;
Size:
2 byte ( 16 bits )
Values:
'\u0000' (0) to '\uffff' (65535)
Default Value:
'\u0000'
The Non-Primitive Data Types will contain a memory address of variable value because the reference types won’t store the variable value directly in memory. They are strings, objects, arrays, etc.
a) UserDeveind DataType
b) Predefined DataType
user-defined DataType
class Welcome
{
}
Welcome wel;
here
Welcome --->User-definedDataType
wel ------->Referece varible
A string is a predefined DataType using this we can represent a group of characters
String: Strings are defined as an array of characters. The difference between a character array and a string is the string is terminated with a special character ‘\0’.
Below is the basic syntax for declaring a string in Java programming language.
Syntax:
<String_Type> <string_variable> = “<sequence_of_string>”;
Example:
// Declare String without using new operator
String s = "webmobilez";
// Declare String using new operator
String s1 = new String("webmobilez");
There are three kinds of variables in Java −
public class StudentDetails {
public void StudentAge()
{
// local variable age
int age = 0;
age = age + 5;
System.out.println("Student age is : " + age);
}
public static void main(String args[])
{
StudentDetails obj = new StudentDetails();
obj.StudentAge();
}
}
output:
Student age is : 5
Instance Variables: Instance variables are non-static variables and are declared in a class outside any method, constructor or block.
Static Variables: Static variables are also known as Class variables.
To access static variables, we need not create an object of that class, we can simply access the variable as
class_name.variable_name;
import java.io.*;
class Emp {
// static variable salary
public static double salary;
public static String name = "Harsh";
}
public class EmpDemo {
public static void main(String args[])
{
// accessing static variable without object
Emp.salary = 1000;
System.out.println(Emp.name + "'s average salary:"
+ Emp.salary);
}
}
Output:
Harsh's average salary:1000.0
The following table will demonstrate the use of increment and decrement operators.
Assignment Operators
The java assignment operator statement has the following syntax:
=
If the value already exists in the variable it is overwritten by the assignment operator (=).
public class AssignmentOperatorsDemo {
public AssignmentOperatorsDemo( ) {
// Assigning Primitive Values
int j, k;
j = 10; // j gets the value 10.
j = 5; // j gets the value 5. Previous value is overwritten.
k = j; // k gets the value 5.
System.out.println("j is : "+j);
System.out.println("k is : "+k);
// Assigning References
Integer i1 = new Integer("1");
Integer i2 = new Integer("2");
System.out.println("i1 is : "+i1);
System.out.println("i2 is : "+i2);
i1 = i2;
System.out.println("i1 is : "+i1);
System.out.println("i2 is : "+i2);
// Multiple Assignments
k = j = 10; // (k = (j = 10))
System.out.println("j is : "+j);
System.out.println("k is : "+k);
}
public static void main(String args[]){
new AssignmentOperatorsDemo();
}
}
Assignment Operators
x operation= y
is equivalent to
x = x operation y
x and y must be numeric or char types except for “=”, which allows x and y also to be object references.
In this case, x must be of the same type of class or interface as y. If mixed floating-point and integer
types, the rules for mixed types in expressions apply.
= | Assignment operator. x = y; y is evaluated and x set to this value. The value of x is then returned. |
+=, -=, *=, /=, %= | Arithmetic operation and then assignment, e.g. x += y; is equivalent to x = x + y; |
&=, |=, ^= | Bitwise operation and then assignment, e.g. x &= y; is equivalent to x = x & y; |
<<=, >>=, >>>= | Shift operations and then assignment, e.g. x <<= n; is equivalent to x = x << n; |
Arithmetic Operators
Java provides eight Arithmetic operators. They are for addition, subtraction, multiplication, division, modulo (or remainder), increment (or add 1), decrement (or subtract 1), and negation. An example program is shown below that demonstrates the different arithmetic operators in java.
The binary operator + is overloaded in the sense that the operation performed is determined by the type of the operands. When one of the operands is a String object, the other operand is implicitly converted to its string representation and string concatenation is performed.
String message = 100 + “Messages”; //”100 Messages”
public class ArithmeticOperatorsDemo {
public ArithmeticOperatorsDemo() {
int x, y = 10, z = 5;
x = y + z;
System.out.println("+ operator resulted in " + x);
x = y - z;
System.out.println("- operator resulted in " + x);
x = y * z;
System.out.println("* operator resulted in " + x);
x = y / z;
System.out.println("/ operator resulted in " + x);
x = y % z;
System.out.println("% operator resulted in " + x);
x = y++;
System.out.println("Postfix ++ operator resulted in " + x);
x = ++z;
System.out.println("Prefix ++ operator resulted in " + x);
x = -y;
System.out.println("Unary operator resulted in " + x);
// Some examples of special Cases
int tooBig = Integer.MAX_VALUE + 1; // -2147483648 which is
// Integer.MIN_VALUE.
int tooSmall = Integer.MIN_VALUE - 1; // 2147483647 which is
// Integer.MAX_VALUE.
System.out.println("tooBig becomes " + tooBig);
System.out.println("tooSmall becomes " + tooSmall);
System.out.println(4.0 / 0.0); // Prints: Infinity
System.out.println(-4.0 / 0.0); // Prints: -Infinity
System.out.println(0.0 / 0.0); // Prints: NaN
double d1 = 12 / 8; // result: 1 by integer division. d1 gets the value
// 1.0.
double d2 = 12.0F / 8; // result: 1.5
System.out.println("d1 is " + d1);
System.out.println("d2 iss " + d2);
}
public static void main(String args[]) {
new ArithmeticOperatorsDemo();
}
}
Arithmetic Operators
x and y are numeric or char types. If mixed floating-point and integer types, then floating-point
arithmetic used and a floating-point value returned. If mixed integer types, the wider type is returned. If
double and float mixed, double is returned.
x + y | Addition |
x – y | Subtraction |
x * y | Multiplication |
x / y | Division If FP arithmetic and y = 0.0, then infinity returned if x is not zero, NaN if x is zero.ArthmeticException thrown if x & y are integer types and y is zero. |
x % y | Modulo – remainder of x/y returned.If FP arithmetic and y = 0.0 or infinity,then NaN returned ArthmeticException thrown if x & y are integer types and y is zero. |
-x | Unary minus Negation of x value |
Boolean Operators
x and y are boolean types. x and y can be expressions that result in a boolean value.Result is a boolean true or false value.
x && y | x && y | If both x and y are true, result is true. If either x or y are false, the result is false If x is false, y is not evaluated. |
x & y | Boolean AND | If both x and y are true,the result is true. If either x or y are false, the result is false Both x and y are evaluated before the test. |
x || y | Conditional OR | If either x or y are true, the result is true. If x is true, y is not evaluated. |
x | y | Boolean OR | If either x or y are true, the result is true. Both x & y are evaluated before the test. |
!x | Boolean NOT | If x is true, the result is false. If x is false, the result is true. |
x ^ y | Boolean XOR | If x is true and y is false, the result is true. If x is false and y is true, the result is true. Otherwise, the result is false. Both x and y are evaluated before the test. |
Comparison Operators
Relational operators in Java are used to compare 2 or more objects. Java provides six relational operators: greater than (>), less than (<), greater than or equal (>=), less than or equal (<=), equal (==), and not equal (!=).All relational operators are binary operators, and their operands are numeric expressions.Binary numeric promotion is applied to the operands of these operators. The evaluation results in a boolean value. Relational operators have precedence lower than arithmetic operators, but higher than that of the assignment operators. An example program is shown below that demonstrates the different relational
operators in java
public class RelationalOperatorsDemo {
public RelationalOperatorsDemo( ) {
int x = 10, y = 5;
System.out.println(”x > y : “+(x > y));
System.out.println(”x < y : “+(x < y));
System.out.println(”x >= y : “+(x >= y));
System.out.println(”x <= y : “+(x <= y));
System.out.println(”x == y : “+(x == y));
System.out.println(”x != y : “+(x != y));
}
public static void main(String args[]){
new RelationalOperatorsDemo();
}
}
Logical operators return a true or false value based on the state of the Variables. There are six logical, or boolean, operators. They are AND, conditional AND, OR, conditional OR, exclusive OR, and NOT. Each
argument to a logical operator must be a boolean data type, and the result is always a boolean data type. An example program is shown below that demonstrates the different Logical operators in java.
public class LogicalOperatorsDemo {
public LogicalOperatorsDemo() {
boolean x = true;
boolean y = false;
System.out.println("x & y : " + (x & y));
System.out.println("x && y : " + (x && y));
System.out.println("x | y : " + (x | y));
System.out.println("x || y: " + (x || y));
System.out.println("x ^ y : " + (x ^ y));
System.out.println("!x : " + (!x));
}
public static void main(String args[]) {
new LogicalOperatorsDemo();
}
}
Comparison Operators
x and y are numeric or char types only except for “==” and “!=” operators, which can also compare
references. If mixed types, then the narrower type converted to wider type. The returned value is boolean true or false.
x < y | Is x less than y ? |
x <= y | Is x less than or equal to y ? |
x > y | Is x greater than y ? |
x >= y | Is x greater than or equal to y ? |
x == y | Is x equal to y ? |
x != y | Is x not equal to y ? |
Bitwise Operators
Java provides Bit wise operators to manipulate the contents of variables at the bit level.
These variables must be of numeric data type ( char, short, int, or long). Java provides seven bitwise
operators. They are AND, OR, Exclusive-OR, Complement, Left-shift, Signed Right-shift, and Unsigned
Right-shift. An example program is shown below that demonstrates the different Bit wise operators in java.
Ex:
public class BitwiseOperatorsDemo {
Comparison Operators
x and y are numeric or char types only except for "==" and "!=" operators, which can also compare
references. If mixed types, then the narrower type converted to wider type. Returned value is boolean
true or false.
x < y Is x less than y ?
x <= y Is x less than or equal to y ?
x > y Is x greater than y ?
x >= y Is x greater than or equal to y ?
x == y Is x equal to y ?
x != y Is x not equal to y ?
public BitwiseOperatorsDemo() {
int x = 0xFAEF; //1 1 1 1 1 0 1 0 1 1 1 0 1 1 1 1
int y = 0xF8E9; //1 1 1 1 1 0 0 0 1 1 1 0 1 0 0 1
int z;
System.out.println(”x & y : ” + (x & y));
System.out.println(”x | y : ” + (x | y));
System.out.println(”x ^ y : ” + (x ^ y));
System.out.println(”~x : ” + (~x));
System.out.println(”x << y : ” + (x << y));
System.out.println(”x >> y : ” + (x >> y));
System.out.println(”x >>> y : ” + (x >>> y));
//There is no unsigned left shift operator
}
public static void main(String args[]) {
new BitwiseOperatorsDemo();
}
}
The result of applying bitwise operators between two corresponding bits in the operands is shown in the
Table below.
There is only call by value in java, not call by reference. If we call a method passing a value, it is known as call by value. The changes being done in the called method, is not affected in the calling method.
call by value in java
class Operation{
int data=50;
void change(int data){
data=data+100;//changes will be in the local variable only
}
public static void main(String args[]){
Operation op=new Operation();
System.out.println("before change "+op.data);
op.change(500);
System.out.println("after change "+op.data);
}
}
Output:before change 50 after change 50
Call by Reference method
Call by reference method copies the address of an argument into the formal parameter. In this method, the address is used to access the actual argument used in the function call. It means that changes made in the parameter alter the passing argument.
public class JavaTester {
public static void main(String[] args) {
IntWrapper a = new IntWrapper(30);
IntWrapper b = new IntWrapper(45);
System.out.println("Before swapping, a = " + a.a + " and b = " + b.a);
// Invoke the swap method
swapFunction(a, b);
System.out.println("\n**Now, Before and After swapping values will be different here**:");
System.out.println("After swapping, a = " + a.a + " and b is " + b.a);
}
public static void swapFunction(IntWrapper a, IntWrapper b) {
System.out.println("Before swapping(Inside), a = " + a.a + " b = " + b.a);
// Swap n1 with n2
IntWrapper c = new IntWrapper(a.a);
a.a = b.a;
b.a = c.a;
System.out.println("After swapping(Inside), a = " + a.a + " b = " + b.a);
}
}
class IntWrapper {
public int a;
public IntWrapper(int a){ this.a = a;}
}
Before swapping, a = 30 and b = 45 Before swapping(Inside), a = 30 b = 45 After swapping(Inside), a = 45 b = 30 **Now, Before and After swapping values will be different here**: After swapping, a = 45 and b is 30
After Creation of Object compulsory we should perform initialization then only that object in a position to provide service to others.At the time of Object Creation some peace of code will execute automatically to perform initialization that peace of code is nothing but “Constructor”. Hence the main Objective of constructor is to perform initialization.
If we don’t have constructor we will face burden. For example see the following code.
Ex:
class Student
{
String name;
int rollno;
public static void main(String[] args)
{
Student s1 = new Student();
Student s2 = new Student();
Student s3 = new Student();
Student s4 = new Student();
s1.name = "Malli";s1.rollno = 101;
s2.name = "Sankar";s2.rollno = 102;
s3.name = "Kiran";s3.rollno = 103;
s4.name = "Sai";s4.rollno = 104;
System.out.println(s1.name+"-----"+s1.rollno);
System.out.println(s2.name+"-----"+s2.rollno);
System.out.println(s3.name+"-----"+s3.rollno);
System.out.println(s4.name+"-----"+s4.rollno);
}
}
To over come this type of burden constructor was introduced.
Ex:-
class Student
{
String name;
int rollno;
Student(String name, int rollno)
{
this.name = name;
this.rollno = rollno;
}
public static void main(String[] args)
{
Student s1 = new Student("raju",101);
Student s2 = new Student("mani",102);
System.out.println(s1.name+"-----"+s1.rollno);
System.out.println(s2.name+"-----"+s2.rollno);
}
}
O/P:
raju ——101
nani ——102
Rules for Constructor
While writing constructors we should follow the following rules.
1) The name of the constructor and name of the class must be same.
2) The only allowed modifiers for the constructors are public, private, protected, . If we
are using any other modifier we will get C.E(Compiler Error).
Ex:
class Test
{
static Test()
{
----
}
}
C.E:- modifier static not allowed here.
3) return type is not allowed for the constructors even void also. If we r declaring return type then the compiler treats it as a method and hence there is no C.E and R.E(RuntimeError).
class Test
{
void Test()
{
System.out.println("Hai .....");
}
public static void main(String arg[])
{
Test t = new Test();
}
}
It is legal(But Stupid) to have a method whose name is exactly same as class name.
Here it was treated as method.
Default Constructor
If we r not writing any constructor then the compiler always generates default constructor.
If we r writing at least one constructor then the compiler won’t generate any constructor.
Hence every class contains either programmer written constructor or compiler-generated default constructor but not both simultaneously.
Prototype of default constructor:
1) It is always no-arg constructor.
2) It contains only one – line super();
This is a call to superclass – constructor it is no-argument call only.
3) The modifier of the default constructor is same as class modifier(either public or default).
The first line inside any constructor must be a call to super class constructor(super()) or a call to overloaded constructor of the same class(this()). If we are not taking any thing then the compiler will always place
super() super() & this() in constructor
we should use as first statement in the constructor. We can use either super or this but not both simultaneously. Outside constructs we can’t use i.e we can invoke a constructor directly from another constructor only.
Overloaded Constructor
A class can contain more than one constructors with different arguments. This type of constructors are called “overloaded constructor”.
class Test
{
Test()
{
this(10);
System.out.println("No-arg constructor");
}
Test(int i)
{
this(10.5);
System.out.println("int-arg");
}
Test(double d)
{
System.out.println("double-arg")
}
public static void main(String arg[])
{
Test t1 = new Test();
Test t2 = new Test(10);
Case1:
class Test
{
Test()
{
super()
System.out.println("constructor")
}
}
Case2:
class Test
{
Test()
{
System.out.println("constructor")
super();
}
}
C.E: Call to super() must be first statement in constructor
Case3:
class Test
{
Test()
{
super();
this(10);
super("Constructor");
}
Test(int i)
{
System.out.println("Constructor")
}
}
Case4
class Test
{
public void m1()
{
super();
}
}
C.E: Call to to this must be first statement in
C.E: Call to to Super must be first statement in
Test t3 = new Test(20.5);
Test t4 = new Test('a');
Test t5 = new Test(10l);
}
}
Inheritance concept is not applicable for constructor and hence overriding is also not applicable.
Introduction
An array is a data structure that represents an index collection of fixed no of homogeneous data elements. The main advantage of arrays is we can represent a group of values with single name hence readability of the code will be improved. The main limitation of arrays is they are fixed in size.
i.e once we constructed an array there is no chance of increasing or decreasing bases on our requirement hence with respect to memory arrays shows worst performance we can overcome this problem by using collections.
Array Declaration
The following are the ways to declare an array.
1) int [] a;
2) int a[];
3) int [] a;
The first one is recommended to use because the type is clearly separated from the name.
At the first time of declarations we are not allowed to specify the size. Violation leads to C.E.
Ex:
int[] a
Declaring Multidimensional Arrays
The following are the valid declarations for multidimensional arrays.
int[][] a;
int a[][];
int [][]a;
int[] a[];
int[] []a;
we can specify the dimension before name of variable also, but this facility is available only for the
first variable.
int[] a[],b[];
Construction of Arrays
Single Dimension : Arrays are internally implemented as object hence by using new operator we can
construct an array.
Compulsory at the time of construction we should specify the size otherwise compile time error.
Ex:
int[] a = new int[10];
It is legal to have an error with size 0 there is no C.E or R.E
int[] a = new int[0];
If we are specifying array size with some –ve integer
int[] a = new int[-10];
we will get R.E saying NegativeArraySizeException.
The only allowed Data type to allow the size are byte, short, char, int. if we are using any other
datatype we will get a C.E.
length(): 1) It is the final method applicable only for String Objects.
2) It represents the no of characters present in the String.
Ex:
String s = “raju”;
System.out.println(s.length); -> C.E
System.out.println(s.length()); -> 4
In the case of Multidimensional array length variable always represent base size but not total no of
elements.
Ex:
int[][] a = new [3][2];
System.out.println(a.length);
System.out.println(a[0].length);
There is no variable which represents the total no of elements present in multidimensional arrays.
Anonymous Arrays
Some times we can declare an array with out name also such type of arrays are called anonymous arrays.The main objective of anonymous arrays is just for temporary usage. We can create an anonymous
arrays as follows.
Ex:
new int[] {10,20,30}
class Test
{
public static void main(String arg[])
{
System.out.println(sum(new int[]{10,20,30,40}));
}
public static int sum(int[] a)
{
int total = 0;
for(int i = 0; i< a.length;i++)
{
total = total + a[i];
}
return total;
}
}
Array Element Assignments
In the case of primitive arrays as array element any datatype is allowed which can be implicitly
promoted to the declared type.
Ex:
int [] a = new int[10];
in this case the following datatypes are allowed as array elements.
byte, short, int, char.
a[0] = 10;
a[1] = ‘a’;
byte b = 20;
a[2] = b;
a[3] = 10.5; possible loss of precision. found : double
required: int
in the case of object arrays as array elements we can provide either declared type object or it’s child
class objects.
Number[] n = new Number[6]
Array Variable Assignments
A char element can be promoted as the int element but a char array can’t be prompted to int array.
Ex:
int [] a = new int[6];
int [] b = a;
char[] ch = {‘a’,’b’,’c’};
int [] c = ch; -> Incompatible types found : char[]
required:int[]
Un initialized Arrays
Ex:
class Test
{
int[] a;
public static void main(String arg[])
{
Test t = new Test();
System.out.println(t.a); -> null
System.out.println(t.a[0]); -> NullPointerException
}
}
Instance Level
1) int[] a;
System.out.println(objectref.a) -> null
System.out.println(objectref.a[0]) -> NullPointerException.
2) int[] a = new int[6];
System.out.println(objectref.a); -> [I@123
System.out.println(objectref.a[0]); -> 0;
There are two types of modifiers in Java: access modifiers and non-access modifiers.
The access modifiers in Java specifies the accessibility or scope of a field, method, constructor, or class. We can change the access level of fields, constructors, methods, and class by applying the access modifier on it.
There are four types of Java access modifiers:
There are many non-access modifiers, such as static, abstract, synchronized, native, volatile, transient, etc. Here, we are going to learn the access modifiers only.
Java Access Modifiers
Access Modifier | within class | within package | outside package by subclass only | outside package |
---|---|---|---|---|
Private | Y | N | N | N |
Default | Y | Y | N | N |
Protected | Y | Y | Y | N |
Public | Y | Y | Y | Y |
Object-Oriented Programming is a programming style that is associated with concepts like class, object, Inheritance, Encapsulation, Abstraction, Polymorphism. Most popular programming languages like Java, C++, C#, Ruby, etc. follow an object-oriented programming paradigm.
Data Hiding
The data should not go out directly i.e outside person is not allowed to access the data this is nothing but “Data Hiding”.The main advantage of data hiding is we can achieve security. By using private modifier we can achieve this.
Ex:
Class datademo
{
private double amount;
………
}
It is highly recommended to declare data members with private modifier.
Abstraction
Hiding implementation details is nothing but abstraction. The main advantages of abstraction are we can achieve security as we r not highlighting internal implementation. The enhancement will become easy. Without affecting outside person we can change our internal implementation. It improves maintainability.
Note:-
1) If we don’t know about implementation just we have to represent the specification then we should go for interface
2) If we don’t know about complete implementation just we have partial implementation then we should go for abstract.
3) If we know complete implementation and if we r ready to provide service then we should go for
concrete class
Encapsulation
If a class follows data hiding and abstraction such type of class is said to be ‘Encapsulated’ class
Encapsulation = Data Hiding + Abstraction
Ex:
class Account
{
private int balance;
public void setBalance(int balance)
{
//validating the user & his permissions.
this.balance = balance;
}
public int getBalance()
{
//validating the user and his permissions.
return balance;
}
}
The data members we have to declared as private. So that outside person is not allowed to access directly we have to provide access to our data by defining setter and getter methods. i.e hiding data behind methods
is the central concept of encapsulation.
The main advantages of encapsulation are security, enhancement, maintainability.
Tightly Encapsulated Class
A class is said to be tightly encapsulated if all the data members declared as private
Ex:-
class student
{
private String name;
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
Q) which of the following classes are tightly encapsulated classes?
class x
{
private int i =10;
private int getI();
{
return i;
}
}
class z extends x
{
private int k = 40;
}
class x
{
int i = 0;
}
class y extends x
{
private int j = 20;
}
class z extends y
{
private int k = 30;
}
no class is tightly encapsulated if the parent class is not tightly encapsulated then no child class is tightly encapsulated.
-> Also known as ‘inheritance’.
-> By using extends keyword we can implement inheritance.
-> The main advantage is reusability.
Note:- parent class reference can be used to hold child class objects but by using that reference we r not allowed to call child class-specific methods.
class test
{
public static void main(String arg[])
{
p p1 = new p();
p1.m1();
p1.m2();
p1.m3(); C.E: Child class methods are not available to the parent class.
c c1 = new c();
c1.m1();
c1.m2();
c2.m3();
p p2 = new c();
p2.m1();
p2.m2();
p2.m3(); C.E: By using parent class reference we can’t call child class specific
method
c c4 = new p() C.E: Child class reference can’t be used to hold parent class object.
}
}
A class can extend only one class at a time but an interface can extend any no of interfaces simultaneously
-> Also known as Composition or Aggregation .
-> There is no specific keyword, but most of the cases we can implemented by using new keyword.
-> Main advantage is reusability.
Ex:
class engine
{
m1(){}
m2(){}
.
.
.
}
class car
{
engine e = new engine();
.
.
}
Class car has engine.
HAS – A relationship increases dependency b/w components and creates maintainability problems
In java method signature consists of method name and arguments list( including order also)
public void m1(int i, float f)
{
}
Compiler uses method signature to resolve method calls. Two methods with the same signature are not allowed in any java class, violation leads to compile time error.
Compiler uses method signature to resolve method calls.
Two methods with the same signature are not allowed in any java class, violation leads to compile time error.
Ex:
class Test
{
public void m1(int i)
{
}
public void m2()
{
}
public int m1(int i)
{
}
public void m1(int i, float f)
{
}
method signature
}
C.E:-m1(int) is already defined in Test
In java return type is not part of method signature
OverLoading
Two methods r said to be overloaded if the method names are same, But arguments are different(At least Order) Lack of overloading increases the complexity of the program in the case of ‘c’ language.
For the same requirement, we should maintain different method names if arguments are the same.
In C
abs(int i) -> only for int arguments.
fabs(float f) -> only for float arguments.
labs(long l) -> only for long arguments.
But in java, two methods with the same name are allowed even though arguments r different.
abs(int i)
abs(float f)
abs(long l)
Ex:
Case1:
class Test
{
public void m1()
{
System.out.println("no-args");
}
public void m1(int i)
{
System.out.println("int-args");
}
public void m2(double d)
{
System.out.println("double-args");
}
public static void main(String[] args)
{
Test t = new Test();
t.m1();
t.m1(10);
t.m1(10.5);
}
}
The overloading method resolution is the responsibility of compiler based on reference type and method
arguments. Hence overloading is considered as compile-time polymorphism or EarlyBinding.
Automatic promotion in overloading
Ex:-
Case2:
class Test
{
public void m1()
{
System.out.println("no-args");
}
public void m1(int i)
{
System.out.println("int-args");
}
public void m1(float f)
{
System.out.println("float-args");
}
public static void main(String[] args)
{
Test t = new Test();
t.m1();
t.m1(10);
t.m1(10l);
t.m1(10f);
t.m1('a');
t.m1(10.5);
}
}
In the case of overloading if there is no method with the required argument then the compiler won’t raise immediately compile time error. First it will promote arguments to next level and checks is there any matched method with promoted arguments, if there is no such method compiler will promote the argument to the next level and checks for the matched method. After all possible promotions still the compiler unable to find the matched method then it raises compile time error.
Ex:-
class Test
{
public void m1(String s)
{
System.out.println("String Version");
}
public void m1(Object o)
{
System.out.println("Object Version");
}
public static void main(String arg[])
{
Test t = new Test();
t.m1("raju"); String Version
t.m1(new Object()); Object Version
t.m1(null);
}
}
In the case of overloading the more specific version will get the chance first.
Overriding
What ever the parent has by default available to the child class through inheritance, If the child class is not
satisfied with the parent class implementation then the child is allowed to overwrite that parent class method
to provide it’s own specific implementation, this concept is nothing but “overriding”.
JDBC stands for Java Database Connectivity. JDBC is a Java API to connect and execute the query with the database. It is a part of JavaSE (Java Standard Edition). JDBC API uses JDBC drivers to connect with the database. There are four types of JDBC drivers:
We have discussed the above four drivers in the next chapter.
We can use JDBC API to access tabular data stored in any relational database. By the help of JDBC API, we can save, update, delete and fetch data from the database. It is like Open Database Connectivity (ODBC) provided by Microsoft.
Before JDBC, ODBC API was the database API to connect and execute the query with the database. But, ODBC API uses ODBC driver which is written in C language (i.e. platform dependent and unsecured). That is why Java has defined its own API (JDBC API) that uses JDBC drivers (written in Java language).
We can use JDBC API to handle database using Java program and can perform the following activities:
Hibernate is a Java framework that simplifies the development of Java application to interact with the database. It is an open source, lightweight, ORM (Object Relational Mapping) tool. Hibernate implements the specifications of JPA (Java Persistence API) for data persistence.
An ORM tool simplifies the data creation, data manipulation and data access. It is a programming technique that maps the object to the data stored in the database
The ORM tool internally uses the JDBC API to interact with the database.
Java Persistence API (JPA) is a Java specification that provides certain functionality and standard to ORM tools. The javax.persistence package contains the JPA classes and interfaces.
Following are the advantages of hibernate framework:
Hibernate framework is open source under the LGPL license and lightweight.
The performance of hibernate framework is fast because cache is internally used in hibernate framework. There are two types of cache in hibernate framework first level cache and second level cache. First level cache is enabled by default.
HQL (Hibernate Query Language) is the object-oriented version of SQL. It generates the database independent queries. So you don’t need to write database specific queries. Before Hibernate, if database is changed for the project, we need to change the SQL query as well that leads to the maintenance problem.
Hibernate framework provides the facility to create the tables of the database automatically. So there is no need to create tables in the database manually.
Fetching data from multiple tables is easy in hibernate framework.
Hibernate supports Query cache and provides statistics about query and database status.
Hibernate Reference Website LinkJSP technology is used to create web application just like Servlet technology. It can be thought of as an extension to Servlet because it provides more functionality than servlet such as expression language, JSTL, etc.
A JSP page consists of HTML tags and JSP tags. The JSP pages are easier to maintain than Servlet because we can separate designing and development. It provides some additional features such as Expression Language, Custom Tags, etc.
There are many advantages of JSP over the Servlet. They are as follows:
JSP technology is the extension to Servlet technology. We can use all the features of the Servlet in JSP. In addition to, we can use implicit objects, predefined tags, expression language and Custom tags in JSP, that makes JSP development easy.
JSP can be easily managed because we can easily separate our business logic with presentation logic. In Servlet technology, we mix our business logic with the presentation logic.
If JSP page is modified, we don’t need to recompile and redeploy the project. The Servlet code needs to be updated and recompiled if we have to change the look and feel of the application.
JSP Reference Website LinkAn ORM tool simplifies the data creation, data manipulation and data access. It is a programming technique that maps the object to the data stored in the database.
Hibernate framework uses many objects such as session factory, session, transaction etc. alongwith existing Java API such as JDBC (Java Database Connectivity), JTA (Java Transaction API) and JNDI (Java Naming Directory Interface).
The Hibernate architecture includes many objects such as a persistent object, session factory, transaction factory, connection factory, session, transaction, etc.
The Hibernate architecture is categorized in four layers.
In this state, hibernate doesn’t track the object but you can re-attach a detached object to Hibernate session by calling the update() or saveOrUpdate(), or merge() method. Once reattached, the detached object will move to Persistent state.
Actually our POJO class object having 3 states like…