Java 8 & Java 9 New Features Study Material: DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038
Java 8 & Java 9 New Features Study Material: DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038
Java 8 & Java 9 New Features Study Material: DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038
New Features
Study Material
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
1 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Java 8 New Features
Table of Contents
4) Predicates ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 21
5) Functions :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 24
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
2 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Java 9 New Features
Table of Contents
1) Private Methods in Interfaces …………………………………………………………………………… 40
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
3 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Java 8 New Features
Java 7 – July 28th 2011
2 Years 7 Months 18 Days
Java 10 - 2018
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
4 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Lambda (λ) Expressions
☀ Lambda calculus is a big change in mathematical world which has been introduced in 1930.
Because of benefits of Lambda calculus slowly this concepts started using in programming
world. “LISP” is the first programming which uses Lambda Expression.
☀ The Main Objective of Lambda Expression is to bring benefits of functional programming into
Java.
Ex: 1
() {
public void m1() { sop(“hello”);
sop(“hello”); }
} () { sop(“hello”); }
() sop(“hello”);
Ex:2
If the type of the parameter can be decided by compiler automatically based on the context
then we can remove types also.
The above Lambda expression we can rewrite as (a,b) sop (a+b);
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
5 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Ex: 3
Conclusions:
Ex:
() sop(“hello”);
(int a ) sop(a);
(inta, int b) return a+b;
2) Usually we can specify type of parameter. If the compiler expects the type based on the
context then we can remove type. i.e., programmer is not required.
Ex:
(inta, int b) sop(a+b);
(a,b) sop(a+b);
3) If multiple parameters present then these parameters should be separated with comma (,).
4) If zero number of parameters available then we have to use empty parameter [ like ()].
Ex: () sop(“hello”);
5) If only one parameter is available and if the compiler can expect the type then we can remove
the type and parenthesis also.
Ex:
(int a) sop(a);
(a) sop(a);
A sop(a);
6) Similar to method body lambda expression body also can contain multiple statements. If more
than one statements present then we have to enclose inside within curly braces. If one
statement present then curly braces are optional.
7) Once we write lambda expression we can call that expression just like a method, for this
functional interfaces are required.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
6 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Functional Interfaces
If an interface contain only one abstract method, such type of interfaces are called functional
interfaces and the method is called functional method or single abstract method (SAM).
Ex:
1) Runnable It contains only run() method
2) Comparable It contains only compareTo() method
3) ActionListener It contains only actionPerformed()
4) Callable It contains only call() method
Inside functional interface in addition to single Abstract method (SAM) we write any number of
default and static methods.
Ex:
1) interface Interf {
2) public abstract void m1();
3) default void m2() {
4) System.out.println (“hello”);
5) }
6) }
In Java 8, Sun Micro System introduced @Functional Interface annotation to specify that the
interface is Functional Interface.
Ex:
@Functional Interface
Interface Interf { This code compiles without any compilation errors.
public void m1();
}
Inside Functional Interface we can take only one abstract method, if we take more than one
abstract method then compiler raise an error message that is called we will get compilation error.
Ex:
@Functional Interface {
public void m1(); This code gives compilation error.
public void m2();
}
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
7 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Inside Functional Interface we have to take exactly only one abstract method.If we are not
declaring that abstract method then compiler gives an error message.
Ex:
@Functional Interface {
interface Interface { compilation error
}
Ex:
1) @Functional Interface
2) interface A {
3) public void methodOne();
4) }
5) @Functional Interface
6) Interface B extends A {
7) }
In the child interface we can define exactly same parent interface abstract method.
Ex:
1) @Functional Interface
2) interface A {
3) public void methodOne();
4) }
5) @Functional Interface
6) interface B extends A { No Compile Time Error
7) public void methodOne();
8) }
In the child interface we can’t define any new abstract methods otherwise child interface won’t be
Functional Interface and if we are trying to use @Functional Interface annotation then compiler
gives an error message.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
8 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
1) @Functional Interface {
2) interface A {
3) public void methodOne();
4) }
Compiletime Error
5) @Functional Interface
6) interface B extends A {
7) public void methodTwo();
8) }
Ex:
@Functional Interface
interface A {
No compile time error
public void methodOne();
}
interface B extends A {
public void methodTwo(); This’s Normal interface so that code compiles without
error
}
In the above example in both parent & child interface we can write any number of default
methods and there are no restrictions. Restrictions are applicable only for abstract methods.
1) interface Interf {
2) public void methodOne() {}
3) public class Demo implements Interface {
4) public void methodOne() {
5) System.out.println(“method one execution”);
6) }
7) public class Test {
8) public static void main(String[] args) {
9) Interfi = new Demo();
10) i.methodOne();
11) }
12) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
9 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Above code With Lambda expression
1) interface Interf {
2) public void methodOne() {}
3) class Test {
4) public static void main(String[] args) {
5) Interfi = () System.out.println(“MethodOne Execution”);
6) i.methodOne();
7) }
8) }
1) interface Interf {
2) public void sum(inta,int b);
3) }
4) class Demo implements Interf {
5) public void sum(inta,int b) {
6) System.out.println(“The sum:” +(a+b));
7) }
8) }
9) public class Test {
10) public static void main(String[] args) {
11) Interfi = new Demo();
12) i.sum(20,5);
13) }
14) }
1) interface Interf {
2) public void sum(inta, int b);
3) }
4) class Test {
5) public static void main(String[] args) {
6) Interfi = (a,b) System.out.println(“The Sum:” +(a+b));
7) i.sum(5,10);
8) }
9) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
10 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Without Lambda Expressions
1) interface Interf {
2) publicint square(int x);
3) }
4) class Demo implements Interf {
5) public int square(int x) {
6) return x*x; OR (int x) x*x
7) }
8) }
9) class Test {
10) public static void main(String[] args) {
11) Interfi = new Demo();
12) System.out.println(“The Square of 7 is: “ +i.square(7));
13) }
14) }
1) interface Interf {
2) public int square(int x);
3) }
4) class Test {
5) public static void main(String[] args) {
6) Interfi = x x*x;
7) System.out.println(“The Square of 5 is:”+i.square(5));
8) }
9) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
11 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
17) }
1) class ThreadDemo {
2) public static void main(String[] args) {
3) Runnable r = () {
4) for(int i=0; i<10; i++) {
5) System.out.println(“Child Thread”);
6) }
7) };
8) Thread t = new Thread(r);
9) t.start();
10) for(i=0; i<10; i++) {
11) System.out.println(“Main Thread”);
12) }
13) }
14) }
1) class Test {
2) public static void main(String[] args) {
3) Thread t = new Thread(new Runnable() {
4) public void run() {
5) for(int i=0; i<10; i++) {
6) System.out.println("Child Thread");
7) }
8) }
9) });
10) t.start();
11) for(int i=0; i<10; i++)
12) System.out.println("Main thread");
13) }
14) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
12 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
With Lambda expression
1) class Test {
2) public static void main(String[] args) {
3) Thread t = new Thread(() {
4) for(int i=0; i<10; i++) {
5) System.out.println("Child Thread");
6) }
7) });
8) t.start();
9) for(int i=0; i<10; i++) {
10) System.out.println("Main Thread");
11) }
12) }
13) }
☀ We can reduce length of the code so that readability of the code will be improved.
☀ We can resolve complexity of anonymous inner classes.
☀ We can provide Lambda expression in the place of object.
☀ We can pass lambda expression as argument to methods.
Note:
☀ Anonymous inner class can extend concrete class, can extend abstract class, can implement
interface with any number of methods but
☀ Lambda expression can implement an interface with only single abstract method (Functional
Interface).
☀ Hence if anonymous inner class implements Functional Interface in that particular case only
we can replace with lambda expressions. Hence wherever anonymous inner class concept is
there, it may not possible to replace with Lambda expressions.
☀ Anonymous inner class! = Lambda Expression
Ex:
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
13 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
☀ Within lambda expression ‘this” keyword represents current outer class object reference (that
is current enclosing class reference in which we declare lambda expression)
Ex:
1) interface Interf {
2) public void m1();
3) }
4) class Test {
5) int x = 777;
6) public void m2() {
7) Interfi = () {
8) int x = 888;
9) System.out.println(x); 888
10) System.out.println(this.x); 777
11) };
12) i.m1();
13) }
14) public static void main(String[] args) {
15) Test t = new Test();
16) t.m2();
17) }
18) }
☀ From lambda expression we can access enclosing class variables and enclosing method
variables directly.
☀ The local variables referenced from lambda expression are implicitly final and hence we can’t
perform re-assignment for those local variables otherwise we get compile time error.
Ex:
1) interface Interf {
2) public void m1();
3) }
4) class Test {
5) int x = 10;
6) public void m2() {
7) int y = 20;
8) Interfi = () {
9) System.out.println(x); 10
10) System.out.println(y); 20
11) x = 888;
12) y = 999; //CE
13) };
14) i.m1();
15) y = 777;
16) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
14 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
17) public static void main(String[] args) {
18) Test t = new Test();
19) t.m2();
20) }
21) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
15 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Default Methods
☀ Until 1.7 version onwards inside interface we can take only public abstract methods and public
static final variables (every method present inside interface is always public and abstract
whether we are declaring or not).
☀ Every variable declared inside interface is always public static final whether we are declaring
or not.
☀ But from 1.8 version onwards in addition to these, we can declare default concrete methods
also inside interface, which are also known as defender methods.
☀ We can declare default method with the keyword “default” as follows
☀ Interface default methods are by-default available to all implementation classes. Based on
requirement implementation class can use these default methods directly or can override.
Ex:
1) interface Interf {
2) default void m1() {
3) System.out.println("Default Method");
4) }
5) }
6) class Test implements Interf {
7) public static void main(String[] args) {
8) Test t = new Test();
9) t.m1();
10) }
11) }
Note: We can’t override object class methods as default methods inside interface otherwise we
get compile time error.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
16 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Ex:
1) interface Interf {
2) default inthashCode() {
3) return 10;
4) }
5) }
CompileTimeError
Reason: Object class methods are by-default available to every Java class hence it’s not required
to bring through default methods.
1) Eg 1:
2) interface Left {
3) default void m1() {
4) System.out.println("Left Default Method");
5) }
6) }
7)
8) Eg 2:
9) interface Right {
10) default void m1() {
11) System.out.println("Right Default Method");
12) }
13) }
14)
15) Eg 3:
16) class Test implements Left, Right {}
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
17 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
How to override default method in the implementation class?
In the implementation class we can provide complete new implementation or we can call any
interface method as follows.
interfacename.super.m1();
Ex:
Ex:
1) interface Interf {
2) public static void sum(int a, int b) {
3) System.out.println("The Sum:"+(a+b));
4) }
5) }
6) class Test implements Interf {
7) public static void main(String[] args) {
8) Test t = new Test();
9) t.sum(10, 20); //CE
10) Test.sum(10, 20); //CE
11) Interf.sum(10, 20);
12) }
13) }
☀ As interface static methods by default not available to the implementation class, overriding
concept is not applicable.
☀ Based on our requirement we can define exactly same method in the implementation class,
it’s valid but not overriding.
Ex:1
1) interface Interf {
2) public static void m1() {}
3) }
4) class Test implements Interf {
5) public static void m1() {}
6) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
19 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Ex:2
1) interface Interf {
2) public static void m1() {}
3) }
4) class Test implements Interf {
5) public void m1() {}
6) }
Ex3:
1) class P {
2) private void m1() {}
3) }
4) class C extends P {
5) public void m1() {}
6) }
From 1.8 version onwards we can write main() method inside interface and hence we can run
interface directly from the command prompt.
Ex:
1) interface Interf {
2) public static void main(String[] args) {
3) System.out.println("Interface Main Method");
4) }
5) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
20 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Predicates
A predicate is a function with a single argument and returns boolean value.
To implement predicate functions in Java, Oracle people introduced Predicate interface in 1.8
version (i.e.,Predicate<T>).
Predicate interface present in Java.util.function package.
It’s a functional interface and it contains only one method i.e., test()
Ex:
interface Predicate<T> {
public boolean test(T t);
}
Ex:1 Write a predicate to check whether the given integer is greater than 10 or not.
Ex:
public boolean test(Integer I) {
if (I >10) {
return true;
}
else {
return false;
}
}
(Integer I) {
if(I > 10)
return true;
else
return false;
}
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
21 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
I (I>10);
1) import Java.util.function;
2) class Test {
3) public static void main(String[] args) {
4) predicate<Integer> p = I (i>10);
5) System.out.println(p.test(100));
6) System.out.println(p.test(7));
7) System.out.println(p.test(true)); //CE
8) }
9) }
# 1 Write a predicate to check the length of given string is greater than 3 or not.
Predicate<String> p = s (s.length() > 3);
System.out.println (p.test(“rvkb”)); true
System.out.println (p.test(“rk”)); false
#-2 write a predicate to check whether the given collection is empty or not.
Predicate<collection> p = c c.isEmpty();
Predicate joining
It’s possible to join predicates into a single predicate by using the following methods.
and()
or()
negate()
these are exactly same as logical AND ,OR complement operators
Ex:
1) import Java.util.function.*;
2) class test {
3) public static void main(string[] args) {
4) int[] x = {0, 5, 10, 15, 20, 25, 30};
5) predicate<integer> p1 = i->i>10;
6) predicate<integer> p2=i -> i%2==0;
7) System.out.println("The Numbers Greater Than 10:");
8) m1(p1, x);
9) System.out.println("The Even Numbers Are:");
10) m1(p2, x);
11) System.out.println("The Numbers Not Greater Than 10:");
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
22 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
12) m1(p1.negate(), x);
13) System.out.println("The Numbers Greater Than 10 And Even Are:†);
14) m1(p1.and(p2), x);
15) System.out.println("The Numbers Greater Than 10 OR Even:†);
16) m1(p1.or(p2), x);
17) }
18) public static void m1(predicate<integer>p, int[] x) {
19) for(int x1:x) {
20) if(p.test(x1))
21) System.out.println(x1);
22) }
23) }
24) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
23 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Functions
Functions are exactly same as predicates except that functions can return any type of result
but function should (can) return only one value and that value can be any type as per our
requirement.
To implement functions oracle people introduced Function interface in 1.8version.
Function interface present in Java.util.function package.
Functional interface contains only one method i.e., apply()
interface function(T,R) {
public R apply(T t);
}
1) import Java.util.function.*;
2) class Test {
3) public static void main(String[] args) {
4) Function<String, Integer> f = s ->s.length();
5) System.out.println(f.apply("Durga"));
6) System.out.println(f.apply("Soft"));
7) }
8) }
Note: Function is a functional interface and hence it can refer lambda expression.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
24 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Differences between predicate and function
Predicate Function
To implement conditional checks To perform certain operation And to
We should go for predicate return some result we Should go for
function.
Predicate can take one type Function can take 2 type Parameters.
Parameter which represents First one represent Input argument
Input argument type. type and Second one represent return
Predicate<T> Type.
Function<T,R>
Predicate interface defines Function interface defines only one
only one method called test() Method called apply().
public boolean test(T t) public R apply(T t)
Predicate can return only Function can return any type of value
boolean value.
Note: Predicate is a boolean valued function and(), or(), negate() are default methods present
inside Predicate interface.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
25 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Method And Constructor References
by using :: (Double Colon) Operator
Functional Interface method can be mapped to our specified method by using :: (double colon)
operator. This is called method reference.
Our specified method can be either static method or instance method.
Functional Interface method and our specified method should have same argument types,
except this the remaining things like return type, methodname, modifiers etc are not required
to match.
Syntax
If our specified method is static method If the method is instance method
Classname::methodName Objref::methodName
Functional Interface can refer lambda expression and Functional Interface can also refer
method reference. Hence lambda expression can be replaced with method reference. Hence
method reference is alternative syntax to lambda expression.
1) class Test {
2) public static void main(String[] args) {
3) Runnable r = () {
4) for(int i=0; i<=10; i++) {
5)
System.out.println("Child Thread");
6) }
7) };
8) Thread t = new Thread(r);
9) t.start();
10) for(int i=0; i<=10; i++) {
11) System.out.println("Main Thread");
12) }
13) }
14) }
1) class Test {
2) public static void m1() {
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
26 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
3) for(int i=0; i<=10; i++) {
4) System.out.println("Child Thread");
5) }
6) }
7) public static void main(String[] args) {
8) Runnable r = Test:: m1;
9) Thread t = new Thread(r);
10) t.start();
11) for(int i=0; i<=10; i++) {
12) System.out.println("Main Thread");
13) }
14) }
In the above example Runnable interface run() method referring to Test class static method m1().
Method reference to Instance method:
Ex:
1) interface Interf {
2) public void m1(int i);
3) }
4) class Test {
5) public void m2(int i) {
6) System.out.println("From Method Reference:"+i);
7) }
8) public static void main(String[] args) {
9) Interf f = I ->sop("From Lambda Expression:"+i);
10) f.m1(10);
11) Test t = new Test();
12) Interf i1 = t::m2;
13) i1.m1(20);
14) }
15) }
In the above example functional interface method m1() referring to Test class instance method
m2().
The main advantage of method reference is we can use already existing code to implement
functional interfaces (code reusability).
Constructor References
We can use :: ( double colon )operator to refer constructors also
Ex:
Interf f = sample :: new;
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
27 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
functional interface f referring sample class constructor
Ex:
1) class Sample {
2) private String s;
3) Sample(String s) {
4) this.s = s;
5) System.out.println("Constructor Executed:"+s);
6) }
7) }
8) interface Interf {
9) public Sample get(String s);
10) }
11) class Test {
12) public static void main(String[] args) {
13) Interf f = s -> new Sample(s);
14) f.get("From Lambda Expression");
15) Interf f1 = Sample :: new;
16) f1.get("From Constructor Reference");
17) }
18) }
Note: In method and constructor references compulsory the argument types must be matched.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
28 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Streams
To process objects of the collection, in 1.8 version Streams concept introduced.
If we want to represent a group of individual objects as a single entity then We should go for
collection.
If we want to process a group of objects from the collection then we should go for streams.
We can create a stream object to the collection by using stream() method of Collection
interface. stream() method is a default method added to the Collection in 1.8 version.
Stream is an interface present in java.util.stream. Once we got the stream, by using that we
can process objects of that collection.
1.Configuration
2.Processing
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
29 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
1) Configuration:
We can configure either by using filter mechanism or by using map mechanism.
Filtering:
We can configure a filter to filter elements from the collection based on some boolean condition
by using filter()method of Stream interface.
Ex:
Stream s = c.stream();
Stream s1 = s.filter(i -> i%2==0);
Hence to filter elements of collection based on some Boolean condition we should go for filter()
method.
Mapping:
If we want to create a separate new object, for every object present in the collection based on our
requirement then we should go for map() method of Stream interface.
2) Processing
processing by collect() method
Processing by count()method
Processing by sorted()method
Processing by min() and max() methods
forEach() method
toArray() method
Stream.of()method
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
30 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Processing by collect() method
This method collects the elements from the stream and adding to the specified to the collection
indicated (specified) by argument.
1) import Java.util.*;
2) class Test {
3) public static void main(String[] args) {
4) ArrayList<Integer> l1 = new ArrayList<Integer>();
5) for(int i=0; i<=10; i++) {
6) l1.add(i);
7) }
8) System.out.println(l1);
9) ArrayList<Integer> l2 = new ArrayList<Integer>();
10) for(Integer i:l1) {
11) if(i%2 == 0)
12) l2.add(i);
13) }
14) System.out.println(l2);
15) }
16) }
1) import Java.util.*;
2) import Java.util.stream.*;
3) class Test {
4) public static void main(String[] args) {
5) ArrayList<Integer> l1 = new ArrayList<Integer>();
6) for(inti=0; i<=10; i++) {
7) l1.add(i);
8) }
9) System.out.println(l1);
10) List<Integer> l2 = l1.stream().filter(i -> i%2==0).collect(Collectors.toList());
11) System.out.println(l2);
12) }
13) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
31 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Ex: Program for map() and collect() Method
1) import Java.util.*;
2) import Java.util.stream.*;
3) class Test {
4) public static void main(String[] args) {
5) ArrayList<String> l = new ArrayList<String>();
6) l.add("rvk"); l.add("rk"); l.add("rkv"); l.add("rvki"); l.add("rvkir");
7) System.out.println(l);
8) List<String> l2 = l.Stream().map(s -
>s.toUpperCase()).collect(Collectors.toList());
9) System.out.println(l2);
10) }
11) }
II.Processing by count()method
This method returns number of elements present in the stream.
Ex:
long count = l.stream().filter(s ->s.length()==5).count();
sop(“The number of 5 length strings is:”+count);
III.Processing by sorted()method
If we sort the elements present inside stream then we should go for sorted() method.
the sorting can either default natural sorting order or customized sorting order specified by
comparator.
sorted()- default natural sorting order
sorted(Comparator c)-customized sorting order.
Ex:
List<String> l3=l.stream().sorted().collect(Collectors.toList());
sop(“according to default natural sorting order:”+l3);
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
32 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
IV.Processing by min() and max() methods
min(Comparator c)
returns minimum value according to specified comparator.
max(Comparator c)
returns maximum value according to specified comparator
Ex:
String min=l.stream().min((s1,s2) -> s1.compareTo(s2)).get();
sop(“minimum value is:”+min);
V.forEach() method
This method will not return anything.
This method will take lambda expression as argument and apply that lambda expression for each
element present in the stream.
Ex:
l.stream().forEach(s->sop(s));
l3.stream().forEach(System.out:: println);
Ex:
1) import Java.util.*;
2) import Java.util.stream.*;
3) class Test1 {
4) public static void main(String[] args) {
5) ArrayList<Integer> l1 = new ArrayaList<Integer>();
6) l1.add(0); l1.add(15); l1.add(10); l1.add(5); l1.add(30); l1.add(25); l1.add(20);
7) System.out.println(l1);
8) ArrayList<Integer> l2=l1.stream().map(i-> i+10).collect(Collectors.toList());
9) System.out.println(l2);
10) long count = l1.stream().filter(i->i%2==0).count();
11) System.out.println(count);
12) List<Integer> l3=l1.stream().sorted().collect(Collectors.toList());
13) System.out.println(l3);
14) Comparator<Integer> comp=(i1,i2)->i1.compareTo(i2);
15) List<Integer> l4=l1.stream().sorted(comp).collect(Collectors.toList());
16) System.out.println(l4);
17) Integer min=l1.stream().min(comp).get();
18) System.out.println(min);
19) Integer max=l1.stream().max(comp).get();
20) System.out.println(max);
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
33 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
21) l3.stream().forEach(i->sop(i));
22) l3.stream().forEach(System.out:: println);
23)
24) }
25) }
VI.toArray() method
We can use toArray() method to copy elements present in the stream into specified array
VII.Stream.of()method
We can also apply a stream for group of values and for arrays.
Ex:
Stream s=Stream.of(99,999,9999,99999);
s.forEach(System.out:: println);
Double[] d={10.0,10.1,10.2,10.3};
Stream s1=Stream.of(d);
s1.forEach(System.out :: println);
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
34 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Date and Time API: (Joda-Time API)
Until Java 1.7version the classes present in Java.util package to handle Date and Time (like Date,
Calendar, TimeZoneetc) are not up to the mark with respect to convenience and performance.
To overcome this problem in the 1.8version oracle people introduced Joda-Time API. This API
developed by joda.org and available in Java in the form of Java.time package.
1) import Java.time.*;
2) public class DateTime {
3) public static void main(String[] args) {
4) LocalDate date = LocalDate.now();
5) System.out.println(date);
6) LocalTime time=LocalTime.now();
7) System.out.println(time);
8) }
9) }
O/p:
2015-11-23
12:39:26:587
Once we get LocalDate object we can call the following methods on that object to retrieve
Day,month and year values separately.
Ex:
1) import Java.time.*;
2) class Test {
3) public static void main(String[] args) {
4) LocalDate date = LocalDate.now();
5) System.out.println(date);
6) int dd = date.getDayOfMonth();
7) int mm = date.getMonthValue();
8) int yy = date.getYear();
9) System.out.println(dd+"..."+mm+"..."+yy);
10) System.out.printf("\n%d-%d-%d",dd,mm,yy);
11) }
12) }
Once we get LocalTime object we can call the following methods on that object.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
35 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Ex:
1) importJava.time.*;
2) class Test {
3) public static void main(String[] args) {
4) LocalTime time = LocalTime.now();
5) int h = time.getHour();
6) int m = time.getMinute();
7) int s = time.getSecond();
8) int n = time.getNano();
9) System.out.printf("\n%d:%d:%d:%d",h,m,s,n);
10) }
11) }
If we want to represent both Date and Time then we should go for LocalDateTime object.
LocalDateTimedt = LocalDateTime.now();
System.out.println(dt);
O/p: 2015-11-23T12:57:24.531
We can represent a particular Date and Time by using LocalDateTime object as follows.
Ex:
LocalDateTime dt1 = LocalDateTime.of(1995,Month.APRIL,28,12,45);
sop(dt1);
Ex:
LocalDateTime dt1=LocalDateTime.of(1995,04,28,12,45);
Sop(dt1);
Sop(“After six months:”+dt.plusMonths(6));
Sop(“Before six months:”+dt.minusMonths(6));
To Represent Zone:
ZoneId object can be used to represent Zone.
Ex:
1) import Java.time.*;
2) class ProgramOne {
3) public static void main(String[] args) {
4) ZoneId zone = ZoneId.systemDefault();
5) System.out.println(zone);
6) }
7) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
36 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
We can create ZoneId for a particular zone as follows
Ex:
ZoneId la = ZoneId.of("America/Los_Angeles");
ZonedDateTimezt = ZonedDateTime.now(la);
System.out.println(zt);
Period Object:
Period object can be used to represent quantity of time
Ex:
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1989,06,15);
Period p = Period.between(birthday,today);
System.out.printf("age is %d year %d months %d
days",p.getYears(),p.getMonths(),p.getDays());
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
37 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Java 9
New Features
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
38 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Table of Contents
12) Private Methods in Interfaces …………………………………………………………………………… 40
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
39 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Private Methods in Interfaces
Need Of Default Methods inside interfaces:
Prior to Java 8, Every method present inside interface is always public and abstract whether we
are declaring or not.
1) interface Prior2Java8Interf
2) {
3) public void m1();
4) public void m2();
5) }
Assume this interface is implemented by 1000s of classes and each class provided implementation
for both methods.
1) interface Prior2Java8Interf
2) {
3) public void m1();
4) public void m2();
5) }
6) class Test1 implements Prior2Java8Interf
7) {
8) public void m1(){}
9) public void m2(){}
10) }
11) class Test2 implements Prior2Java8Interf
12) {
13) public void m1(){}
14) public void m2(){}
15) }
16) class Test3 implements Prior2Java8Interf
17) {
18) public void m1(){}
19) public void m2(){}
20) }
21) class Test1000 implements Prior2Java8Interf
22) {
23) public void m1(){}
24) public void m2(){}
25) }
It is valid because all implementation classes provided implementation for both m1() and m2().
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
40 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Assume our programming requirement is we have to extend the functionality of this interface by
adding a new method m3().
1) interface Prior2Java8Interf
2) {
3) public void m1();
4) public void m2();
5) public void m3();
6) }
If we add new method m3() to the interface then all the implementation classes will be effected
and won't be compiled,because every implementation class should implement all methods of
interface.
CE: Test1 is not abstract and does not override abstract method
m3() in PriorJava8Interf
Hence prior to java 8,it is impossible to extend the functionality of an existing interface without
effecting implementation classes. JDK 8 Engineers addresses this issue and provides solution in the
form of Default methods, which are also known as Defender methods or Virtual Extension
Methods.
1) interface Java8Interf
2) {
3) public void m1();
4) public void m2();
5) default void m3()
6) {
7) //"Default Implementation
8) }
9) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
41 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Hence the main advantage of Default Methods inside interfaces is, without effecting
implementation classes we can extend functionality of interface by adding new methods
(Backward compatibility).
Eg:
In the above code all log methods having some common code,which increases length of the code
and reduces readability.It creates maintenance problems also. In Java8 there is no solution for
this.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
42 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
How to declare private Methods inside interface:
JDK 9 Engineers addresses this issue and provided private methods inside interfaces. We can
seperate that common code into a private method and we can call that private method from every
default method which required that functionality.
1) interface Java9Interf
2) {
3) default void m1()
4) {
5) m3();
6) }
7) default void m2()
8) {
9) m3();
10) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
43 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
11) private void m3()
12) {
13) System.out.println("common functionality of methods m1 & m2");
14) }
15) }
16) class Test implements Java9Interf
17) {
18) public static void main(String[] args)
19) {
20) Test t = new Test();
21) t.m1();
22) t.m2();
23) //t.m3(); ==>CE
24) }
25) }
Output:
D:\java9durga>java Test
common functionality of methods m1 & m2
common functionality of methods m1 & m2
Inside Java 8 interaces, we can take public static methods also.If several static methods having
some common functionality, we can seperate that common functionality into a private static
method and we can call that private static method from public static methods where ever it is
required.
1) interface Java9Interf
2) {
3) public static void m1()
4) {
5) m3();
6) }
7) public static void m2()
8) {
9) m3();
10) }
11) private static void m3()
12) {
13) System.out.println("common functionality of methods m1 & m2");
14) }
15) }
16) class Test implements Java9Interf
17) {
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
44 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
18) public static void main(String[] args)
19) {
20) Java9Interf.m1();
21) Java9Interf.m2();
22) }
23) }
Output:
D:\durga_classes>java Test
common functionality of methods m1 & m2
common functionality of methods m1 & m2
Note: Interface static methods should be called by using interface name only even in
implementation classes also.
1. Code Reusability
2. We can expose only intended methods to the API clients (Implementation classes), because
interface private methods are not visible to the implementation classses.
Note:
1. private methods cannot be abstract and hence compulsory private methods should have the
body.
2. private method inside interface can be either static or non-static.
1) interface Prior2Java8Interface
2) {
3) public-static-final variables
4) public-abstract methods
5) }
2. In Java 8 ,we can declare default and public-static methods also inside interface.
1) interface Java8Interface
2) {
3) public-static-final variables
4) public-abstract methods
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
45 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
5) default methods with implementation
6) public static methods with implementation
7) }
3. In Java 9, We can declare private instance and private static methods also inside interface.
1) interface Java9Interface
2) {
3) public-static-final variables
4) public-abstract methods
5) default methods with implementation
6) public static methods with implementation
7) private instance methods with implementation
8) private static methods with implementation
9) }
Note: The main advantage of private methods inside interface is Code Reusablility without
effecting implemenation classes.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
46 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Try with Resources Enahancements
Need of Try with Resources:
Until 1.6 version it is highly recommended to write finally block to close all resources which are
open as part of try block.
1) BufferedReader br=null;
2) try
3) {
4) br=new BufferedReader(new FileReader("abc.txt"));
5) //use br based on our requirements
6) }
7) catch(IOException e)
8) {
9) // handling code
10) }
11) finally
12) {
13) if(br != null)
14) br.close();
15) }
To overcome these problems Sun People introduced "try with resources" in 1.7 version.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
47 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
4) }
5) catch(IOException e)
6) {
7) // handling code
8) }
Conclusions:
1. We can declare any number of resources but all these resources should be separated with ;
(semicolon)
1) try(R1 ; R2 ; R3)
2) {
3) -------------
4) }
2. All resources should be AutoCloseable resources. A resource is said to be auto closable if and
only if the corresponding class implements the java.lang.AutoCloseable interface either directly or
indirectly.
All database related, network related and file io related resources already implemented
AutoCloseable interface. Being a programmer we should aware this point and we are not required
to do anything extra.
3. AutoCloseable interface introduced in Java 1.7 Version and it contains only one method: close()
4. All resource reference variables should be final or effectively final and hence we can't perform
reassignment within the try block.
5. Untill 1.6 version try should be followed by either catch or finally but in 1.7 version we can take
only try with resource without catch or finally
1) try(R)
2) {
3) //valid
4) }
6. The main advantage of "try with resources" is finally block will become dummy because we are
not required to close resources of explicitly.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
48 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Problems with JDK 7 Try with Resources:
1. The resource reference variables which are created outside of try block cannot be used directly
in try with resources.
We should create the resource in try block primary list or we should declare with new reference
variable in try block. i.e. Resource reference variable should be local to try block.
But from JDK 9 onwards we can use the resource reference variables which are created outside of
try block directly in try block resources list. i.e. The resource reference variables need not be local
to try block.
But make sure resource(br) should be either final or effectively final. Effectively final means we
should not perform reassignment.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
49 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
1) MyResource r1 = new MyResource();
2) MyResource r2 = new MyResource();
3) MyResource r3 = new MyResource();
4) try(r1,r2,r3)
5) {
6) }
Demo Program:
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
50 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
40) catch (Exception e)
41) {
42) System.out.println("Handling:"+e);
43) }
44) }
45) }
46) public static void JDK7()
47) {
48) try(MyResource r=new MyResource())
49) {
50) r.doProcess();
51) }
52) catch(Exception e)
53) {
54) System.out.println("Handling:"+e);
55) }
56) }
57) public static void JDK9()
58) {
59) MyResource r= new MyResource();
60) try(r)
61) {
62) r.doProcess();
63) }
64) catch(Exception e)
65) {
66) System.out.println("Handling:"+e);
67) }
68) }
69) public static void multipleJDK9()
70) {
71) MyResource r1= new MyResource();
72) MyResource r2= new MyResource();
73) MyResource r3= new MyResource();
74) MyResource r4= new MyResource();
75) try(r1;r2;r3;r4)
76) {
77) r1.doProcess();
78) r2.doProcess();
79) r3.doProcess();
80) r4.doProcess();
81) }
82) catch(Exception e)
83) {
84) System.out.println("Handling:"+e);
85) }
86) }
87) public static void main(String[] args)
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
51 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
88) {
89) System.out.println("Program Execution With PreJDK7");
90) preJDK7();
91)
92) System.out.println("Program Execution With JDK7");
93) JDK7();
94)
95) System.out.println("Program Execution With JDK9");
96) JDK9();
97) System.out.println("Program Execution Multiple Resources With JDK9");
98) multipleJDK9();
99) }
100) }
Output:
Program Execution With PreJDK7
Resource Creation...
Resource Processing...
Resource Closing...
Program Execution With JDK7
Resource Creation...
Resource Processing...
Resource Closing...
Program Execution With JDK9
Resource Creation...
Resource Processing...
Resource Closing...
Program Execution Multiple Resources With JDK9
Resource Creation...
Resource Creation...
Resource Creation...
Resource Creation...
Resource Processing...
Resource Processing...
Resource Processing...
Resource Processing...
Resource Closing...
Resource Closing...
Resource Closing...
Resource Closing...
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
52 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Diamond Operator Enhancements
This enhancement is as the part of Milling Project Coin (JEP 213).
Before understanding this enhancement, we should aware Generics concept, which has been
introduced in java 1.5 version.
Case 1: Type-Safety
Arrays are always type safe. i.e we can give the guarantee for the type of elements present inside
array. For example if our programming requirement is to hold String type of objects, it is
recommended to use String array. For the string array we can add only string type of objects. By
mistake if we are trying to add any other type we will get compile time error.
Eg:
String[] can contains only String type of elements. Hence, we can always give guarantee for the
type of elements present inside array. Due to this arrays are safe to use with respect to type.
Hence arrays are type safe.
But collections are not type safe that is we can't give any guarantee for the type of elements
present inside collection. For example if our programming requirement is to hold only string type
of objects, and if we choose ArrayList, by mistake if we are trying to add any other type we won't
get any compile time error but the program may fail at runtime.
Hence we can't give any guarantee for the type of elements present inside collections. Due to this
collections are not safe to use with respect to type, i.e collections are not Type-Safe.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
53 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Case 2: Type-Casting
In the case of array at the time of retrieval it is not required to perform any type casting.
But in the case of collection at the time of retrieval compulsory we should perform type casting
otherwise we will get compile time error.
Eg:
For this ArrayList we can add only string type of objects. By mistake if we are trying to add any
other type then we will get compile time error.
1) l.add("Durga");//valid
2) l.add("Ravi");//valid
3) l.add(new Integer(10));//error: no suitable method found for add(Integer)
At the time of retrieval it is not required to perform any type casting we can assign elements
directly to string type variables.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
54 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
String name1 = l.get(0);//valid and Type Casting is not required.
Prior to Java 7, Programmer compulsory should explicitly include the Type of generic class in the
Type Parameter of the constructor.
Whenever we are using Diamond Operator, then the compiler will consider the type automatically
based on context, Which is also known as Type inference. We are not required to specify Type
Parameter of the Constructor explicitly.
Hence the main advantage of Diamond Operator is we are not required to speicfy the type
parameter in the constructor explicitly,length of the code will be reduced and readability will be
improved.
Eg 2:
List<Map<String,Integer>> l = new ArrayList<Map<String,Integer>>();
But until Java 8 version we cannot apply diamond operator for Anonymous Generic classes. But in
Java 9, we can use.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
55 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Usage of Diamond Operator for Anonymous Classes:
In JDK 9, Usage of Diamond Operator extended to Anonymous classes also.
Anonymous class:
Sometimes we can declare classes without having the name, such type of nameless classes are
called Anonymous Classes.
Eg 1:
We are creating a child class that extends Thread class without name(Anonymous class) and we
are creating object for that child class.
Eg 2:
We are creating an implementation class for Runnable interface without name(Anonymous class)
and we are creating object for that implementation class.
Eg 3:
We are creating a child class that extends ArrayList class without name(Anonymous class) and we
are creating object for that child class.
From JDK 9 onwards we can use Diamond Operator for Anonymous Classes also.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
56 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Demo Program - 1: To demonstrate usage of diamond operator for Anonymous Class
1) class MyGenClass<T>
2) {
3) T obj;
4) public MyGenClass(T obj)
5) {
6) this.obj = obj;
7) }
8)
9) public T getObj()
10) {
11) return obj;
12) }
13) public void process()
14) {
15) System.out.println("Processing obj...");
16) }
17) }
18) public class Test
19) {
20) public static void main(String[] args)
21) {
22) MyGenClass<String> c1 = new MyGenClass<String>("Durga")
23) {
24) public void process()
25) {
26) System.out.println("Processing... " + getObj());
27) }
28) };
29) c1.process();
30)
31) MyGenClass<String> c2 = new MyGenClass<>("Pavan")
32) {
33) public void process()
34) {
35) System.out.println("Processing... " + getObj());
36) }
37) };
38) c2.process();
39) }
40) }
Output:
Processing... Durga
Processing... Pavan
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
57 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
If we compile the above program according to Java 1.8 version,then we will get compile time error
D:\durga_classes>javac -source 1.8 Test.java
error: cannot infer type arguments for MyGenClass<T>
MyGenClass<String> c2 = new MyGenClass<>("Pavan")
^
reason: cannot use '<>' with anonymous inner classes in -source 1.8
(use -source 9 or higher to enable '<>' with anonymous inner classes)
1) import java.util.Iterator;
2) import java.util.NoSuchElementException;
3) public class DiamondOperatorDemo
4) {
5) public static void main(String[] args)
6) {
7) String[] animals = { "Dog", "Cat", "Rat", "Tiger","Elephant" };
8) Iterator<String> iter = new Iterator<>()
9) {
10) int i = 0;
11) public boolean hasNext()
12) {
13) return i < animals.length;
14) }
15) public String next()
16) {
17) if (!hasNext())
18) throw new NoSuchElementException();
19) return animals[i++];
20) }
21) };
22) while (iter.hasNext())
23) {
24) System.out.println(iter.next());
25) }
26) }
27) }
Output:
Dog
Cat
Rat
Tiger
Elephant
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
58 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Note - 1:
Note - 2:
Be Ready for Partial Diamond Operator in the next versions of Java, as the part of Project
"Amber". Open JDK people already working on this.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
59 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
SafeVarargs Annotation Enhancements
This SafeVarargs Annotation was introduced in Java 7.
Prior to Java 9, we can use this annotation for final methods, static methods and constructors.
But from Java 9 onwards we can use for private methods also.
To understand the importance of this annotation, first we should aware var-arg methods and heap
pollution problem.
But from 1.5 version onwards, we can declare a method with variable number of arguments, such
type of methods are called var-arg methods.
Output
var-arg method
var-arg method
var-arg method
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
60 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
8) total=total+x1;
9) }
10) System.out.println("The Sum:"+ total);
11) }
12) public static void main(String[] args)
13) {
14) sum();
15) sum(10);
16) sum(10,20,30);
17) }
18) }
Output
The Sum:0
The Sum:10
The Sum:60
1) import java.util.*;
2) public class Test
3) {
4) public static void main(String[] args)
5) {
6) List<String> l1= Arrays.asList("A","B");
7) List<String> l2= Arrays.asList("C","D");
8) m1(l1,l2);
9) }
10) public static void m1(List<String>... l)//argument will become List<String>[]
11) {
12) Object[] a = l;// we can assign List[] to Object[]
13) a[0]=Arrays.asList(10,20);
14) String name=(String)l[0].get(0);//String type pointing to Integer type
15) System.out.println(name);
16) }
17) }
Compilation:
javac Test.java
Execution:
java Test
RE: java.lang.ClassCastException: java.base/java.lang.Integer cannot be cast to
java.base/java.lang.String
In the above program at runtime, String type variable name is trying to point to Integer type,which
causes Heap Pollution and results ClassCastException.
1) import java.util.*;
2) public class Test
3) {
4) public static void main(String[] args)
5) {
6) List<String> l1= Arrays.asList("A","B");
7) List<String> l2= Arrays.asList("C","D");
8) m1(l1,l2);
9) }
10) @SafeVarargs
11) public static void m1(List<String>... l)
12) {
13) for(List<String> l1: l)
14) {
15) System.out.println(l1);
16) }
17) }
18) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
62 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Output:
[A, B]
[C, D]
In the program, inside m1() method we are not performing any reassignments. Hence there is no
chance of Heap Pollution Problem. Hence we can suppress Compiler generated warnings with
@SafeVarargs annotation.
Note: At compile time observe the difference with and without SafeVarargs Annotation.
1) import java.util.*;
2) public class Test
3) {
4) @SafeVarargs //valid
5) public Test(List<String>... l)
6) {
7) }
8) @SafeVarargs //valid
9) public static void m1(List<String>... l)
10) {
11) }
12) @SafeVarargs //valid
13) public final void m2(List<String>... l)
14) {
15) }
16) @SafeVarargs //valid in Java 9 but not in Java 8
17) private void m3(List<String>... l) {
18) }
19) }
FAQs:
Q1. For which purpose we can use @SafeVarargs annotation?
Q2. What is Heap Pollution?
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
63 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Factory Methods for creating unmodifiable Collections
List: An indexed Collection of elements where duplicates are allowed and insertion order is
preserved.
Set: An unordered Collection of elements where duplicates are not allowed and insertion order is
not preserved.
Map: A Map is a collection of key-value pairs and each key-value pair is called Entry.Entry is an
inner interface present inside Map interface.Duplicate keys are not allowed,but values can be
duplicated.
As the part of programming requirement, it is very common to use Immutable Collection objects
to improve Memory utilization and performance.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
64 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
This way of creating unmodifiable Collections is verbose and not convenient.It increases length of
the code and reduces readability.
JDK Engineers addresses this problem and introduced several factory methods for creating
unmodifiable collections.
Upto 10 elements the matched method will be executed and for more than 10 elements internally
var-arg method will be called.JDK Enginerrs identified List of upto 10 elements is the common
requirement and hence they provided the corresponding methods. For remaining cases var-arg
method will be executed, which is very costly. These many methods just to improve performance.
Note:
1. While using these factory methods if any element is null then we will get NullPointerException.
2. After creating the List object,if we are trying to change the content(add|remove|replace
elements)then we will get UnsupportedOperationException because List is
immutable(unmodifiable).
List<String> fruits=List.of("Apple","Banana","Mango");
fruits.add("Orange"); //UnsupportedOperationException
fruits.remove(1); //UnsupportedOperationException
fruits.set(1,"Orange"); //UnsupportedOperationException
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
65 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Creation of unmodifiable Set(Immutable Set) with Java 9 Factory Methods:
Note:
1. While using these Factory Methods if we are trying to add duplicate elements then we will get
IllegalArgumentException, because Set won't allow duplicate elements
Set<Integer> numbers=Set.of(10,20,30,10);
RE: IllegalArgumentException: duplicate element: 10
2. While using these factory methods if any element is null then we will get NullPointerException.
3. After creating the Set object, if we are trying to change the content (add|remove elements)then
we will get UnsupportedOperationException because Set is immutable(unmodifiable).
Set<String> fruits=Set.of("Apple","Banana","Mango");
fruits.add("Orange"); //UnsupportedOperationException
fruits.remove("Apple"); //UnsupportedOperationException
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
66 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Creation of unmodifiable Map (Immutable Map) with Java 9
Factory Methods:
Java 9 Map interface defines of() and ofEntries() Factory methods for this purpose.
9. static <K,V> Map<K,V> of(K k1,V v1,K k2,V v2,K k3,V v3,K k4,V v4,K k5,V v5,K k6,V v6,K k7,V
v7,K k8,V v8)
10.static <K,V> Map<K,V> of(K k1,V v1,K k2,V v2,K k3,V v3,K k4,V v4,K k5,V v5,K k6,V v6,K k7,V
v7,K k8,V v8,K k9,V v9)
11.static <K,V> Map<K,V> of(K k1,V v1,K k2,V v2,K k3,V v3,K k4,V v4,K k5,V v5,K k6,V v6,K k7,V
v7,K k8,V v8,K k9,V v9,K k10,V v10)
12.static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)
Note:
Up to 10 entries,it is recommended to use of() methods and for more than 10 items we should use
ofEntries() method.
Map.Entry<String,String> e=Map.entry("A","Apple");
This Entry object is immutable and we cannot modify its content. If we are trying to change we will
get RE: UnsupportedOperationException
e.setValue("Durga"); UnsupportedOperationException
By using these Entry objects we can create unmodifiable Map object with Map.ofEntries() method.
Eg:
1) import java.util.*;
2) class Test
3) {
4) public static void main(String[] args)
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
67 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
5) {
6) Map.Entry<String,String> e1=Map.entry("A","Apple");
7) Map.Entry<String,String> e2=Map.entry("B","Banana");
8) Map.Entry<String,String> e3=Map.entry("C","Cat");
9) Map<String,String> m=Map.ofEntries(e1,e2,e3);
10) System.out.println(m);
11) }
12) }
Note:
1. While using these Factory Methods if we are trying to add duplicate keys then we will get
IllegalArgumentException: duplicate key.But values can be duplicated.
Map<String,String> map=Map.of("A","Apple","A","Banana","C","Cat","D","Dog");
RE: java.lang.IllegalArgumentException: duplicate key: A
2. While using these factory methods if any element is null (either key or value) then we will get
NullPointerException.
3. After creating the Map object, if we are trying to change the content(add|remove|replace
elements)then we will get UnsupportedOperationException because Map is
immutable(unmodifiable).
Eg:
Map<String,String> map=Map.ofEntries(entry("A","Apple"),entry("B","Banana"));
map.put("C","Cat"); UnsupportedOperationException
map.remove("A"); UnsupportedOperationException
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
68 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Serialization for unmodifiable Collections:
The immutable collection objects are serializable iff all elements are serializable.
In Brief form, the process of writing state of an object to a file is called Serialization and the
process of reading state of an object from the file is called Deserialization.
Serialization
e1 e2 e3
e1 e2 e3
l1
e1 e2 e3
Deserialization emp.ser
l2
1) import java.util.*;
2) import java.io.*;
3) class Employee implements Serializable
4) {
5) private int eno;
6) private String ename;
7) Employee(int eno,String ename)
8) {
9) this.eno=eno;
10) this.ename=ename;
11) }
12) public String toString()
13) {
14) return String.format("%d=%s",eno,ename);
15) }
16) }
17) class Test
18) {
19) public static void main(String[] args) throws Exception
20) {
21) Employee e1= new Employee(100,"Sunny");
22) Employee e2= new Employee(200,"Bunny");
23) Employee e3= new Employee(300,"Chinny");
24) List<Employee> l1=List.of(e1,e2,e3);
25) System.out.println(l1);
26)
27) System.out.println("Serialization of List Object...");
28) FileOutputStream fos=new FileOutputStream("emp.ser");
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
69 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
29) ObjectOutputStream oos=new ObjectOutputStream(fos);
30) oos.writeObject(l1);
31)
32) System.out.println("Deserialization of List Object...");
33) FileInputStream fis=new FileInputStream("emp.ser");
34) ObjectInputStream ois=new ObjectInputStream(fis);
35) List<Employee> l2=(List<Employee>)ois.readObject();
36) System.out.println(l2);
37) //l2.add(new Employee(400,"Vinnny"));//UnsupportedOperationException
38) }
39) }
Output:
D:\durga_classes>java Test
[100=Sunny, 200=Bunny, 300=Chinny]
Serialization of List Object...
Deserialization of List Object...
[100=Sunny, 200=Bunny, 300=Chinny]
After deserialization also we cannot modify the content, otherwise we will get
UnsupportedOperationException.
Note: The Factroy Methods introduced in Java 9 are not to create general collections and these
are meant for creating immutable collections.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
70 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Stream API Enhancements
Streams concept has been introduced in Java 1.8 version.
The main objective of Streams concept is to process elements of Collection with Functional
Programming (Lambda Expressions).
Once we got the stream, by using that we can process objects of that collection.
For this we can use either filter() method or map() method.
We can use filter() method to filter elements from the collection based on some boolean
condition.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
71 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Demo Program:
1) import java.util.*;
2) import java.util.stream.*;
3) public class Test
4) {
5) public static void main(String[] args)
6) {
7) ArrayList<Integer> l1 = new ArrayList<Integer>();
8) for(int i =0; i <=10; i++)
9) {
10) l1.add(i);
11) }
12) System.out.println("Before Filtering:"+l1);
13) List<Integer> l2=l1.stream().filter(i->i%2==0).collect(Collectors.toList());
14) System.out.println("After Filtering:"+l2);
15) }
16) }
Output:
Before Filtering:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After Filtering:[0, 2, 4, 6, 8, 10]
Demo Program:
1) import java.util.*;
2) import java.util.stream.*;
3) public class Test
4) {
5) public static void main(String[] args) {
6) ArrayList<Integer> l1 = new ArrayList<Integer>();
7) for(int i =0; i <=10; i++)
8) {
9) l1.add(i);
10) }
11) System.out.println("Before using map() method:"+l1);
12) List<Integer> l2=l1.stream().map(i->i*i).collect(Collectors.toList());
13) System.out.println("After using map() method:"+l2);
14) }
15) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
72 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Output:
Before using map() method:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After using map() method:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Typical use is for the mapper function of flatMap to return Stream.empty() if it wants to send zero
values, or something like Stream.of(x, y, z) if it wants to return several values.
Demo Program:
1) import java.util.*;
2) import java.util.stream.*;
3) public class Test
4) {
5) public static void main(String[] args)
6) {
7) ArrayList<Integer> l1 = new ArrayList<Integer>();
8) for(int i =0; i <=10; i++)
9) {
10) l1.add(i);
11) }
12) System.out.println("Before using map() method:"+l1);
13) List<Integer> l2=l1.stream().flatMap(
14) i->{ if (i%2 !=0) return Stream.empty();
15) else return Stream.of(i);
16) }).collect(Collectors.toList());
17) System.out.println("After using flatMap() method:"+l2);
18)
19) List<Integer> l3=l1.stream().flatMap(
20) i->{ if (i%2 !=0) return Stream.empty();
21) else return Stream.of(i,i*i);
22) }).collect(Collectors.toList());
23) System.out.println("After using flatMap() method:"+l3);
24) }
25) }
Output:
D:\durga_classes>java Test
Before using map() method:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After using flatMap() method:[0, 2, 4, 6, 8, 10]
After using flatMap() method:[0, 0, 2, 4, 4, 16, 6, 36, 8, 64, 10, 100]
1. takeWhile()
2. dropWhile()
3. Stream.iterate()
4. Stream.ofNullable()
Note: takeWhile() and dropWhile() methods are default methods and iterate() and ofNullable()
are static methods of Stream interface.
1. takeWhile():
It is the default method present in Stream interface.
But, in the case of takeWhile() method, there is no guarantee that it will process every element of
the Stream. It will take elements from the Stream as long as predicate returns true. If predicate
returns false, at that point onwards remaining elements won't be processed, i.e rest of the Stream
is discarded.
Eg: Take elements until we will get even numbers. Once we got odd number then stop and ignore
rest of the stream.
Demo Program:
1) import java.util.*;
2) import java.util.stream.*;
3) public class Test
4) {
5) public static void main(String[] args)
6) {
7) ArrayList<Integer> l1 = new ArrayList<Integer>();
8) l1.add(2);
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
74 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
9) l1.add(4);
10) l1.add(1);
11) l1.add(3);
12) l1.add(6);
13) l1.add(5);
14) l1.add(8);
15) System.out.println("Initial List:"+l1);
16) List<Integer> l2=l1.stream().filter(i->i%2==0).collect(Collectors.toList());
17) System.out.println("After Filtering:"+l2);
18) List<Integer> l3=l1.stream().takeWhile(i->i%2==0).collect(Collectors.toList());
19) System.out.println("After takeWhile:"+l3);
20) }
21) }
Output:
Initial List:[2, 4, 1, 3, 6, 5, 8]
After Filtering:[2, 4, 6, 8]
After takeWhile:[2, 4]
Eg 2:
Stream.of("A","AA","BBB","CCC","CC","C").takeWhile(s-
>s.length()<=2).forEach(System.out::println);
Output:
A
AA
2. dropWhile()
It is the default method present in Stream interface.
Demo Program:
1) import java.util.*;
2) import java.util.stream.*;
3) public class Test
4) {
5) public static void main(String[] args)
6) {
7) ArrayList<Integer> l1 = new ArrayList<Integer>();
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
75 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
8) l1.add(2);
9) l1.add(4);
10) l1.add(1);
11) l1.add(3);
12) l1.add(6);
13) l1.add(5);
14) l1.add(8);
15) System.out.println("Initial List:"+l1);
16) List<Integer> l2=l1.stream().dropWhile(i->i%2==0).collect(Collectors.toList());
17) System.out.println("After dropWhile:"+l2);
18) }
19) }
Output:
Initial List:[2, 4, 1, 3, 6, 5, 8]
After dropWhile:[1, 3, 6, 5, 8]
Eg 2:
Stream.of("A","AA","BBB","CCC","CC","C").dropWhile(s-
>s.length()<=2).forEach(System.out::println);
Output:
BBB
CCC
CC
C
3. Stream.iterate():
It is the satic method present in Stream interface.
Eg: Stream.iterate(1,x->x+1).forEach(System.out::println);
Output:
1
2
3
...infinite times
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
76 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
How to limit the number of iterations:
For this we can use limit() method.
Eg: Stream.iterate(1,x->x+1).limit(5).forEach(System.out::println);
Output:
1
2
3
4
5
To prevent infinite loops, in Java 9, another version of iterate() method introduced, which is
nothing but 3-arg iterate() method.
for(int i =0;i<10;i++){}
Eg: Stream.iterate(1,x->x<5,x->x+1).forEach(System.out::println);
Output:
1
2
3
4
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
77 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
4. ofNullable():
public static Stream<T> ofNullable(T t)
This method will check whether the provided element is null or not. If it is not null, then this
method returns the Stream of that element. If it is null then this method returns empty stream.
Eg 1:
List l=Stream.ofNullable(100).collect(Collectors.toList());
System.out.println(l);
Output:[100]
Eg 2:
List l=Stream.ofNullable(null).collect(Collectors.toList());
System.out.println(l);
Output: []
Demo Program:
1) import java.util.*;
2) import java.util.stream.*;
3) import java.util.*;
4) import java.util.stream.*;
5) public class Test
6) {
7) public static void main(String[] args)
8) {
9) List<String> l=new ArrayList<String>();
10) l.add("A");
11) l.add("B");
12) l.add(null);
13) l.add("C");
14) l.add("D");
15) l.add(null);
16) System.out.println(l);
17)
18) List<String> l2= l.stream().filter(o->o!=null).collect(Collectors.toList());
19) System.out.println(l2);
20)
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
78 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
21) List<String> l3= l.stream()
22) .flatMap(o->Stream.ofNullable(o)).collect(Collectors.toList());
23) System.out.println(l3);
24) }
25) }
Output:
[A, B, null, C, D, null]
[A, B, C, D]
[A, B, C, D]
Demo Program:
1) import java.util.*;
2) import java.util.stream.*;
3) public class Test
4) {
5) public static void main(String[] args)
6) {
7) Map<String,String> m=new HashMap<>();
8) m.put("A","Apple");
9) m.put("B","Banana");
10) m.put("C",null);
11) m.put("D","Dog");
12) m.put("E",null);
13) List<String> l=m.entrySet().stream().map(e->e.getKey()).collect(Collectors.toList());
14) System.out.println(l);
15)
16) List<String> l2=m.entrySet().stream()
17) .flatMap(e->Stream.ofNullable(e.getValue())).collect(Collectors.toList());
18) System.out.println(l2);
19)
20) }
21) }
Output:
[A, B, C, D, E]
[Apple, Banana, Dog]
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
79 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
The Java Shell (RPEL)
JShell Agenda
1) Introduction to the JShell …………………………………………………………………………………….…. 81
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
80 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT 1: Introduction to the JShell
Jshell is also known as interactive console.
JShell is Java's own REPL Tool.
By using this tool we can execute Java code snippets and we can get immediate results.
For beginners it is very good to start programming in fun way.
By using this Jshell we can test and execute Java expressions, statements, methods, classes etc. It
is useful for testing small code snippets very quickly, which can be plugged into our main coding
based on our requirement.
Prior to Java 9 we cannot execute a single statement, expression, methods without full pledged
classes. But in Java 9 with JShell we can execute any small piece of code without having complete
class structure.
It is not new thing in Java. It is already there in other languages like Python, Swift, Lisp, Scala, Ruby
etc..
Python IDLE
Apple's Swift Programming Language PlayGround
Limitations of JShell:
1. JShell is not meant for Main Coding. We can use just to test small coding snippets, which can be
used in our Main Coding.
2. JShell is not replacement of Regular Java IDEs like Eclpise, NetBeans etc
3. It is not that much impressed feature. All other languages like Python, LISP, Scala, Ruby, Swift
etc are already having this REPL tools
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
81 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT-2: Getting Started with JShell
Starting and Stopping JShell:
Open the jshell from the command prompt in verbose mode
jshell -v
D:\durga_classes>jshell -v
| Welcome to JShell -- Version 9
| For an introduction type: /help intro
Note: Observe the difference b/w with -v and without -v (verbose mode)
D:\durga_classes>jshell -v
| Welcome to JShell -- Version 9
| For an introduction type: /help intro
Note: If any information displaying on the jshell starts with '|', it is the information to the
programmer from the jshell
jshell> 10+20
$1 ==> 30
| created scratch variable $1 : int
jshell> 20-30*6/2
$2 ==> -70
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
82 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
| created scratch variable $2 : int
jshell> System.out.println("DURGASOFT")
DURGASOFT
Here if we observe the output not starts with | because it is not information from the Jshell.
Note: Terminating semicolons are automatically added to the end of complete snippet by JShell if
not entered. .
jshell> Math.sqrt(4)
$4 ==> 2.0
| created scratch variable $4 : double
jshell> Math.max(10,20)
$5 ==> 20
| created scratch variable $5 : int
jshell> Math.random()
$6 ==> 0.6956946870985563
| created scratch variable $6 : double
jshell> Math.random()
$7 ==> 0.3657412865477785
| created scratch variable $7 : double
jshell> Math.random()
$8 ==> 0.8828801968574324
| created scratch variable $8 : double
Note: We are not required to import Java.lang package, because by default available.
Note: The following packages are bydefault available to the Jshell and we are not required to
import. We can check with /imports command
jshell> /imports
| import Java.io.*
| import Java.math.*
| import Java.net.*
| import Java.nio.file.*
| import Java.util.*
| import Java.util.concurrent.*
| import Java.util.function.*
| import Java.util.prefs.*
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
83 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
| import Java.util.regex.*
| import Java.util.stream.*
jshell> ArrayList<String> l=new ArrayList<String>();
l ==> []
jshell> l.add("Sunny");l.add("Bunny");l.add("Chinny");
$2 ==> true
$3 ==> true
$4 ==> true
jshell> l
l ==> [Sunny, Bunny, Chinny]
jshell> l.isEmpty()
$6 ==> false
jshell> l.get(2)
$7 ==> "Chinny"
jshell> l.get(10)
| Java.lang.IndexOutOfBoundsException thrown: Index 10 out-of-bounds for length 3
jshell> l.size()
$9 ==> 3
Note: Interlly jshell having Java compiler which is responsible to check syntax.If any violation we
will get Compile time error which is exactly same as normal compile time errors.
jshell> System.out.println(x+y)
| Error:
| cannot find symbol
| symbol: variable x
| System.out.println(x+y)
| ^
| Error:
| cannot find symbol
| symbol: variable y
| System.out.println(x+y)
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
84 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
jshell> Sytsem.out.println("Durga")
| Error:
| package Sytsem does not exist
| Sytsem.out.println("Durga")
| ^--------^
Note: In our program if there is any chance of getting checked exceptions compulsory we required
to handle either by try-catch or by throws keyword. Otherwise we will get Compile time error.
Eg:
1) import Java.io.*;
2) class Test
3) {
4) public static void main(String[] args)
5) {
6) PrintWriter pw=new PrintWriter("abc.txt");
7) pw.println("Hello");
8) }
9) }
D:\durga_classes>Javac Test.Java
Test.Java:6: error: unreported exception FileNotFoundException; must be caught or declared to be
thrown
PrintWriter pw=new PrintWriter("abc.txt");
But in the case of Jshell, jshell itself will takes care of these and we are not required to use try-
catch or throws. Thanks to Jshell.
Conclusions:
1. From the jshell we can execute any expression, any Java statement.
2. Most of the packages are not required to import to the Jshell because by default already
available to the jshell.
3. Internally jshell use Java compiler to check syntaxes
4. If we are not handling any checked exceptions we won’t get any compile time errors, because
jshell will takes care.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
85 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT - 3: Getting Help from the JShell
If You Cry For Help....JShell will provide everything.
JShell can provide complete information about available commands with full documentation, and
how to use each command and what are various options are available etc..
Agenda:
1) To know list of options allowed with jshell:
jshell>/help commandname
jshell>/command - tab
jshell> /list -
-all -history -start
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
86 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
1) To know list of options allowed with jshell
Type jshell --help from normal command prompt
D:\durga_classes>jshell --help
Usage: jshell <options> <load files>
where possible options include:
--class-path <path> Specify where to find user class files
--module-path <path> Specify where to find application modules
--add-modules <module>(,<module>)*
Specify modules to resolve, or all modules on the
module path if <module> is ALL-MODULE-PATHs
--startup <file> One run replacement for the start-up definitions
--no-startup Do not run the start-up definitions
--feedback <mode> Specify the initial feedback mode. The mode may be
predefined (silent, concise, normal, or verbose) or
previously user-defined
-q Quiet feedback. Same as: --feedback concise
-s Really quiet feedback. Same as: --feedback silent
-v Verbose feedback. Same as: --feedback verbose
-J<flag> Pass <flag> directly to the runtime system.
Use one -J for each runtime flag or flag argument
-R<flag> Pass <flag> to the remote runtime system.
Use one -R for each remote flag or flag argument
-C<flag> Pass <flag> to the compiler.
Use one -C for each compiler flag or flag argument
--version Print version information and exit
--show-version Print version information and continue
--help Print this synopsis of standard options and exit
--help-extra, -X Print help on non-standard options and exit
D:\durga_classes>jshell --version
jshell 9
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
87 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
3) To know introduction of jshell
jshell> /help intro
|
| intro
|
| The jshell tool allows you to execute Java code, getting immediate results.
| You can enter a Java definition (variable, method, class, etc), like: int x = 8
| or a Java expression, like: x + x
| or a Java statement or import.
| These little chunks of Java code are called 'snippets'.
|
| There are also jshell commands that allow you to understand and
| control what you are doing, like: /list
|
| For a list of commands: /help
jshell> /help
| Type a Java language expression, statement, or declaration.
| Or type one of the following commands:
| /list [<name or id>|-all|-start]
| list the source you have typed
| /edit <name or id>
| edit a source entry referenced by name or id
| /drop <name or id>
| delete a source entry referenced by name or id
| /save [-all|-history|-start] <file>
| Save snippet source to a file.
| /open <file>
| open a file as source input
| /vars [<name or id>|-all|-start]
| list the declared variables and their values
| /methods [<name or id>|-all|-start]
| list the declared methods and their signatures
| /types [<name or id>|-all|-start]
| list the declared types
| /imports
| list the imported items
| /exit
| exit jshell
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
88 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
| /env [-class-path <path>] [-module-path <path>] [-add-modules <modules>] ...
| view or change the evaluation context
| /reset [-class-path <path>] [-module-path <path>] [-add-modules <modules>]...
| reset jshell
| /reload [-restore] [-quiet] [-class-path <path>] [-module-path <path>]...
| reset and replay relevant history -- current or previous (-restore)
| /history
| history of what you have typed
| /help [<command>|<subject>]
| get information about jshell
| /set editor|start|feedback|mode|prompt|truncation|format ...
| set jshell configuration information
| /? [<command>|<subject>]
| get information about jshell
| /!
| re-run last snippet
| /<id>
| re-run snippet by id
| /-<n>
| re-run n-th previous snippet
|
| For more information type '/help' followed by the name of a
| command or a subject.
| For example '/help /list' or '/help intro'.
|
| Subjects:
|
| intro
| an introduction to the jshell tool
| shortcuts
| a description of keystrokes for snippet and command completion,
| information access, and automatic code generation
| context
| the evaluation context options for /env /reload and /reset
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
89 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
|
| /list -start
| List the automatically evaluated start-up snippets
|
| /list -all
| List all snippets including failed, overwritten, dropped, and start-up
|
| /list <name>
| List snippets with the specified name (preference for active snippets)
|
| /list <id>
| List the snippet with the specified snippet id
jshell> /
/! /? /drop /edit /env /exit /help
/history /imports /list /methods /open /reload /reset
/save /set /types /vars
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
90 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
If we press tab again then we will get one line synopsis for every command:
jshell> /
/!
re-run last snippet
/-<n>
re-run n-th previous snippet
/<id>
re-run snippet by id
/?
get information about jshell
/drop
delete a source entry referenced by name or id
/edit
edit a source entry referenced by name or id
/env
view or change the evaluation context
/exit
exit jshell
/help
get information about jshell
/history
history of what you have typed
/imports
list the imported items
/list
list the source you have typed
/methods
list the declared methods and their signatures
/open
open a file as source input
/reload
reset and replay relevant history -- current or previous (-restore)
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
91 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
/reset
reset jshell
/save
Save snippet source to a file.
/set
set jshell configuration information
/types
list the declared types
/vars
list the declared variables and their values
If we press tab again then we can see full documentation of command one by one:
jshell> /
/!
Reevaluate the most recently entered snippet.
jshell> /
/-<n>
Reevaluate the n-th most recently entered snippet.
jshell> /
/<id>
Reevaluate the snippet specified by the id.
jshell> /list -
-all -history -start
jshell> /list -
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
92 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
If we press tab again then we will get synopsis:
jshell> /list -
list the source you have typed
/list
List the currently active snippets of code that you typed or read with /open
/list -start
List the automatically evaluated start-up snippets
/list -all
List all snippets including failed, overwritten, dropped, and start-up
/list <name>
List snippets with the specified name (preference for active snippets)
/list <id>
List the snippet with the specified snippet id
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
93 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Conclusions:
1) To know list of options allowed with jshell
Type jshell --help from normal command prompt
jshell> /list -
-all -history -start
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
94 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT - 4: Understanding JShell Snippets
What are Coding Snippets?
Everything what allowed in Java is a snippet. It can be
Expression,Declaration,Statement,classe,interface,method,variable,import,...
We can use all these as snippets from jshell.
jshell> System.out.println("Hello")
Hello
jshell> 10+20
$3 ==> 30
| created scratch variable $3 : int
jshell> $3>x
$4 ==> true
| created scratch variable $4 : boolean
jshell> m1()
hello
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
95 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Note: We can use /list command to list out all snippets stored in the jshell memory with snippet
id.
jshell> /list
1 : System.out.println("Hello")
2 : int x=10;
3 : 10+20
4 : $3>x
5 : String s= "Durga";
6 : public void m1()
{
System.out.println("hello");
}
7 : m1()
The numbers 1,2,3 are snippet id. In the future we can access the snippet with id directly.
Note: There are some snippets which will be executed automatically at the time jshell star-
tup,and these are called start-up snippets. We can also add our own snippets as start-up snippets.
We can list out all start-up snippets with command: /list -start
s1 : import Java.io.*;
s2 : import Java.math.*;
s3 : import Java.net.*;
s4 : import Java.nio.file.*;
s5 : import Java.util.*;
s6 : import Java.util.concurrent.*;
s7 : import Java.util.function.*;
s8 : import Java.util.prefs.*;
s9 : import Java.util.regex.*;
s10 : import Java.util.stream.*;
s1 : import Java.io.*;
s2 : import Java.math.*;
s3 : import Java.net.*;
s4 : import Java.nio.file.*;
s5 : import Java.util.*;
s6 : import Java.util.concurrent.*;
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
96 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
s7 : import Java.util.function.*;
s8 : import Java.util.prefs.*;
s9 : import Java.util.regex.*;
s10 : import Java.util.stream.*;
1 : System.out.println("Hello")
2 : int x=10;
3 : 10+20
4 : $3>x
e1 : String s =10;
5 : String s= "Durga";
6 : public void m1()
{
System.out.println("hello");
}
7 : m1()
jshell> /list 1
1 : System.out.println("Hello")
jshell> /list 1 2
1 : System.out.println("Hello")
2 : int x=10;
jshell> /list 1 5
1 : System.out.println("Hello")
5 : String s= "Durga";
We can also access snippets directly by using name.The name can be either variable name,class
name ,method name etc
jshell> /list m1
jshell> /list x
2 : int x=10;
jshell> /list s
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
97 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
5 : String s= "Durga";
jshell> /3
10+20
$8 ==> 30
| created scratch variable $8 : int
jshell> /7
m1()
hello
jshell> /list
1 : System.out.println("Hello")
2 : int x=10;
3 : 10+20
4 : $3>x
5 : String s= "Durga";
6 : public void m1()
{
System.out.println("hello");
}
7 : m1()
8 : 10+20
9 : m1()
jshell> /drop $3
| dropped variable $3
jshell> /list
1 : System.out.println("Hello")
2 : int x=10;
4 : $3>x
5 : String s= "Durga";
6 : public void m1()
{
System.out.println("hello");
}
7 : m1()
8 : 10+20
9 : m1()
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
98 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
jshell> /4
$3>x
| Error:
| cannot find symbol
| symbol: variable $3
| $3>x
| ^^
Conclusions:
1. We can use /list command to list out all snippets stored in the jshell memory with snippet id.
jshell>/list
2. In the future we can access the snippet with id directly without retypinng whole snippet.
jshell>/list id
3. There are some snippets which will be executed automatically at the time jshell star-tup,and
these are called start-up snippets. We can list out all start-up snippets with command: /list -start
jshell> /list 1
7. We can access snippets directly by using name.The name can be either variable name,class
name ,method name etc
jshell> /list m1
jshell> /3
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
99 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT – 5: Editing and Navigating Code Snippets
We can list all our active snippets with /list command and we can list total history of our jshell
activities with /history command.
jshell> /list
1 : int x=10;
2 : String s="Durga";
3 : System.out.println("Hello");
4 : class Test{}
jshell> /history
int x=10;
String s="Durga";
System.out.println("Hello");
class Test{}
/list
/history
1. By using down arrow and up arrow we can navigate through history.While navigating we can
use left and right arrows to move character by character with in the snippet.
2. We can Ctrl+A to move to the beginning of the line and Ctrl+E to move to the end of the line.
3. We can use Alt+B to move backward by one word and Alt+F to move forward by one word.
4. We can use Delete key to delete the character at the cursor. We can us Backspace to delete
character before the cursor.
5. We can use Ctrl+K to delete the text from the cursor to the end of line.
6. We can use Alt+D to delete the text from the cursor to the end of the word.
7. Ctrl+W to delete the text from cursor to the previous white space.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
100 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
KEY ACTION
Up arrow Moves up one line, backward through history
Down arrow Moves down one line, forward through history
Left arrow Moves backward one character
Right arrow Moves forward one character
Ctrl+A Moves to the beginning of the line
Ctrl+E Moves to the end of the line
Alt+B Moves backward one word
Alt+F Moves forward one word
Delete Deletes the character at the cursor
Backspace Deletes the character before the cursor
Ctrl+K Deletes the text from the cursor to the end of the line
Alt+D Deletes the text from the cursor to the end of the word
Ctrl+W Deletes the text from the cursor to the previous white space.
Ctrl+Y Pastes the most recently deleted text into the line.
Ctrl+R Searches backward through history
Ctrl+S Searches forwards through history
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
101 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT – 6: Working with JShell Variables
After completing this JShell Variables session, we can answer the following:
1. Explicit variables
2. Implicit variables or Scratch variables
Explicit variables:
These variables created by programmer explicitly based on our programming requirement.
Eg:
The variables x and s provided explicitly by the programmer and hence these are explicit variables.
Implicit Variables:
Sometimes JShell itself creates variables implicitly to hold temporary values,such type of variables
are called Implicit variables.
Eg:
jshell> 10+20
$3 ==> 30
| created scratch variable $3 : int
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
102 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
jshell> 10<20
$4 ==> true
| created scratch variable $4 : boolean
The variables $3 and $4 are created by JShell and hence these are implicit variables.
jshell> $3+40
$5 ==> 70
| created scratch variable $5 : int
If we are trying to declare a variable with the same name which is already available then old
variable will be replaced with new variable.i.e in JShell, variable overriding is possible.
In JShell at a time only one variable is possible with the same name.i.e 2 variables with the same
name is not allowed.
While declaring variables compulsory the types must be matched,otherwise we will get compile
time error.
Note: By using /vars command we can list out type,name and value of all variables which are
created in JShell.
Instead of /vars we can also use /var,/va,/v
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
103 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
| List the type, name, and value of the current active jshell variables
|
| /vars <name>
| List jshell variables with the specified name (preference for active var
iables)
|
| /vars <id>
| List the jshell variable with the specified snippet id
|
| /vars -start
| List the automatically added start-up jshell variables
|
| /vars -all
| List all jshell variables including failed, overwritten, dropped, and st
art-up
jshell> /vars
| String s = "Durga"
| int $3 = 30
| boolean $4 = true
| String x = "DURGASOFT"
| String s1 = "Hello"
jshell> /drop $3
| dropped variable $3
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
104 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
jshell> /vars
| String s = "Durga"
| boolean $4 = true
| String x = "DURGASOFT"
| String s1 = "Hello"
jshell>List<String> heroes=List.of("Ameer","Sharukh","Salman");
heroes ==> [Ameer, Sharukh, Salman]
| created variable heroes : List<String>
jshell>List<String> heroines=List.of("Katrina","Kareena","Deepika");
heroines ==> [Katrina, Kareena, Deepika]
| created variable heroines : List<String>
jshell> /vars
| String s = "Durga"
| boolean $4 = true
| String x = "DURGASOFT"
| String s1 = "Hello"
| List<String> heroes = [Ameer, Sharukh, Salman]
| List<String> heroines = [Katrina, Kareena, Deepika]
| List<List<String>> l = [[Ameer, Sharukh, Salman], [Katrina,Kareena, Deepika]]
jshell> System.out.println("Hello");
Hello
jshell> System.out.printf("Hello:%s\n","Durga")
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
105 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Hello:Durga
$11 ==> Java.io.PrintStream@10bdf5e5
| created scratch variable $11 : PrintStream
jshell> $11.printf("Hello")
Hello$12 ==> Java.io.PrintStream@10bdf5e5
| created scratch variable $12 : PrintStream
jshell> /vars
| String s = "Durga"
| boolean $4 = true
| String x = "DURGASOFT"
| String s1 = "Hello"
| List<String> heroes = [Ameer, Sharukh, Salman]
| List<String> heroines = [Katrina, Kareena, Deepika]
| List<List<String>> l = [[Ameer, Sharukh, Salman],
[Katrina, Kareena, Deepika]]
| PrintStream $11 = Java.io.PrintStream@10bdf5e5
| PrintStream $12 = Java.io.PrintStream@10bdf5e5
FAQs:
1. What are various types of variables possible in jshell?
2. Is it possible to use scratch variable in our code?
3. Is it possible 2 variables with the same name in JShell?
4. If we are trying to declare a variable with the same name which is already available in JShell
then what will happen?
5. How to list out all active variables of jshell?
6. How to list out all active& in-active variables of jshell?
7. How to drop variables in the JShell?
8. What is the difference between print() and printf() methods?
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
106 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT – 7: Working with JShell Methods
In the JShell we can create our own methods and we can invoke these methods multiple times
based on our requirement.
Eg:
jshell> m1()
Hello
jshell> m2()
New Method
In the JShell there may be a chance of multiple methods with the same name but different
argument types, and such type of methods are called overloaded methods.Hence we can declare
oveloaded methods in the JShell.
jshell> /methods
| void m1()
| void m1(int)
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
107 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
| /methods
| List the name, parameter types, and return type of the current active jshell methods
|
| /methods <name>
| List jshell methods with the specified name (preference for active methods)
|
| /methods <id>
| List the jshell method with the specified snippet id
|
| /methods -start
| List the automatically added start-up jshell methods
|
| /methods -all
| List all snippets including failed, overwritten, dropped, and start-up
jshell> /methods
| void m1()
| void m2()
| void m1(int)
If we are trying to declare a method with same signature of already existing method in JShell,then
old method will be overridden with new method(eventhough return types are different).
i.e in JShell at a time only one method with same signature is possible.
jshell> /methods
| int m1(int)
Eg1: To print the number of occurrences of specified character in the given String
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
108 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
5) {
6) if(s.charAt(i)==ch)
7) {
8) count++;
9) }
10) }
11) System.out.println("The number of occurrences:"+count);
12) }
jshell> charCount("Jajaja",'j')
The number of occurrences:2
jshell> sum(10,20)
The Sum:30
jshell> sum(10,20,30,40)
The Sum:100
In JShell,inside method body we can use undeclared variables and methods.But until declaring all
dependent variables and methods,we cannot invoke that method.
jshell> m1()
| attempted to call method m1() which cannot be invoked until variable x is declared
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
109 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
jshell> int x=10
x ==> 10
| created variable x : int
| update modified method m1()
jshell> m1()
10
jshell> m1()
| attempted to call method m1() which cannot be invoked until method m2() is declared
jshell> m1()
Hello DURGASOFT
jshell> m2()
Hello DURGASOFT
We can drop methods by name with /drop command. If multiple methods with the same name
then we should drop by snippet id.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
110 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
jshell> /methods
| void m1()
| void m1(int)
| void m2()
| void m3()
jshell> /drop m3
| dropped method m3()
jshell> /methods
| void m1()
| void m1(int)
| void m2()
jshell> /drop m1
| The argument references more than one import, variable, method, or class.
| Use one of:
| /drop 1 : public void m1(){},
| /drop 2 : public void m1(int i){}
jshell> /methods
| void m1()
| void m1(int)
| void m2()
jshell> /list
jshell> /drop 2
| dropped method m1(int)
jshell> /methods
| void m1()
| void m2()
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
111 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
FAQs:
1. Is it possible to declare methods in the JShell?
2. Is it possible to declare multiple methods with the same name in JShell?
3. Is it possible to declare multiple methods with the same signature in JShell?
4. If we are trying to declare a method with the same name which is already there in the JShell,but
with different argument types then what will happen?
5.If we are trying to declare a method with the same signature which is already there in the
JShell,then what will happen?
6. Inside a method if we are trying to use a varaiable or method which is not yet declared then
what will happen?
7. How to drop methods in JShell?
8. If multiple methods with the same name then how to drop these methods?
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
112 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT – 8: Using An External Editor with JShell
It is very difficult to type lengthy code from JShell. To overcome this problem,JShell provide in-
built editor.
jshell> /edit
diagram(image) of inbuilt-editor
If we are not satisfied with JShell in-built editor ,then we can set our own editor to the JShell.For
this we have to use /set editor command.
Eg:
jshell> /edit
But this way of setting editor is temporary and it is applicable only for current session.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
113 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
How to set default editor once again:
We have to type the following command from the jshell
FAQs:
1. How to open default editor of JShell?
2. How to configure our own editor to the JShell?
3. How to configure Notepad as editor to the JShell?
4. How to make our customized editor as permanent editor in the JShell?
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
114 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT – 9: Using classes, interfaces and enum with JShell
In the JShell we can declare classes,interfaces,enums also.
We can use /types command to list out our created types like classes,interfaces and enums.
jshell> /types
| class Student
| interface Interf
| enum Colors
jshell> /edit
| created class Student
jshell> /types
| class Student
jshell> s.getName()
$3 ==> "Durga"
| created scratch variable $3 : String
jshell> s.getRollno()
$4 ==> 101
| created scratch variable $4 : int
jshell> /edit
| created interface Interf
| created enum Beer
jshell> Interf.m1()
interface static method
jshell> Beer.KF.getTaste()
$8 ==> "Sour"
| created scratch variable $8 : String
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
116 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT – 10: Loading and Saving Snippets in JShell
We can load and save snippets from the file.
Assume all our required snippets are available in mysnippets.jsh. This file can be with any
extension like .txt,But recommended to use .jsh.
mysnippets.jsh:
String s="Durga";
public void m1()
{
System.out.println("method defined in the file");
}
int x=10;
We can load all snippets of this file from the JShell with /open command as follows.
jshell> /list
jshell> /list
1 : String s="Durga";
2 : public void m1()
{
System.out.println("method defined in the file");
}
3 : int x=10;
Once we loaded snippets,we can use these loaded snippets based on our requirement.
jshell> m1()
method defined in the file
jshell> s
s ==> "Durga"
| value of s : String
jshell> x
x ==> 10
| value of x : int
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
117 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Saving JShell snippets to the file:
We can save JShell snippets to the file with /save command.
Note: If the specified file is not available then this save command itself will create that file.
jshell> /ex
| Goodbye
D:\>type active.jsh
int x=10;
x
System.out.println("Hello");
public void m1(){}
D:\>type start.jsh
import Java.io.*;
import Java.math.*;
import Java.net.*;
import Java.nio.file.*;
import Java.util.*;
import Java.util.concurrent.*;
import Java.util.function.*;
import Java.util.prefs.*;
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
118 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
import Java.util.regex.*;
import Java.util.stream.*;
Note: Bydefault,all files will be created in current working directory. If we want in some other
location then we have to use absolute path(Full Path).
Eg:
jshell> 10+20
$2 ==> 30
| created scratch variable $2 : int
jshell> System.out.println("Hello");
Hello
jshell> /list
1 : int x=10;
2 : 10+20
3 : System.out.println("Hello");
jshell> /exit
| Goodbye
D:\>jshell -v
| Welcome to JShell -- Version 9
| For an introduction type: /help intro
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
119 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
jshell> /list
1 : int x=10;
2 : 10+20
3 : System.out.println("Hello");
Eg:
jshell> /list
1 : int x=10;
2 : 10+20
3 : System.out.println("Hello");
jshell> /reset
| Resetting state.
jshell> /list
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
120 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT – 11: Using Jar Files in the JShell
It is very easy to use external jar files in the jshell. We can add Jar files to the JShell in two ways.
mysnippets.jsh:
1) import Java.sql.*;
2) public void getEmpInfo() throws Exception
3) {
4) Connection con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","
scott","tiger");
5) Statement st=con.createStatement();
6) ResultSet rs=st.executeQuery("select * from employees");
7) while(rs.next())
8) {
9) System.out.println(rs.getInt(1)+".."+rs.getString(2)+".."+rs.getDouble(3)+".."+rs.getStr
ing(4));
10) }
11) con.close();
12) }
DaTabase info:
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
121 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
100..Sunny..1000.0..Mumbai
200..Bunny..2000.0..Hyd
300..Chinny..3000.0..Hyd
400..Vinny..4000.0..Delhi
jshell> getEmpInfo()
100..Sunny..1000.0..Mumbai
200..Bunny..2000.0..Hyd
300..Chinny..3000.0..Hyd
400..Vinny..4000.0..Delhi
Note: Internally JShell will use environment variable CLASSPATH if we are not setting CLASSPATH
explicitly.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
122 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT – 12: How to customize JShell Startup
By default the following snippets will be executed at the time of JShell Startup.
s1 : import Java.io.*;
s2 : import Java.math.*;
s3 : import Java.net.*;
s4 : import Java.nio.file.*;
s5 : import Java.util.*;
s6 : import Java.util.concurrent.*;
s7 : import Java.util.function.*;
s8 : import Java.util.prefs.*;
s9 : import Java.util.regex.*;
s10 : import Java.util.stream.*;
mystartup.jsh:
int x =10;
String s="DURGA";
System.out.println("Hello Durga Welcome to JShell");
s1 : int x =10;
s2 : String s="DURGA";
s3 : System.out.println("Hello Durga Welcome to JShell");
Note: if we want DEFAULT import start-up snippets also then we have to open JShell as follows.
jshell> /list
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
123 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
1 : int x =10;
2 : String s="DURGA";
3 : System.out.println("Hello Durga Welcome to JShell");
s1 : import Java.io.*;
s2 : import Java.math.*;
s3 : import Java.net.*;
s4 : import Java.nio.file.*;
s5 : import Java.util.*;
s6 : import Java.util.concurrent.*;
s7 : import Java.util.function.*;
s8 : import Java.util.prefs.*;
s9 : import Java.util.regex.*;
s10 : import Java.util.stream.*;
Note: To import all JAVASE packages (almost around 173 packages) at the time of startup we have
to open JShell as follows.
jshell> /list
s1 : import Java.applet.*;
s2 : import Java.awt.*;
s3 : import Java.awt.color.*;
..
s172 : import org.xml.sax.ext.*;
s173 : import org.xml.sax.helpers.*;
Note: In addition to JAVASE, to provide our own snippets we have to open JShell as follows
jshell> /list
1 : int x =10;
2 : String s="DURGA";
3 : System.out.println("Hello Durga Welcome to JShell");
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
124 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
s1 : import Java.applet.*;
s2 : import Java.awt.*;
s3 : import Java.awt.color.*;
..
s172 : import org.xml.sax.ext.*;
s173 : import org.xml.sax.helpers.*;
Hence to print statements to the console just we can use print() or println() methods directly
instead of using System.out.print() or System.out.println() methods.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
125 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
s19 : void println(Object obj) { System.out.println(obj); }
s20 : void printf(Java.util.Locale l, String format, Object... args) { System.out.printf(l, format, args);
}
s21 : void printf(String format, Object... args) { System.out.printf(format, args); }
Now onwards,to print some statements to the console directly we can use print() and println()
methodds.
jshell> print("Hello");
Hello
jshell> print(10.5)
10.5
Note:
Note:
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
126 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
UNIT – 13: Shortcuts and Auto-Completion of Commands
Shortcut for Creating Variables:
Just type the value on the JShell and then "Shift+Tab followed by v" then complete variable
declaration code will be generated we have to provide only name of the variable.
jshell> /imports
| import Java.io.*
| import Java.math.*
| import Java.net.*
| import Java.nio.file.*
| import Java.util.*
| import Java.util.concurrent.*
| import Java.util.function.*
| import Java.util.prefs.*
| import Java.util.regex.*
| import Java.util.stream.*
| import Java.sql.Connection
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
127 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Auto Completion commands :
1. To get all static members of the class:
jshell>classsname.<Tab>
Eg:
jshell> String.<Tab>
CASE_INSENSITIVE_ORDER class copyValueOf(
format( join( valueOf(
jshell> s.sub<Tab>
subSequence( substring(
jshell> s.substring(
substring(
jshell> s.substring(<Tab>
Signatures:
String String.substring(int beginIndex)
String String.substring(int beginIndex, int endIndex)
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
128 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
jshell> s.substring(<Tab>
String String.substring(int beginIndex)
Returns a string that is a substring of this string.The substring begins with the character at the
specified index and extends to the end of this string.
Examples:
"unhappy".substring(2) returns "happy"
"Harbison".substring(3) returns "bison"
"emptiness".substring(9) returns "" (an empty string)
Parameters:
beginIndex - the beginning index, inclusive.
Returns:
the specified substring.
Note: Even this <Tab> short cut applicable for our own classes and methods also.
jshell> m1(<Tab>
m1(
jshell> m1(<Tab>
Signatures:
void m1(int... x)
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
129 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
The Java Platform Module System (JPMS)
JPMS Agenda
1) Introduction
4) What is a Module
9) JPMS vs NoClassDefFoundError
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
130 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Java Platform Module System (JPMS)
Introduction:
Modularity concept introduced in Java 9 as the part of Jigsaw project. It is the main important
concept in java 9.
Until Java 1.8 version we can develop applications by writing several classes, interfaces and
enums. We can places these components inside packages and we can convert these packages into
jar files. By placing these jar files in the classpath, we can run our applications. An enterprise
application can contain 1000s of jar files also.
Hence jar file is nothing but a group of packages and each package contains several .class files.
But in Java 9, a new construct got introduced which is nothing but 'Module'. From java 9 version
onwards we can develop applications by using module concept.
Module is nothing but a group of packages similar to jar file. But the specialty of module when
compared with jar file is, module can contain configuration information also.
Hence module is more powerful than jar file. The configuration information of module should be
specified in a special file named with module-info.java
Every module should compulsory contains module-info.java, otherwise JVM won't consider that as
a module of Java 9 platform.
module-info.java
In Java 9, JDK itself modularized. All classes of Java 9 are grouped into several modules (around 98)
like
java.base
java.logging
java.sql
java.desktop(AWT/Swing)
java.rmi etc
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
131 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
java.base module acts as base for all java 9 modules.
We can find module of a class by using getModule() method.
durgajava9
|-A1.java
|-A2.java
|-A3.java
|-Test.java
A1.java:
1) package pack1;
2) public class A1
3) {
4) public void m1()
5) {
6) System.out.println("pack1.A");
7) }
8) }
A2.java
1) package pack2;
2) import pack1.A1;
3) public class A2
4) {
5) public void m2()
6) {
7) System.out.println("pack2.A2 method");
8) A1 a = new A1();
9) a.m1();
10) }
11) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
132 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
A3.java:
1) import pack2.A2;
2) class Test
3) {
4) public static void main(String[] args)
5) {
6) System.out.println("Test class main");
7) A2 a= new A2();
8) a.m2();
9) }
10) }
D:\durgajava9>javac -d . A1.java
D:\durgajava9>javac -d . A2.java
D:\durgajava9>javac -d . A3.java
D:\durgajava9>javac Test.java
durgajava9
|-Test.class
|-pack1
|-A1.class
|-pack2
|-A2.class
At runtime, by mistake if pack1 is not available then after executing some part of the code in the
middle, we will get NoClassDefFoundError.
D:\durgajava9>java Test
Test class main
pack2.A2 method
Exception in thread "main" java.lang.NoClassDefFoundError: pack1/A1
But in Java9, there is a way to specify all dependent modules information in module-info.java. If
any module is missing then at the beginning only, JVM will identify and won't start its execution.
Hence there is no chance of raising NoClassDefFoundError in the middle of execution.
classpath = jar1;jar2;jar3;jar4
If jar4 requires Test.class file of jar3.But Different versions of Test.class is available in jar1, jar2 and
jar3. In this case jar1 Test.class file will be considered, because JVM will always search from Left to
Right in the classpath. It will create version conflicts and causes abnormal behavior of program.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
133 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
But in java9 module system, there is a way to specify dependent modules information for every
module seperately.JVM will always consider only required module and there is no order
importance. Hence version conflicts won't be raised in Java 9.
Package Package
pack1 pack2
Jar File
Assume pack1 can be used by other jar files, but pack2 is just for internal purpose only.
Until Java 8 there is no way to specify this information. Everything in jar file is public and available
to everyone. Hence there may be a chance of Security problems.
But in Java 9 Module system, we can export particular package of a module. Only this exported
package can be used by other modules. The remaining packages of that module are not visible to
outside. Hence Strong encapsulation is available in Java 9 and there is no chance of security
problems.
Even though class is public, if module won't export the corresponding package, then it cannot be
accessed by other modules. Hence public is not really that much public in Java 9 Module System.
To run small program also, total rt.jar should be loaded, which makes our application heavy
weight and not suitable for IOT applications and micro services which are targeted for portable
devices.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
134 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
It will create memory and performance problems also.
(This is something like inviting a Big Elephant in our Small House: Installing a Heavy Weight Java
application in a small portable device).
But in java 9, rt.jar removed. Instead of rt.jar all classes are maintained in the form of modules.
Hence from Java 9 onwards JDK itself modularized. Whenever we are executing a program only
required modules will be loaded instead of loading all modules, which makes our application light
weighted.
Now we can use java applications for small devices also. From Java 9 version onwards, by using
JLINK , we can create our own very small custom JREs with only required modules.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
135 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Q. What is Jar Hell or Classpath Hell?
The problems with use of jar files are:
This set of Problems is called Jar Hell OR Classpath Hell. To overcome this, we should go for JPMS.
What is a Module:
Module is nothing but collection of packages. Each module should compulsory contains a special
configuration file: module-info.java.
module-info.java
module moduleName
{
Here we have to define module dependencies which represents
1. What other modules required by this module?
2. What packages exported by this module for other modules?
etc
}
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
136 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Steps to Develop First Module Based Application:
src
moduleA
pack1
Test.java
module-info.java
module moduleA
{
}
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
137 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Step-3: Arrange all files in the required package structure
Arrange all the files according to required folder structure
src
moduleA
pack1
Test.java
module-info.java
out
moduleA
pack1
Test.class
module-info.class
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
138 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Step-5: Run the class with --module-path option
java --module-path out -m moduleA/pack1.Test
Case-1:
If module-info.java is not available then the code won't compile and we will get error. Hence
module-info.java is mandatory for every module.
Case-2:
Every class inside module should be part of some package, otherwise we will get compile time
error saying : unnamed package is not allowed in named modules
In the above application inside Test.java if we comment package statement
//package pack1;
Case-3:
The module name should not ends with digit(like module1,module2 etc),otherwise we will get
warning at compile time.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
139 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Various Possible Ways to Compile a Module:
javac --module-source-path src -d out -m moduleA
javac --module-source-path src -d out --module moduleA
javac --module-source-path src -d out
src/moduleA/module-info.java src/moduleA/pack1/Test.java
javac --module-source-path src -d out
C:/Users/Durga/Desktop/src/moduleA/module-info.java
C:/Users/Durga/Desktop/src/moduleA/pack1/Test.java
module moduleName
{
Here we have to define module dependencies which represents
1. What other modules required by this module?
2. What packages exported by this module for other modules?
etc
}
1. requires directive:
It can be used to specify the modules which are required by current module.
Eg:
1) module moduleA
2) {
3) requires moduleB;
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
140 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Note:
1. We cannot use same requires directive for multiple modules. For every module we have to use
separate requires directive.
2. We can use requires directive only for modules but not for packages and classes.
2. exports directive:
It can be used to specify what packages exported by current module to the other modules.
Eg:
1) module moduleA
2) {
3) exports pack1;
4) }
It indicates that moduleA exporting pack1 package so that this package can be used by other
modules.
Note: We cannot use same exports directive for exporting multiple packages. For every package a
separate exports directive must be required.
Note: Be careful about syntax requires directive always expecting module name where as exports
directive expecting package name.
1) module modulename
2) {
3) requires modulename;
4) exports packagename;
5) }
Note:
By default all packages present in a module are private to that module. If module exports any
package only that particular package is accessible by other modules. Non exporting packages
cannot be accessed by other modules.
Eg: Assume moduleA contains 2 packages pack1 and pack2. If moduleA exports only pack1 then
other modules can use only pack1. pack2 is just for its internal purpose and cannot be accessed by
other modules.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
141 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
1) module moduleA
2) {
3) exports pack1;
4) }
pack1 pack2
(A.java) (Test.java)
module-info.java module-info.java
moduleA moduleB
moduleA components:
A.java:
1) package pack1;
2) public class A
3) {
4) public void m1()
5) {
6) System.out.println("Method of moduleA");
7) }
8) }
module-info.java:
1) module moduleA
2) {
3) exports pack1;
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
142 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
moduleB components:
Test.java:
1) package pack2;
2) import pack1.A;
3) public class Test
4) {
5) public static void main(String[] args)
6) {
7) System.out.println("moduleB accessing members of moduleA");
8) A a = new A();
9) a.m1();
10) }
11) }
module-info.java:
1) module moduleB
2) {
3) requires moduleA;
4) }
src
moduleA moduleB
pack1 pack2
A.java Test.java
module-info.java module-info.java
Compilation:
C:\Users\Durga\Desktop>javac --module-source-path src -d out -m moduleA,moduleB
Note: space is not allowed between the module names otherwise we will get error.
moduleA moduleB
pack1 pack2
A.class Test.class
module-info.class module-info.class
Execution:
C:\Users\Durga\Desktop>java --module-path out -m moduleB/pack2.Test
Output:
moduleB accessing members of moduleA
Method of moduleA
Case-1:
Even though class A is public, if moduleA won't export pack1, then moduleB cannot access A class.
Eg:
1) module moduleA
2) {
3) //exports pack1;
4) }
Case-2:
We have to export only packages. If we are trying to export modules or classes then we will get
compile time error.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
144 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Eg-1: exporting module instead of package
1) module moduleA
2) {
3) exports moduleA;
4) }
In this case compiler considers moduleA as package and it is trying to search for that package.
1) module moduleA
2) {
3) exports pack1.A;
4) }
In this case compiler considers pack1.A as package and it is trying to search for that package.
Case-3:
If moduleB won't use "requires moduleA" directive then moduleB is not allowed to use members
of moduleA, even though moduleA exports.
1) module moduleB
2) {
3) //requires moduleA;
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
145 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
^
(package pack1 is declared in module moduleA, but module moduleB does not read it)
1 error
Case-4:
If compiled codes are available in different packages then how to run?
We have to use special option: --upgrade-module-path
If compiled codes of moduleA is available in out and compiled codes of moduleB available in out2
out out 2
moduleA moduleB
pack1 pack2
A.class Test.class
module-info.class module-info.class
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
146 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Case-5:
If source codes of two modules are in different directories then how to compile?
Assume moduleA source code is available in src directory and moduleB source code is available in
src2
src src 2
moduleA moduleB
pack1 pack2
A.java Test.java
module-info.java module-info.java
Note: We can use exports directive only for packages but not modules and classes, and we can
use requires directive only for modules but not for packages and classes.
Note: To access members of one module in other module, compulsory we have to take care the
following 3 things.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
147 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
JPMS vs NoClassDefFoundError:
In Java 9 Platform Modular System, JVM will check all dependencies at the beginning only. If any
dependent module is missing then JVM won't start its execution. Hence there is no chance of
NoClassDefFoundError in the middle of Program execution.
Demo Program:
Components of moduleA:
A.java:
1) package pack1;
2) public class A
3) {
4) public void m1()
5) {
6) System.out.println("Method of moduleA");
7) }
8) }
module-info.java:
1) module moduleA
2) {
3) exports pack1;
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
148 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Components of moduleB:
B.java:
1) package pack2;
2) import pack1.A;
3) public class B
4) {
5) public void m2()
6) {
7) System.out.println("Method of moduleB");
8) A a = new A();
9) a.m1();
10) }
11) }
module-info.java:
1) module moduleB
2) {
3) requires moduleA;
4) exports pack2;
5) }
Components of moduleC:
Test.java:
1) package pack3;
2) import pack2.B;
3) public class Test
4) {
5) public static void main(String[] args)
6) {
7) System.out.println("Test class main method");
8) B b = new B();
9) b.m2();
10) }
11) }
module-info.java:
1) module moduleC
2) {
3) requires moduleB;
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
149 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Compilation and Execution:
C:\Users\Durga\Desktop>javac --module-source-path src -d out -m moduleA, moduleB, moduleC
If we delete compiled code of module (inside out folder), then JVM will raise error at the
beginning only and JVM won't start program execution.
But in Non Modular programming, JVM will start execution and in the middle, it will raise
NoClassDefFoundError.
Hence in Java Platform Module System, there is no chance of getting NoClassDefFoundError in the
middle of program execution.
Student1 requires Material, only for himself, if any other person asking he won't share.
1) module student1
2) {
3) requires material;
4) }
"Student1 requires material not only for himself, if any other person asking him, he will share it"
1) module Student1
2) {
3) requires transitive material;
4) }
Sometimes module requires the components of some other module not only for itself and for the
modules that requires that module also. For this requirement we can use transitive keyword.
The transitive keyword says that "Whatever I have will be given to a module that asks me."
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
150 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Case-1:
1) module moduleA
2) {
3) exports pack1;
4) }
5) module moduleB
6) {
7) requires moduleA;
8) }
9) module moduleC
10) {
11) requires moduleB;
12) }
requires requires
moduleC moduleB moduleA
In this case only moduleB is available to moduleC and moduleA is not available. Hence moduleC
cannot use the members of moduleA directly.
Case-2:
1) module moduleA
2) {
3) exports pack1;
4) }
5) module moduleB
6) {
7) requires transitive moduleA;
8) }
9) module moduleC
10) {
11) requires moduleB;
12) }
requires requires
Module C Module B Module A
requires
In this both moduleB and moduleA are available to moduleC. Now moduleC can use members of
both modules directly.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
151 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Case Study:
Assume Modules C1, C2,....C10 requires Module B and Module B requires A.
C1
C2
A B
C3
:
:
:
C10
1) module B
2) {
3) requires transitive A;
4) }
Then module A is by default available to C1, C2,.., C10 automatically. Inside every module of C, we
are not required to use "requires A" explicitly. Hence transitive keyword promotes code
reusability.
Note: Transitive means implied readability i.e., Readability will be continues to the next level.
moduleA components:
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
152 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
A.java:
1) package pack1;
2) public class A
3) {
4) public void m1()
5) {
6) System.out.println("moduleA method");
7) }
8) }
module-info.java:
1) module moduleA
2) {
3) exports pack1;
4) }
moduleB components:
B.java:
1) package pack2;
2) import pack1.A;
3) public class B
4) {
5) public A m2()
6) {
7) System.out.println("moduleB method");
8) A a = new A();
9) return a;
10) }
11) }
module-info.java:
1) module moduleB
2) {
3) requires transitive moduleA;
4) exports pack2;
5) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
153 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
moduleC components:
Test.java:
1) package pack3;
2) import pack2.B;
3) public class Test
4) {
5) public static void main(String[] args)
6) {
7) System.out.println("Test class main method");
8) B b = new B();
9) b.m2().m1();
10) }
11) }
module-info.java:
1) module moduleC
2) {
3) requires moduleB;
4) }
In the above program if we are not using transitive keyword then we will get compile time error
because moduleA is not available to moduleC.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
154 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
The static keyword is used to say that, "This dependency check is mandatory at compile time and
optional at runtime."
Eg1:
1) module moduleB
2) {
3) requires moduleA;
4) }
moduleA should be available at the time of compilation and runtime. It is not optional
dependency.
Eg2:
1) module moduleB
2) {
3) requires static moduleA;
4) }
At the time of compilation moduleA should be available, but at runtime it is optional. i.e., at
runtime even moduleA is not available JVM will execute code.
pack1 pack2
(A.java) (B.java)
module-info.java module-info.java
moduleA moduleB
moduleA components:
A.java:
1) package pack1;
2) public class A
3) {
4) public void m1()
5) {
6) System.out.println("moduleA method");
7) }
8) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
155 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
module-info.java:
1) module moduleA
2) {
3) exports pack1;
4) }
moduleB components:
Test.java:
1) package pack2;
2) public class Test
3) {
4) public static void main(String[] args)
5) {
6) System.out.println("Optional Dependencies Demo!!!");
7)
8) }
9) }
module-info.java:
1) module moduleB
2) {
3) requires static moduleA;
4) }
At the time of compilation both modules should be available. But at runtime, we can run moduleB
Test class, even moduleA compiled classes are not available i.e., moduleB having optional
dependency with moduleA.
If we remove static keyword and at runtime if we delete compiled classes of moduleA, then we
will get error.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
156 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Use cases of Optional Dependencies:
Usage of optional dependencies is very common in Programming world.
1. When distributing a library and we may not want to force a big dependency to the client.
2. On the other hand, a more advanced library may have performance benefits, so whatever
module client needs, he can use.
3. We may want to allow easily pluggable implementations of some functionality. We may provide
implementations using all of these, and pick the one whose dependency is found.
Cyclic Dependencies:
If moduleA depends on moduleB and moduleB depends on moduleA, such type of dependency is
called cyclic dependency.
Demo Program:
moduleA moduleB
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
157 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
moduleA components:
module-info.java
1) module moduleA
2) {
3) requires moduleB;
4) }
moduleB components:
module-info.java
1) module moduleB
2) {
3) requires moduleA;
4) }
There may be a chance of cyclic dependency between more than 2 modules also.
moduleA requires moduleB
moduleB requires moduleC
moduleC requires moduleA
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
158 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
159 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Qualified Exports:
Sometimes a module can export its package to specific module instead of every module. Then the
specified module only can access. Such type of exports are called Qualified Exports.
Syntax:
exports <pack1> to <module1>,<module2>,...
Eg:
1) module moduleA
2) {
3) exports pack1;//to export pack1 to all modules
4) exports pack1 to moduleA;// to export pack1 only for moduleA
5) exports pack1 to moduleA,moduleB;// to export pack1 for both moduleA,mo
duleB
6) }
Components of exportermodule:
A.java:
1) package pack1;
2) public class A
3) {
4) }
B.java:
1) package pack2;
2) public class B
3) {
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
160 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
C.java:
1) package pack3;
2) public class C
3) {
4) }
module-info.java:
1) module exportermodule
2) {
3) exports pack1;
4) exports pack2 to moduleA;
5) exports pack3 to moduleA,moduleB;
6) }
moduleA moduleB
pack1 √ √
pack2 √
pack3 √ √
Components of moduleA:
Test.java:
1) package packA;
2) import pack1.A;
3) import pack2.B;
4) import pack3.C;
5) public class Test
6) {
7) public static void main(String[] args)
8) {
9) System.out.println("Qualified Exports Demo");
10) }
11) }
module-info.java:
1) module moduleA
2) {
3) requires exportermodule;
4) }
Explanation:
For moduleA, all 3 packages are available. Hence we can compile and run moduleA successfully.
C:\Users\Durga\Desktop>javac --module-source-path src -d out -m exportermodule, moduleA
C:\Users\Durga\Desktop>java --module-path out -m moduleA/packA.Test
Qualified Exports Demo
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
161 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Components of moduleB:
Test.java:
1) package packB;
2) import pack1.A;
3) import pack2.B;
4) import pack3.C;
5) public class Test
6) {
7) public static void main(String[] args)
8) {
9) System.out.println("Qualified Exports Demo");
10) }
11) }
module-info.java:
1) module moduleB
2) {
3) requires exportermodule;
4) }
Explanation:
For moduleB, only pack1 and pack3 are available. pack2 is not available. But in moduleB we are
trying to access pack2 and hence we will get compile time error.
Answers: 1,5,6,7,11,12
Module Graph:
The dependencies between the modules can be represented by using a special graph, which is
nothing but Module Graph.
1) module moduleA
2) {
3) requires moduleB;
4) }
moduleA
moduleB
Eg 2: If moduleA requires moduleB and moduleC then the corresponding module graph is:
1) module moduleA
2) {
3) requires moduleB;
4) requires moduleC;
5) }
moduleA
moduleB moduleC
Eg 3: If moduleA requires moduleB and moduleB requires moduleC then the corresponding
module graph is:
1) module moduleA
2) {
3) requires moduleB;
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
163 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
5) module moduleB
6) {
7) requires moduleC;
8) }
moduleA
moduleB
moduleC
Eg 4: If moduleA requires moduleB and moduleB requires transitive moduleC then the
corresponding module graph is:
1) module moduleA
2) {
3) requires moduleB;
4) }
5) module moduleB
6) {
7) requires transitive moduleC;
8) }
moduleA
moduleB
moduleC
Eg 5: If moduleA requires moduleB and moduleC, moduleC requires moduleD and transitive
moduleE then the corresponding Modular Graph is:
1) module moduleA
2) {
3) requires moduleB;
4) requires moduleC;
5) }
6) module moduleC
7) {
8) requires moduleD;
9) requires transitive moduleE;
10) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
164 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
moduleA
moduleB moduleC
moduleD moduleE
Java 9 JDK itself modularized. All classes of Java SE are divided into several modules.
Eg:
java.base
java.sql
java.xml
java.rmi
etc...
The module graph of JDK is
In the above diagram all modules requires java.base module either directly or indirectly. Hence
this module acts as BASE module for all java modules.
Observe modular graphs carefully:java.se and java.sql modules etc
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
165 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Observable Modules:
The modules which are observed by JVM at runtime are called Observable modules.
The modules we are specifying with --module-path option with java command are observed by
JVM and hence these are observable modules.
JDK itself contains several modules (like java.base, java.sql, java.rmi etc). These modules can be
observed automatically by JVM at runtime and we are not required to use --module-path. Hence
these are observable modules.
Observable Modules = All Predefined JDK Modules + The modules specified with --module-path
option
We can list out all Observable Modules by using --list-modules option with java command.
Eg1: To print all readymade compiled modules (pre defined modules) present in Java 9
C:\Users\Durga\Desktop>java --list-modules
java.activation@9
java.base@9
java.compiler@9
....
Eg2: Assume our own created compiled modules are available in out folder. To list out these
modules including readymade java modules
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
166 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Aggregator Module:
Sometimes a group of modules can be reused by multiple other modules. Then it is not
recommended to read each module individually. We can group those common modules into a
single module, and we can read that module directly. This module which aggregates functionality
of several modules into a single module is called Aggregator module. If any module reads
aggregator module then automatically all its modules are by default available to that module.
Aggregator module won't provide any functionality by its own, just it gathers and bundles
together a bunch of other modules.
aggregatorModule
1) module aggregatorModule
2) {
3) requires transitive moduleA;
4) requires transitive moduleB;
5) requires transitive moduleC;
6) }
Aggregator Module not required to contain a single java class. Just it "requires transitive" of all
common modules.
If any module reads aggregatorModule automatically all 3 modules are by default available to that
module also.
1) module useModule
2) {
3) requires aggregatorModule;
4) }
Now useModule can use functionality of all 3 modules moduleA, moduleB and moduleC.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
167 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Demo Program for Aggregator Module:
module-info.java
aggregatorModule
packA
(Test.java)
module-info.java
useModule
moduleA components:
A.java:
1) package pack1;
2) public class A
3) {
4) public void m1()
5) {
6) System.out.println("moduleA method");
7) }
8) }
module-info.java:
1) module moduleA
2) {
3) exports pack1;
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
168 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
moduleB components:
B.java:
1) package pack2;
2) public class B
3) {
4) public void m1()
5) {
6) System.out.println("moduleB method");
7) }
8) }
module-info.java:
1) module moduleB
2) {
3) exports pack2;
4) }
moduleC components:
C.java:
1) package pack3;
2) public class C
3) {
4) public void m1()
5) {
6) System.out.println("moduleC method");
7) }
8) }
module-info.java:
1) module moduleC
2) {
3) exports pack3;
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
169 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
aggregatorModule components:
module-info.java:
1) module aggregatorModule
2) {
3) requires transitive moduleA;
4) requires transitive moduleB;
5) requires transitive moduleC;
6) }
useModule components:
Test.java:
1) package packA;
2) import pack1.A;
3) import pack2.B;
4) import pack3.C;
5) public class Test
6) {
7) public static void main(String[] args)
8) {
9) System.out.println("Aggregator Module Demo");
10) A a = new A();
11) a.m1();
12)
13) B b = new B();
14) b.m1();
15)
16) C c = new C();
17) c.m1();
18) }
19) }
module-info.java:
Here we are not required to use requires directive for every module, just we have to use requires
only for aggregatorModule.
1) module useModule
2) {
3) //requires moduleA;
4) //requires moduleB;
5) //requires moduleC;
6) requires aggregatorModule;
7) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
170 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
C:\Users\Durga\Desktop>javac --module-source-path src -d out -m
moduleA,moduleB,moduleC,aggregatorModule,useModule
But in Java 9 module System, two modules cannot contain a package with same name; otherwise
we will get compile time error. Hence in module system, there is no chance of version conflicts and
abnormal behavior of the program.
Demo Program:
moduleA components:
A.java:
1) package pack1;
2) public class A
3) {
4) public void m1()
5) {
6) System.out.println("moduleA method");
7) }
8) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
171 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
module-info.java:
1) module moduleA
2) {
3) exports pack1;
4) }
moduleB components:
B.java:
1) package pack1;
2) public class B
3) {
4) public void m1()
5) {
6) System.out.println("moduleB method");
7) }
8) }
module-info.java:
1) module moduleB
2) {
3) exports pack1;
4) }
useModule components:
Test.java:
1) package packA;
2) public class Test
3) {
4) public static void main(String[] args)
5) {
6) System.out.println("Package Naming Conflicts");
7) }
8) }
module-info.java:
1) module useModule {
2) requires moduleA;
3) requires moduleB;
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
172 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
javac --module-source-path src -d out -m moduleA,moduleB,useModule
error: module useModule reads package pack1 from both moduleA and moduleB
But in module programming, JVM will search for the required modules in the module-path before
it starts execution. If any module is missing at the beginning only JVM will identify and won't start
its execution. Hence in modular programming, there is no chance of getting NoClassDefFoundError
in the middle of program execution.
Demo Program:
useModule
moduleA
moduleB
moduleC moduleD
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
173 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Components of useModule:
Test.java:
1) package packA;
2) public class Test
3) {
4) public static void main(String[] args)
5) {
6) System.out.println("Module Resolution Process(MRP) Demo");
7) }
8) }
module-info.java:
1) module useModule
2) {
3) requires moduleA;
4) }
Components of moduleA:
module-info.java:
1) module moduleA
2) {
3) requires moduleB;
4) }
Components of moduleB:
module-info.java:
1) module moduleB
2) {
3) requires moduleC;
4) requires moduleD;
5) }
Components of moduleC:
module-info.java:
1) module moduleC
2) {
3)
4) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
174 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Components of moduleD:
module-info.java:
1. module moduleD
2. {
3.
4. }
Note:
The following are restricted keywords in java 9:
module, requires, transitive, exports
In normal Java program no restrictions and we can use for identifier purpose also.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
175 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
JLINK (Java Linker)
Until 1.8 version to run a small Java program (like Hello World program) also, we should use a
bigger JRE which contains all java's inbuilt 4300+ classes. It increases the size of Java Runtime
environment and Java applications. Due to this Java is not suitable for IOT devices and Micro
Services. (No one invite a bigger Elephant into their small house).
To overcome this problem, Java people introduced Compact Profiles in Java 8. But they didn't
succeed that much. In Java 9, they introduced a permanent solution to reduce the size of Java
Runtime Environment, which is nothing but JLINK.
JLINK is Java's new command line tool (which is available in JDK_HOME\bin) which allows us to
link sets of only required modules (and their dependencies) to create a runtime image (our own
JRE).
Now, our Custom JRE contains only required modules and classes instead of having all 4300+
classes.
It reduces the size of Java Runtime Environment, which makes java best suitable for IOT and micro
services.
Hence, Jlink's main intention is to avoid shipping everything and, also, to run on very small devices
with little memory. By using Jlink, we can get our own very small JRE.
Jlink also has a list of plugins (like compress) that will help optimize our solutions.
module-info.java:
1) module demoModule
2) {
3) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
176 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Test.java:
1) package packA;
2) public class Test
3) {
4) public static void main(String[] args)
5) {
6) System.out.println("JLINK Demo To create our own customized & small JRE");
7) }
8) }
Compilation:
C:\Users\Durga\Desktop>javac --module-source-path src -d out -m demoModule
o/p: JLINK Demo To create our own customized & small JRE
out
|-java.base.jmod
|-demoModule
|-module-info.class
|-packA
|-Test.class
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
177 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Now observe the size of durgajre is just 35.9MB which is very small when compared with default
JRE size 203MB.
We can run our application with our own custom jre (durgajre) as follows
C:\Users\Durga\Desktop\durgajre\bin>java -m demoModule/packA.Test
o/p: JLINK Demo To create our own customized & small JRE
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
178 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
C:\Users\Durga\Desktop>jlink --module-path out --add-modules demoModule,java.base --
compress 2 --output durgajre2
C:\Users\Durga\Desktop\durgajre2\bin>java -m demoModule/packA.Test
o/p: JLINK Demo To create our own customized & small JRE
Now we can run our application only with the name demoapp
C:\Users\Durga\Desktop\durgajre3\bin>demoapp
JLINK Demo To create our own customized & small JRE
The way of communication with processor is varied from system to system (i.e. os to os). For
example, in windows one way, but in Mac other way. Being a programmer we have to write code
based on operating system, which makes programming very complex.
To resolve this complexity, JDK 9 engineers introduced several enhancements to Process API. By
using this Updated API, we can write java code to communicate with any processor very easily.
According to worldwide Java Developers, Process API Updates is the number 1 feature in Java 9.
With this Enhanced API, we can perform the following activities very easily.
2. Added several new methods (like startPipeline()) to ProcessBuilder class. We can use
ProcessBuilder class to create operating system processes.
3. Introduced a new powerful interface ProcessHandle. With this interface, we can access current
running process, we can access parent and child processes of a particular process etc
4. Introduced a new interface ProcessHandle.Info, by using this we can get complete information
of a particular process.
Note: All these classes and interfaces are part of java.lang package and hence we are not required
to use any import statement.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
180 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
How to get ProcessHandle object:
It is the most powerful and useful interface introduced in java 9.
We can get ProcessHandle object as follows
1. ProcessHandle handle=ProcessHandle.current();
Returns the ProcessHandle of current running Process
2. ProcessHandle handle=p.toHandle();
Returns the ProcessHandle of specified Process object.
3. Optional<ProcessHandle> handle=ProcessHandle.of(PID);
Returns the ProcessHandle of proccess with the specified pid.
Here, the return type is Optional, because PID may exist or may not exist.
ProcessHandle.Info:
We can get complete information of a particular process by using ProcessHandle.Info object.
We can get this Info object as follows.
ProcessHandle p = ProcessHandle.current();
ProcessHandle.Info info = p.info();
Once we got Info object, we can call the following methods on that object.
1. user():
Return the user of the process.
public Optional<String> user()
2. command():
Returns the command,that can be used to start the process.
public Optional<String> command()
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
181 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
3. startInstant():
Returns the start time of the process.
public Optional<String> startInstant()
4. totalCpuDuration():
Returns the total cputime accumulated of the process.
public Optional<String> totalCpuDuration()
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
182 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
ProcessBuilder:
We can use ProcessBuilder to create processes.
We can create ProcessBuilder object by using the following constructor.
Eg:
ProcessBuilder pb = new ProcessBuilder("javac","Test.java");
ProcessBuilder pb = new ProcessBuilder("java","Test");
ProcessBuilder pb = new ProcessBuilder("notepad.exe","D:\\names.txt");
Once we create a ProcessBuilder object,we can start the process by using start() method.
pb.start();
1) import java.awt.*;
2) import java.awt.event.*;
3) public class FrameDemo
4) {
5) public static void main(String[] args)
6) {
7) Frame f = new Frame();
8) f.addWindowListener( new WindowAdapter()
9) {
10) public void windowClosing(WindowEvent e)
11) {
12) System.exit(0);
13) }
14) });
15) f.add(new Label("This Process Started from Java by using ProcessBuilder !!!"));
16) f.setSize(500,500);
17) f.setVisible(true);
18) }
19) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
183 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Test.java
Use Case-5: To open a file with notepad from java by using ProcessBuilder
Use Case-6: To start and destroy a process from java by using ProcessBuilder
1) class Test
2) {
3) public static void main(String[] args) throws Exception
4) {
5) ProcessBuilder pb=new ProcessBuilder("java","FrameDemo");
6) Process p=pb.start();
7) System.out.println("Process Started with id:"+p.pid());
8) Thread.sleep(10000);
9) System.out.println("Destroying the process with id:"+p.pid());
10) p.destroy();
11) }
12) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
184 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Use Case-8: To display all running process information
1) import java.util.*;
2) import java.util.stream.*;
3) import java.time.*;
4) class Test
5) {
6) public static void dumpProcessInfo(ProcessHandle p)
7) {
8) ProcessHandle.Info info=p.info();
9) System.out.println("Process Id:"+p.pid());
10) System.out.println("User: "+info.user().orElse(""));
11) System.out.println("Command: "+info.command().orElse(""));
12) System.out.println("Start Time: "+info.startInstant().orElse(Instant.now()).toString());
13) System.out.println("Total CPU Time Acquired: "+info.totalCpuDuration().
14) orElse(Duration.ofMillis(0)).toMillis());
15) System.out.println();
16) }
17) public static void main(String[] args) throws Exception
18) {
19) Stream<ProcessHandle> allp=ProcessHandle.allProcesses();
20) allp.limit(100).forEach(ph->dumpProcessInfo(ph));
21) }
22) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
185 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Note: If Current Process not having any child processes then we won't get any output
D:\durga_classes>java Test
Process Started with id:4828
Process[pid=4828, exitValue=0]
Process Terminated with Id:4828
D:\durga_classes>java Test
Process Started with id:12512
Process[pid=12512, exitValue=1]
Process Terminated with Id:12512
Observe exit value: 0 for normal termination and non-zero for abnormal termination
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
186 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
HTTP/2 Client
What is the purpose of HTTP/2 Client:
HTTP/2 Client is one of the most exciting features, for which developers are waiting for long time.
By using this new HTTP/2 Client, from Java application, we can send HTTP Request and we can
process HTTP Response.
HTTP Request
Java Application
(HTTP/2 Client API)
Prior to Java 9, we are using HttpURLConnection class to send HTTP Request and to Process HTTP
Response. It is the legacy class which was introduced as the part of JDK 1.1 (1997).There are
several problems with this HttpURLConnection class.
A. We can send only one request at a time per TCP Connection, which creates network traffic
problems and performance problems.
B. It supports only Text data but not binary data
3. It works only in Blocking Mode (Synchronous Mode), which creates performance problems.
Because of these problems, slowly developers started using 3rd party Http Clients like Apache Http
client and Google Http client etc.
JDK 9 Engineers addresses these issues and introduced a brand new HTTP/2 Client in Java 9.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
187 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Advantages of Java 9 HTTP/2 Client:
1. It is Lightweight and very easy to use.
2. It supports both HTTP/1.1 and HTTP/2.
3. It supports both Text data and Binary Data (Streams)
4. It can work in both Blocking and Non-Blocking Modes (Synchronous Communication and
Asynchronous Communication)
5. It provides better performance and Scalability when compared with traditional
HttpURLConnection.
etc...
Module: jdk.incubator.httpclient
Package: jdk.incubator.http
1. HttpClient
2. HttpRequest
3. HttpResponse
Note:
Incubator module is by default not available to our java application. Hence compulsory we should
read explicitly by using requires directive.
1) module demoModule
2) {
3) requires jdk.incubator.httpclient;
4) }
Steps to send Http Request and process Http Response from Java
Application:
1. Create HttpClient Object
2. Create HttpRequest object
3. Send HttpRequest by using HttpClient and Get the HttpResponse
4. Process HttpResponse
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
188 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
2. Creation of HttpRequest object:
We can create HttpRequest object as follows:
String url="http://www.durgasoft.com";
HttpRequest req=HttpRequest.newBuilder(new URI(url)).GET().build();
Note:
newBuilder() method returns Builder object.
GET() method sets the request method of this builder to GET.
build() method builds and returns a HttpRequest.
Eg:
HttpResponse resp=client.send(req,HttpResponse.BodyHandler.asString());
HttpResponse resp=client.send(req,HttpResponse.BodyHandler.asFile(Paths.get("abc.txt")));
Note:
BodyHandler is a functional interface present inside HttpResponse. It can be used to handle body
of HttpResponse.
4. Process HttpResponse:
HttpResponse contains the status code, response headers and body.
Status Line
Response Headers
Response Body
Structure of HTTP Response
HttpResponse class contains the following methods retrieve data from the response
1. statusCode()
Returns status code of the response
It may be (1XX,2XX,3XX,4XX,5XX)
2. body()
Returns body of the response
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
189 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
3. headers()
Returns header information of the response
Eg:
System.out.println("Status Code:"+resp.statusCode());
System.out.println("Body:"+resp.body());
System.out.println("Response Headers Info");
HttpHeaders header=resp.headers();
Map<String,List<String>> map=header.map();
map.forEach((k,v)->System.out.println("\t"+k+":"+v));
demoModule
packA
Test.java
module-info.java
module-info.java:
1) module demoModule
2) {
3) requires jdk.incubator.httpclient;
4) }
Test.java:
1) package packA;
2) import jdk.incubator.http.HttpClient;
3) import jdk.incubator.http.HttpRequest;
4) import jdk.incubator.http.HttpResponse;
5) import jdk.incubator.http.HttpHeaders;
6) import java.net.URI;
7) import java.util.Map;
8) import java.util.List;
9) public class Test
10) {
11) public static void main(String[] args) throws Exception
12) {
13) String url="https://www.redbus.in/info/aboutus";
14) sendGetSyncRequest(url);
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
190 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
15) }
16) public static void sendGetSyncRequest(String url) throws Exception
17) {
18) HttpClient client=HttpClient.newHttpClient();
19) HttpRequest req=HttpRequest.newBuilder(new URI(url)).GET().build();
20) HttpResponse resp=client.send(req,HttpResponse.BodyHandler.asString());
21) processResponse(resp);
22) }
23) public static void processResponse(HttpResponse resp)
24) {
25) System.out.println("Status Code:"+resp.statusCode());
26) System.out.println("Response Body:"+resp.body());
27) HttpHeaders header=resp.headers();
28) Map<String,List<String>> map=header.map();
29) System.out.println("Response Headers");
30) map.forEach((k,v)->System.out.println("\t"+k+":"+v));
31) }
32) }
Note:
Paths is a class present in java.nio.file package and hence we should write import as
import java.nio.file.Paths;
In this case, abc.html file will be created in the current working directory which contains total
response body.
Demo Program:
demoModule
packA
Test.java
module-info.java
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
191 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
module-info.java:
1) module demoModule
2) {
3) requires jdk.incubator.httpclient;
4) }
Test.java:
1) package packA;
2) import jdk.incubator.http.HttpClient;
3) import jdk.incubator.http.HttpRequest;
4) import jdk.incubator.http.HttpResponse;
5) import jdk.incubator.http.HttpHeaders;
6) import java.net.URI;
7) import java.util.Map;
8) import java.util.List;
9) import java.nio.file.Paths;
10) public class Test
11) {
12) public static void main(String[] args) throws Exception
13) {
14) String url="https://www.redbus.in/info/aboutus";
15) sendGetSyncRequest(url);
16) }
17) public static void sendGetSyncRequest(String url) throws Exception
18) {
19) HttpClient client=HttpClient.newHttpClient();
20) HttpRequest req=HttpRequest.newBuilder(new URI(url)).GET().build();
21) HttpResponse resp=client.send(req,HttpResponse.BodyHandler.asFile(Paths.get("abc.
html")));
22) processResponse(resp);
23) }
24) public static void processResponse(HttpResponse resp)
25) {
26) System.out.println("Status Code:"+resp.statusCode());
27) //System.out.println("Response Body:"+resp.body());
28) HttpHeaders header=resp.headers();
29) Map<String,List<String>> map=header.map();
30) System.out.println("Response Headers");
31) map.forEach((k,v)->System.out.println("\t"+k+":"+v));
32) }
33) }
abc.html will be created in the current working directory. Open that file to see body of response.
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
192 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
Asynchronous Communication:
In Blocking Mode (Synchronous Mode), Once we send Http Request, we should wait until getting
response. It creates performance problems.
But in Non-Blocking Mode (Asynchronous Mode), we are not required to wait until getting the
response. We can continue our execution and later point of time we can use that HttpResponse
once it is ready, so that performance of the system will be improved.
CompletableFuture<HttpResponse<String>> cf =
client.sendAsync(req,HttpResponse.BodyHandler.asString());
demoModule
packA
Test.java
module-info.java
module-info.java:
1) module demoModule
2) {
3) requires jdk.incubator.httpclient;
4) }
Test.java:
1) package packA;
2) import jdk.incubator.http.HttpClient;
3) import jdk.incubator.http.HttpRequest;
4) import jdk.incubator.http.HttpResponse;
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
193 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com
5) import jdk.incubator.http.HttpHeaders;
6) import java.net.URI;
7) import java.util.Map;
8) import java.util.List;
9) import java.util.concurrent.CompletableFuture;
10) public class Test
11) {
12) public static void main(String[] args) throws Exception
13) {
14) String url="https://www.redbus.in/info/aboutus";
15) sendGetAsyncRequest(url);
16) }
17) public static void sendGetAsyncRequest(String url) throws Exception
18) {
19) HttpClient client=HttpClient.newHttpClient();
20) HttpRequest req=HttpRequest.newBuilder(new URI(url)).GET().build();
21) System.out.println("Sending Asynchronous Request...");
22) CompletableFuture<HttpResponse<String>> cf = client.sendAsync(req,HttpResponse.B
odyHandler.asString());
23) int count=0;
24) while(!cf.isDone())
25) {
26) System.out.println("Processing not done and doing other activity:"+ ++count);
27) }
28) processResponse(cf.get());
29) }
30) public static void processResponse(HttpResponse resp)
31) {
32) System.out.println("Status Code:"+resp.statusCode());
33) //System.out.println("Response Body:"+resp.body());
34) HttpHeaders header=resp.headers();
35) Map<String,List<String>> map=header.map();
36) System.out.println("Response Headers");
37) map.forEach((k,v)->System.out.println("\t"+k+":"+v));
38) }
39) }
nd
DURGASOFT, # 202, 2 Floor, HUDA Maitrivanam, Ameerpet, Hyderabad - 500038,
194 040 – 64 51 27 86, 80 96 96 96 96, 92 46 21 21 43 | www.durgasoft.com