0882 Learning Java Language PDF
0882 Learning Java Language PDF
#java
Table of Contents
About 1
Remarks 2
Installing Java 3
What's next? 3
Testing 3
Other 3
Versions 4
Examples 4
Introduction 11
Examples 11
Remarks 14
Examples 14
More examples: 16
Nore examples: 19
Introduction 25
Syntax 25
Remarks 25
Parameter types 25
Examples 25
Built-in annotations 25
Default values 30
Meta-Annotations 30
@Target 30
Available Values 30
@Retention 31
Available values 32
@Documented 32
@Inherited 32
@Repeatable 32
Repeating Annotations 33
Inherited Annotations 35
Example 35
The annotation 36
Packaging 38
IDE integration 39
Netbeans 39
Result 39
The idea behind Annotations 40
Examples 42
Introduction 45
Examples 45
Chapter 7: Applets 47
Introduction 47
Remarks 47
Examples 47
Minimal Applet 47
Creating a GUI 48
Chapter 8: Arrays 52
Introduction 52
Syntax 52
Parameters 52
Examples 52
Basic cases 52
Arrays, Collections, and Streams 53
Intro 53
Arrays to a String 61
ArrayIndexOutOfBoundsException 66
Arrays to Stream 68
Copying arrays 71
for loop 71
Object.clone() 71
Arrays.copyOf() 72
System.arraycopy() 72
Arrays.copyOfRange() 72
Casting Arrays 73
Using ArrayList 73
Using System.arraycopy 74
Array Covariance 74
Using a Stream 77
Sorting arrays 78
Chapter 9: Asserting 81
Syntax 81
Parameters 81
Remarks 81
Examples 81
Introduction 82
Parameters 82
Remarks 82
Examples 82
Remarks 87
Examples 87
Introduction 91
Remarks 91
Examples 91
Remarks 96
Examples 96
For Loops 97
While Loops 98
do...while Loop 98
For Each 98
If / Else 99
Break 102
Introduction 105
Examples 105
Simple JMH example 105
Introduction 108
Examples 108
1.Addition 108
2.Subtraction 109
3.Multiplication 109
4.Division 109
6.Power 110
7.Max 111
8.Min 111
BigDecimal.valueOf() 113
Introduction 114
Syntax 114
Remarks 114
Examples 115
Initialization 115
Examples 122
Checking, setting, clearing, and toggling individual bits. Using long as bit mask 123
Syntax 128
Remarks 128
Examples 128
Introduction 130
Syntax 130
Examples 130
Examples 133
Introduction 140
Remarks 140
C++ 140
Java 140
C++ 140
Java 141
C++ 141
Java 141
Polymorphism 142
Examples 145
C++ 146
Java 146
C++ 146
Java 147
C++ 147
Java 147
C++ 149
Java 149
C++ 150
Java 150
Interface 150
C++ 150
Java 150
Remarks 151
Examples 151
Examples 153
Introduction 155
Examples 155
Introduction 156
Examples 156
Introduction 157
Syntax 157
Examples 157
Constructors 162
Remarks 167
Examples 167
Introduction 170
Syntax 170
Parameters 170
Examples 170
Introduction 172
Remarks 172
Examples 173
INCORRECT 176
CORRECT 177
Creating your own Iterable structure for use with Iterator or for-each loop. 184
Syntax 188
Parameters 188
Remarks 188
Examples 188
Introduction 192
Examples 192
The equality operator does NOT test that two objects are equal 200
Syntax 204
Remarks 204
Examples 204
Introduction 212
Examples 212
Introduction 214
Examples 214
Thread-safe Collections 214
Introduction 218
Remarks 218
Examples 218
Producer-Consumer 219
CountDownLatch 221
Synchronization 223
Semaphore 237
Get status of all threads started by your program excluding system threads 239
Examples 244
Introduction 249
Remarks 249
Examples 249
Examples 253
Remarks 259
Examples 259
Examples 266
Syntax 267
Parameters 267
Remarks 267
Examples 268
LocalTime 277
Examples 278
Instant 279
Syntax 283
Remarks 283
References : 284
Examples 284
Introduction 290
Remarks 290
Examples 290
Syntax 292
Parameters 292
Examples 292
Introduction 300
Syntax 300
Remarks 301
Examples 301
Links 303
Introduction 307
Remarks 307
Examples 307
Introduction 310
Remarks 310
Examples 310
Introduction 313
Examples 313
Introduction 314
Examples 314
Introduction 315
Syntax 315
Remarks 315
Restrictions 315
Tips & Tricks 315
Examples 316
By default: 328
Introduction 334
Examples 334
Introduction 335
Syntax 335
Examples 335
Introduction 352
Try-finally 357
try-catch-finally 357
Introduction 361
Remarks 361
Examples 361
ThreadPoolExecutor 362
Introduction 374
Remarks 374
Examples 374
Introduction 381
Examples 381
Locking 389
Introduction 397
Examples 397
Remarks 400
Examples 400
Syntax 403
Parameters 403
Examples 403
Introduction 409
Examples 409
Examples 412
Introduction 413
Syntax 413
Remarks 413
Examples 413
Note: 423
Workarounds 423
Referring to the declared generic type within its own declaration 424
Different ways for implementing a Generic Interface (or extending a Generic Class) 426
Introduction 430
Examples 430
Introduction 434
Examples 434
Hashtable 434
Remarks 435
Examples 435
Explanation: 438
Example: 438
Introduction 439
Remarks 439
Examples 439
Remarks 442
Examples 442
Typical design flaws which prevent a class from being immutable 444
Introduction 448
Syntax 448
Remarks 448
Examples 448
Inheritance 453
Abstract class and Interface usage: "Is-a" relation vs "Has-a" capability 460
Syntax 465
Remarks 465
Examples 465
Introduction 470
Examples 470
Assumptions: 470
Introduction 482
Syntax 482
Examples 482
Variables 492
Methods 492
Introduction 494
Remarks 494
Examples 494
Examples 498
Remarks 501
Examples 501
References 504
Introduction 506
Remarks 506
Examples 506
Creating JAR, WAR and EAR files using the jar command. 508
Prerequisites 509
Examples 513
Differences between Java EE, Java SE, Java ME and JavaFX 514
Java SE 515
Java EE 515
Java ME 515
Java FX 516
Introduction 519
Examples 519
Remarks 524
Examples 524
Finalization 524
Remarks 531
Examples 531
Actions 534
Examples 539
Parameters 541
Remarks 541
Examples 541
Output 543
Output 544
Examples 547
Introduction 550
Examples 550
Introduction 558
Remarks 558
Examples 558
Pitfall - Leaving out braces: the "dangling if" and "dangling else" problems 561
Pitfall - Declaring classes with the same names as standard classes 564
Remarks 569
Examples 569
In summary 573
Pitfall - Not checking if an I/O stream isn't even initialized when closing it 573
Introduction 576
Remarks 576
Examples 576
Solution 576
Pitfall - Interning strings so that you can use == is a bad idea 585
Fragility 585
Examples 590
Remarks 599
Examples 599
Introduction 604
Examples 604
Introduction 609
Remarks 609
Examples 609
Introduction 612
Remarks 612
Examples 612
Introduction 614
Remarks 614
Examples 614
Examples 618
Introduction 619
Syntax 619
Remarks 619
Examples 620
Introduction 621
Syntax 621
Parameters 621
Remarks 621
Examples 621
Example 627
Adapter 627
Examples 631
Introduction 632
Examples 632
Examples 637
Syntax 641
Remarks 641
Examples 641
Expressions 642
Variables 642
Introduction 645
Remarks 645
Examples 645
Details 648
Deserialization: 648
JSONObject.NULL 650
Details 652
Note 652
Remarks 654
History 654
Examples 654
Overview 654
Remarks 657
Examples 657
-XXaggressive 657
-XXallocClearChunks 657
-XXallocClearChunkSize 658
-XXcallProfiling 658
-XXdisableFatSpin 658
-XXdisableGCHeuristics 659
-XXdumpSize 659
-XXexitOnOutOfMemory 659
Remarks 661
Examples 661
Syntax 665
Examples 665
Cheat-Sheet 672
`return` only returns from the lambda, not the outer method 674
Using lambda expressions & predicates to get a certain value(s) from a list 680
Introduction 682
Examples 682
Java LinkedHashMap class 682
Introduction 684
Examples 684
Introduction 685
Syntax 685
Remarks 685
Examples 686
Removing elements from list B that are present in the list A 691
ArrayList 696
AttributeList 696
CopyOnWriteArrayList 696
LinkedList 696
RoleList 697
RoleUnresolvedList 697
Stack 697
Vector 697
Chapter 108: Literals 699
Introduction 699
Examples 699
Underscores 705
Introduction 707
Examples 707
Remarks 708
Locale 709
Language 710
Syntax 712
Parameters 712
Remarks 712
Examples 712
Intro 714
Introduction 716
Syntax 716
Remarks 716
Examples 717
Examples 723
Introduction 727
Remarks 727
Examples 727
Introduction 739
Syntax 742
Remarks 742
Examples 742
Introduction 744
Examples 744
Example of a multi-release Jar file's contents 744
Introduction 747
Syntax 747
Remarks 747
Examples 747
Introduction 752
Syntax 752
Remarks 752
Examples 753
Constructors 758
Examples 761
Multicasting 766
Notes 770
Syntax 771
Examples 771
Examples 775
Introduction 777
Examples 777
final 777
volatile 778
static 779
abstract 780
synchronized 781
transient 782
strictfp 782
Examples 783
NumberFormat 783
Introduction 784
Syntax 784
Examples 784
Examples 798
Remarks 802
Examples 802
Introduction 806
Remarks 806
Examples 806
Syntax 814
Common Usage 815
The Assignment Operators (=, +=, -=, *=, /=, %=, <<=, >>= , >>>=, &=, |= and ^=) 818
Introduction 825
Syntax 825
Examples 825
Map 826
Filter 827
FlatMap 829
Introduction 830
Remarks 830
Examples 830
Variables 831
Type Variables 831
Constants 831
Modifiers 834
Indentation 835
Whitespace 837
Annotations 838
Literals 840
Braces 840
Introduction 842
Remarks 842
Examples 842
Examples 844
Introduction 846
Remarks 846
Examples 846
Examples 855
PreferenceChangeEvent 855
NodeChangeEvent 855
Introduction 862
Syntax 862
Remarks 862
Examples 863
Remarks 874
Examples 874
ch.vorburger.exec 876
Pitfall: Runtime.exec, Process and ProcessBuilder don't understand shell syntax 876
Introduction 879
Syntax 879
Remarks 879
Examples 880
Stacks 886
Example 886
BlockingQueue 887
Deque 889
Remarks 891
Examples 891
Introduction 896
Examples 896
BufferedReader 896
Introduction 896
Introduction 899
Remarks 899
Output 899
Examples 900
Example 903
Workaround 904
Example 904
Examples 908
Dereferencing 908
Examples 910
Introduction 912
Remarks 912
Performance 912
Examples 912
Introduction 912
Introduction 924
Syntax 924
Remarks 924
Imports 924
Pitfalls 924
Examples 925
Using regex with custom behaviour by compiling the Pattern with flags 926
Remarks 930
Examples 930
Client-Server: invoking methods in one JVM from another 930
Overview 932
Introduction 940
Remarks 940
Examples 941
Examples 945
Examples 950
Syntax 951
Parameters 951
Remarks 951
Examples 951
General Pattern that does most commonly asked about tasks 953
Syntax 956
Examples 956
Examples 958
Introduction 962
Remarks 962
Examples 962
Examples 964
Demo 972
Introduction 974
Examples 974
Remarks 985
Examples 985
Service 985
META-INF/services/servicetest.Logger 986
Usage 986
Examples 989
Introduction 994
Examples 994
Thread-safe lazy initialization using holder class | Bill Pugh Singleton implementation 996
Introduction 1000
Examples 1000
Introduction 1001
Examples 1001
Remarks 1003
Examples 1003
Introduction 1004
Examples 1004
Introduction 1007
Syntax 1007
Examples 1007
Cheat-Sheet 1012
h21 1015
Introduction 1033
Examples 1033
Introduction 1035
Examples 1035
Introduction 1037
Syntax 1037
Remarks 1037
Examples 1037
Introduction 1040
Remarks 1040
Examples 1041
Comparing Strings 1041
Substrings 1047
Regex 1057
Remarks 1061
Examples 1061
Instantiating sun.misc.Unsafe via reflection 1061
Examples 1064
Introduction 1067
Remarks 1067
Examples 1067
Syntax 1073
Remarks 1073
Examples 1073
Examples 1083
Remarks 1084
Examples 1084
Introduction 1088
Examples 1088
Syntax 1093
Examples 1093
Introduction 1096
Remarks 1096
Examples 1096
Introduction 1100
Remarks 1100
Examples 1100
Syntax 1103
Examples 1103
Introduction 1106
Examples 1106
Performing Asynchronous Tasks Where No Return Value Is Needed Using a Runnable Class Insta 1106
Performing Asynchronous Tasks Where a Return Value Is Needed Using a Callable Class Instan 1108
Remarks 1113
Examples 1113
Syntax 1115
Remarks 1115
Examples 1116
Introduction 1119
Examples 1119
Introduction 1121
Syntax 1121
Parameters 1121
Remarks 1121
Examples 1121
package-info.java 1124
Remarks 1125
Examples 1126
Remarks 1130
Examples 1130
Examples 1133
Credits 1139
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: java-language
It is an unofficial and free Java Language ebook created for educational purposes. All the content
is extracted from Stack Overflow Documentation, which is written by many hardworking individuals
at Stack Overflow. It is neither affiliated with Stack Overflow nor official Java Language.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/ 1
Chapter 1: Getting started with Java
Language
Remarks
The Java programming language is...
• Class-based: Its object structure is defined in classes. Class instances always have those
fields and methods specified in their class definitions (see Classes and Objects). This is in
contrast to non-class-based languages such as JavaScript.
• Statically-typed: the compiler checks at compile time that variable types are respected. For
example, if a method expects an argument of type String, that argument must in fact be a
string when the method is called.
• Object-oriented: most things in a Java program are class instances, i.e. bundles of state
(fields) and behavior (methods which operate on data and form the object's interface to the
outside world).
• Portable: It can be compiled on any platform with javac and the resultant class files can run
on any platform that has a JVM.
Java is intended to let application developers "write once, run anywhere" (WORA), meaning that
compiled Java code can run on all platforms that support Java without the need for recompilation.
Java code is compiled to bytecode (the .class files) which in turn get interpreted by the Java
Virtual Machine (JVM). In theory, bytecode created by one Java compiler should run the same
way on any JVM, even on a different kind of computer. The JVM might (and in real-world
programs will) choose to compile into native machine commands the parts of the bytecode that are
executed often. This is called "Just-in-time (JIT) compilation".
• Java Standard Edition (SE) is the edition that is designed for general use.
• Java Enterprise Edition (EE) adds a range of facilities for building "enterprise grade" services
in Java. Java EE is covered separately.
• Java Micro Edition (ME) is based on a subset of Java SE and is intended for use on small
devices with limited resources.
https://riptutorial.com/ 2
Each edition has multiple versions. The Java SE versions are listed below.
Installing Java
There is a separate topic on Installing Java (Standard Edition).
What's next?
Here are links to subjects to continue learning and understanding the Java programming
language. These subjects are the basics of the Java programming to get you started.
Testing
While Java does not have any support for testing in the standard library, there are 3rd-party
libraries that are designed to support testing. The two most popular unit testing libraries are:
Other
• Design patterns for Java are covered in Design Patterns.
• Programming for Android is covered in Android.
• Java Enterprise Edition technologies are covered in Java EE.
• The Oracle JavaFX technologies are covered in JavaFX.
https://riptutorial.com/ 3
1. In Versions section the end-of-life (free) date is when Oracle will stop posting further updates of Java SE to its
public download sites. Customers who need continued access to critical bug fixes and security fixes as well as general
maintenance for Java SE can get long term support through Oracle Java SE Support.
Versions
Examples
Creating Your First Java Program
Create a new file in your text editor or IDE named HelloWorld.java. Then paste this code block into
the file and save:
Note: For Java to recognize this as a public class (and not throw a compile time error), the
filename must be the same as the class name (HelloWorld in this example) with a .java extension.
There should also be a public access modifier before it.
Naming conventions recommend that Java classes begin with an uppercase character, and be in
camel case format (in which the first letter of each word is capitalized). The conventions
https://riptutorial.com/ 4
recommend against underscores (_) and dollar signs ($).
cd /path/to/containing/folder/
$ javac HelloWorld.java
It's fairly common to get the error 'javac' is not recognized as an internal or external command,
operable program or batch file. even when you have installed the JDK and are able to run the
program from IDE ex. eclipse etc. Since the path is not added to the environment by default.
In case you get this on windows, to resolve, first try browsing to your javac.exe path, it's most
probably in your C:\Program Files\Java\jdk(version number)\bin. Then try running it with below.
Previously when we were calling javac it was same as above command. Only in that case your OS
knew where javac resided. So let's tell it now, this way you don't have to type the whole path
every-time. We would need to add this to our PATH
You cannot undo this so be careful. First copy your existing path to notepad. Then to get the
exact PATH to your javac browse manually to the folder where javac resides and click on the
address bar and then copy it. It should look something like c:\Program Files\Java\jdk1.8.0_xx\bin
In "Variable value" field, paste this IN FRONT of all the existing directories, followed by a semi-
colon (;). DO NOT DELETE any existing entries.
The compiler will then generate a bytecode file called HelloWorld.class which can be executed in
the Java Virtual Machine (JVM). The Java programming language compiler, javac, reads source
https://riptutorial.com/ 5
files written in the Java programming language and compiles them into bytecode class files.
Optionally, the compiler can also process annotations found in source and class files using the
Pluggable Annotation Processing API. The compiler is a command line tool but can also be invoked
using the Java Compiler API.
To run your program, enter java followed by the name of the class which contains the main method
(HelloWorld in our example). Note how the .class is omitted:
$ java HelloWorld
Hello, World!
You have successfully coded and built your very first Java program!
Note: In order for Java commands (java, javac, etc) to be recognized, you will need to make sure:
You will need to use a compiler (javac) and an executor (java) provided by your JVM. To find out
which versions you have installed, enter java -version and javac -version on the command line.
The version number of your program will be printed in the terminal (e.g. 1.8.0_73).
The class keyword begins the class definition for a class named HelloWorld. Every Java application
contains at least one class definition (Further information about classes).
This is an entry point method (defined by its name and signature of public static void
main(String[])) from which the JVM can run your program. Every Java program should have one. It
is:
• public:
meaning that the method can be called from anywhere mean from outside the
program as well. See Visibility for more information on this.
• static: meaning it exists and can be run by itself (at the class level without creating an
https://riptutorial.com/ 6
object).
• void: meaning it returns no value. Note: This is unlike C and C++ where a return code such
as int is expected (Java's way is System.exit()).
• An array (typically called args) of Strings passed as arguments to main function (e.g. from
command line arguments).
Non-required parts:
• The name args is a variable name, so it can be called anything you want, although it is
typically called args.
• Whether its parameter type is an array (String[] args) or Varargs (String... args) does not
matter because arrays can be passed into varargs.
Note: A single application may have multiple classes containing an entry point (main) method. The
entry point of the application is determined by the class name passed as an argument to the java
command.
System.out.println("Hello, World!");
Element Purpose
this denotes that the subsequent expression will call upon the System class, from
System
the java.lang package.
this is a "dot operator". Dot operators provide you access to a classes members
. 1; i.e. its fields (variables) and its methods. In this case, this dot operator allows
you to reference the out static field within the System class.
this is the name of the static field of PrintStream type within the System class
out
containing the standard output functionality.
this is another dot operator. This dot operator provides access to the println
.
method within the out variable.
this is the name of a method within the PrintStream class. This method in
println particular prints the contents of the parameters into the console and inserts a
newline after.
this parenthesis indicates that a method is being accessed (and not a field) and
(
begins the parameters being passed into the println method.
https://riptutorial.com/ 7
Element Purpose
"Hello, this is the String literal that is passed as a parameter, into the println method.
World!" The double quotation marks on each end delimit the text as a String.
this parenthesis signifies the closure of the parameters being passed into the
)
println method.
Here's another example demonstrating the OO paradigm. Let's model a football team with one
(yes, one!) member. There can be more, but we'll discuss that when we get to arrays.
class Member {
private String name;
private String type;
private int level; // note the data type here
private int rank; // note the data type here as well
Why do we use private here? Well, if someone wanted to know your name, they should ask you
directly, instead of reaching into your pocket and pulling out your Social Security card. This private
does something like that: it prevents outside entities from accessing your variables. You can only
return private members through getter functions (shown below).
After putting it all together, and adding the getters and main method as discussed before, we
have:
https://riptutorial.com/ 8
public class Team {
Member member;
public Team(Member member) {
this.member = member;
}
class Member {
private String name;
private String type;
private int level;
private int rank;
Output:
Aurieel
light
10
1
Run on ideone
Once again, the main method inside the Test class is the entry point to our program. Without the
main method, we cannot tell the Java Virtual Machine (JVM) from where to begin execution of the
https://riptutorial.com/ 9
program.
1 - Because the HelloWorld class has little relation to the System class, it can only access public data.
https://riptutorial.com/ 10
Chapter 2: 2D Graphics in Java
Introduction
Graphics are visual images or designs on some surface, such as a wall, canvas, screen, paper, or
stone to inform, illustrate, or entertain. It includes: pictorial representation of data, as in computer-
aided design and manufacture, in typesetting and the graphic arts, and in educational and
recreational software. Images that are generated by a computer are called computer graphics.
The Java 2D API is powerful and complex. There are multiple ways to do 2D graphics in Java.
Examples
Example 1: Draw and Fill a Rectangle Using Java
This is an Example which print rectangle and fill color in the rectangle.
https://i.stack.imgur.com/dlC5v.jpg
Most methods of the Graphics class can be divided into two basic groups:
1. Draw and fill methods, enabling you to render basic shapes, text, and images
2. Attributes setting methods, which affect how that drawing and filling appears
Code Example: Let us start this with a little example of drawing a rectangle and filling color in it.
There we declare two classes, one class is MyPanel and other Class is Test. In class MyPanel we
use drawRect( ) & fillRect( ) mathods to draw rectangle and fill Color in it. We set the color by
setColor(Color.blue) method. In Second Class we Test our graphic which is Test Class we make a
https://riptutorial.com/ 11
Frame and put MyPanel with p=new MyPanel() object in it.By running Test Class we see a
Rectangle and a Blue Color Filled Rectangle.
import javax.swing.*;
import java.awt.*;
// MyPanel extends JPanel, which will eventually be placed in a JFrame
public class MyPanel extends JPanel {
// custom painting is performed by the paintComponent method
@Override
public void paintComponent(Graphics g){
// clear the previous painting
super.paintComponent(g);
// cast Graphics to Graphics2D
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red); // sets Graphics2D color
// draw the rectangle
g2.drawRect(0,0,100,100); // drawRect(x-position, y-position, width, height)
g2.setColor(Color.blue);
g2.fillRect(200,0,100,100); // fill new rectangle with color blue
}
}
import javax.swing.;
import java.awt.;
public class Test { //the Class by which we display our rectangle
JFrame f;
MyPanel p;
public Test(){
f = new JFrame();
// get the content area of Panel.
Container c = f.getContentPane();
// set the LayoutManager
c.setLayout(new BorderLayout());
p = new MyPanel();
// add MyPanel object into container
c.add(p);
// set the size of the JFrame
f.setSize(400,400);
// make the JFrame visible
f.setVisible(true);
// sets close behavior; EXIT_ON_CLOSE invokes System.exit(0) on closing the JFrame
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
paintComponent( )
https://riptutorial.com/ 12
• It is a main method for painting
• By default, it first paints the background
• After that, it performs custom painting (drawing circle, rectangles etc.)
Note: The Java 2D API enables you to easily perform the following tasks:
import javax.swing.*;
import java.awt.*;
g2.fillOval(int x,int y,int height, int width); This method will fill an oval at specified x and y
position with given height and width.
https://riptutorial.com/ 13
Chapter 3: Alternative Collections
Remarks
This topic about Java collections from guava, apache, eclipse: Multiset, Bag, Multimap, utils
function from this lib and so on.
Examples
Apache HashBag, Guava HashMultiset and Eclipse HashBag
A Bag/ultiset stores each object in the collection together with a count of occurrences. Extra
methods on the interface allow multiple copies of an object to be added or removed at once. JDK
analog is HashMap<T, Integer>, when values is count of copies this key.
Apache Commons
Type Guava GS Collections JDK
Collections
Order not
HashMultiset HashBag HashBag HashMap
defined
Insertion-
LinkedHashMultiset - - LinkedHa
order
Concurrent
ConcurrentHashMultiset SynchronizedBag SynchronizedBag Collection
variant
Concurrent
- SynchronizedSortedBag SynchronizedSortedBag Collection
and sorted
Immutable
ImmutableMultiset UnmodifiableBag UnmodifiableBag Collection
collection
Immutable Collection
ImmutableSortedMultiset UnmodifiableSortedBag UnmodifiableSortedBag )
and sorted
Examples:
https://riptutorial.com/ 14
TreeBag(Arrays.asList(INPUT_TEXT.split(" "))));
https://riptutorial.com/ 15
// Print count words
System.out.println(multiset); // print [Hello x 2, World! x 2, All!, Hi]- in predictable
iteration order
// Print all unique words
System.out.println(multiset.elementSet()); // print [Hello, World!, All!, Hi] - in
predictable iteration order
More examples:
I. Apache Collection:
III. Guava
This multimap allows duplicate key-value pairs. JDK analogs are HashMap<K, List>, HashMap<K,
Set> and so on.
Key's Value's
Duplicate Analog key Analog value Guava Apache
order order
not Insertion-
yes HashMap ArrayList ArrayListMultimap MultiVal
defined order
https://riptutorial.com/ 16
Key's Value's
Duplicate Analog key Analog value Guava Apache
order order
MultiVal
not not multiVal
no HashMap HashSet HashMultimap HashMap<
defined defined
HashSet.
Multimaps.
not MultiVal
newMultimap(
sorted no HashMap TreeSet HashMap, Supplier
new Hash
defined TreeSet.
<TreeSet>)
MultiVal
Insertion- Insertion- multiVal
yes LinkedHashMap ArrayList LinkedListMultimap
order order LinkedH
ArrayLis
MultiVal
Insertion- Insertion- multiVal
no LinkedHashMap LinkedHashSet LinkedHashMultimap LinkedHa
order order
LinkedHa
MultiVal
multiVal
sorted sorted no TreeMap TreeSet TreeMultimap TreeMap<
Set>(),T
Task: Parse "Hello World! Hello All! Hi World!" string to separate words and print all indexes of
every word using MultiMap (for example, Hello=[0, 2], World!=[1, 5] and so on)
// Fill Multimap
int i = 0;
for(String word: words) {
multiMap.put(word, i);
i++;
}
https://riptutorial.com/ 17
System.out.println("Hi = " + multiMap.get("Hi")); // print [4]
System.out.println("Empty = " + multiMap.get("Empty")); // print null
// Create Multiset
MutableBiMap<String, String> biMap = new HashBiMap(englishWords.length);
// Create English-Polish dictionary
int i = 0;
for(String englishWord: englishWords) {
biMap.put(englishWord, russianWords[i]);
i++;
}
// Fill Multimap
int i = 0;
for(String word: words) {
multiMap.put(word, i);
i++;
}
https://riptutorial.com/ 18
System.out.println(multiMap.keySet()); // print [Hi, Hello, World!, All!] - in random
orders
Nore examples:
I. Apache Collection:
1. MultiValueMap
2. MultiValueMapLinked
3. MultiValueMapTree
1. FastListMultimap
2. HashBagMultimap
3. TreeSortedSetMultimap
4. UnifiedSetMultimap
III. Guava
1. HashMultiMap
2. LinkedHashMultimap
3. LinkedListMultimap
4. TreeMultimap
5. ArrayListMultimap
1. Create List
Description JDK guava gs-collections
Create
new ArrayList<>() Lists.newArrayList() FastList.newList()
empty list
https://riptutorial.com/ 19
Description JDK guava gs-collections
from values
Create list
with
new ArrayList<>(100) Lists.newArrayListWithCapacity(100) FastList.newList(100)
capacity =
100
Create list
new
from any ArrayList<>(collection)
Lists.newArrayList(collection) FastList.newList(collecti
collectin
Create list
from any - Lists.newArrayList(iterable) FastList.newList(iterable
Iterable
Create list
- Lists.newArrayList(iterator) -
from Iterator
Create list
Arrays.asList(array) Lists.newArrayList(array) FastList.newListWith(arra
from array
Create list
FastList.newWithNValues(1
using - - () -> "1")
factory
Examples:
System.out.println("createArrayList start");
// Create empty list
List<String> emptyGuava = Lists.newArrayList(); // using guava
List<String> emptyJDK = new ArrayList<>(); // using JDK
MutableList<String> emptyGS = FastList.newList(); // using gs
System.out.println(withElements);
System.out.println(withElementsJDK);
System.out.println(withElementsGS);
https://riptutorial.com/ 20
// Create list from any Iterable interface (any collection)
Collection<String> collection = new HashSet<>(3);
collection.add("1");
collection.add("2");
collection.add("3");
System.out.println(fromIterable);
System.out.println(fromIterableJDK);
System.out.println(fromIterableGS);
/* Attention: JDK create list only from Collection, but guava and gs can create list from
Iterable and Collection */
System.out.println("createArrayList end");
2 Create Set
Description JDK guava gs-collections
Create
new HashSet<>() Sets.newHashSet() UnifiedSet.newSet()
empty set
new
Creatre set HashSet<>(Arrays.asList("alpha", Sets.newHashSet("alpha", UnifiedSet.newSetWith("a
from values "beta", "gamma") "beta", "gamma")
"beta", "gamma"))
Create set
from any new HashSet<>(collection) Sets.newHashSet(collection) UnifiedSet.newSet(collec
collections
Create set
from any - Sets.newHashSet(iterable) UnifiedSet.newSet(iterab
Iterable
https://riptutorial.com/ 21
Description JDK guava gs-collections
from any
Iterator
Examples:
System.out.println("createHashSet start");
// Create empty set
Set<String> emptyGuava = Sets.newHashSet(); // using guava
Set<String> emptyJDK = new HashSet<>(); // using JDK
Set<String> emptyGS = UnifiedSet.newSet(); // using gs
System.out.println(withElements);
System.out.println(withElementsJDK);
System.out.println(withElementsGS);
System.out.println(fromIterable);
System.out.println(fromIterableJDK);
System.out.println(fromIterableGS);
/* Attention: JDK create set only from Collection, but guava and gs can create set from
Iterable and Collection */
https://riptutorial.com/ 22
System.out.println(fromArrayGS);
System.out.println("createHashSet end");
3 Create Map
Description JDK guava gs-collections
Create new
Maps.newHashMap() UnifiedMap.newMap()
empty map HashMap<>()
Create map
with new
Maps.newHashMapWithExpectedSize(100) UnifiedMap.newMap(130)
capacity = HashMap<>(130)
130
Create map
new
from other HashMap<>(map)
Maps.newHashMap(map) UnifiedMap.newMap(map)
map
Examples:
System.out.println("createHashMap start");
// Create empty map
Map<String, String> emptyGuava = Maps.newHashMap(); // using guava
Map<String, String> emptyJDK = new HashMap<>(); // using JDK
Map<String, String> emptyGS = UnifiedMap.newMap(); // using gs
System.out.println(withMap);
System.out.println(withMapJDK);
System.out.println(withMapGS);
System.out.println("createHashMap end");
https://riptutorial.com/ 23
1. CollectionCompare
2. CollectionSearch
3. JavaTransform
https://riptutorial.com/ 24
Chapter 4: Annotations
Introduction
In Java, an annotation is a form of syntactic metadata that can be added to Java source code. It
provides data about a program that is not part of the program itself. Annotations have no direct
effect on the operation of the code they annotate. Classes, methods, variables, parameters and
packages are allowed to be annotated.
Syntax
• @AnnotationName // 'Marker annotation' (no parameters)
• @AnnotationName(someValue) // sets parameter with the name 'value'
• @AnnotationName(param1 = value1) // named parameter
• @AnnotationName(param1 = value1, param2 = value2) // multiple named parameters
• @AnnotationName(param1 = {1, 2, 3}) // named array parameter
• @AnnotationName({value1}) // array with single element as parameter with the name 'value'
Remarks
Parameter types
Only constant expressions of following types are allowed for parameters, as well as arrays of
these types:
• String
• Class
• primitive types
• Enum types
• Annotation Types
Examples
Built-in annotations
The Standard Edition of Java comes with some annotations predefined. You do not need to define
them by yourself and you can use them immediately. They allow the compiler to enable some
fundamental checking of methods, classes and code.
@Override
This annotation applies to a method and says that this method must override a superclass' method
or implement an abstract superclass' method definition. If this annotation is used with any other
https://riptutorial.com/ 25
kind of method, the compiler will throw an error.
Concrete superclass
Abstract class
class Logger1 {
public void log(String logString) {
System.out.prinln(logString);
}
}
class Logger2 {
// This will throw compile-time error. Logger2 is not a subclass of Logger1.
// log method is not overriding anything
@Override
public void log(String logString) {
System.out.println("Log 2" + logString);
}
}
The main purpose is to catch mistyping, where you think you are overriding a method, but are
actually defining a new one.
class Vehicle {
public void drive() {
System.out.println("I am driving");
}
https://riptutorial.com/ 26
}
• In Java 5, it meant that the annotated method had to override a non-abstract method
declared in the superclass chain.
• From Java 6 onward, it is also satisfied if the annotated method implements an abstract
method declared in the classes superclass / interface hierarchy.
(This can occasionally cause problems when back-porting code to Java 5.)
@Deprecated
This marks the method as deprecated. There can be several reasons for this:
The specific reason for deprecation can usually be found in the documentation of the API.
The annotation will cause the compiler to emit an error if you use it. IDEs may also highlight this
method somehow as deprecated
class ComplexAlgorithm {
@Deprecated
public void oldSlowUnthreadSafeMethod() {
// stuff here
}
@SuppressWarnings
https://riptutorial.com/ 27
In almost all cases, when the compiler emits a warning, the most appropriate action is to fix the
cause. In some instances (Generics code using untype-safe pre-generics code, for example) this
may not be possible and it's better to suppress those warnings that you expect and cannot fix, so
you can more clearly see unexpected warnings.
This annotation can be applied to a whole class, method or line. It takes the category of warning
as a parameter.
@SuppressWarnings("deprecation")
public class RiddledWithWarnings {
// several methods calling deprecated code here
}
@SuppressWarning("finally")
public boolean checkData() {
// method calling return from within finally block
}
It is better to limit the scope of the annotation as much as possible, to prevent unexpected
warnings also being suppressed. For example, confining the scope of the annotation to a single-
line:
The warnings supported by this annotation may vary from compiler to compiler. Only the unchecked
and deprecation warnings are specifically mentioned in the JLS. Unrecognized warning types will
be ignored.
@SafeVarargs
Because of type erasure, void method(T... t) will be converted to void method(Object[] t) meaning
that the compiler is not always able to verify that the use of varargs is type-safe. For instance:
There are instances where the use is safe, in which case you can annotate the method with the
SafeVarargs annotation to suppress the warning. This obviously hides the warning if your use is
unsafe too.
@FunctionalInterface
This is an optional annotation used to mark a FunctionalInterface. It will cause the compiler to
complain if it does not conform to the FunctionalInterface spec (has a single abstract method)
@FunctionalInterface
public interface ITrade {
https://riptutorial.com/ 28
public boolean check(Trade t);
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
Java's Reflection API allows the programmer to perform various checks and operations on class
fields, methods and annotations during runtime. However, in order for an annotation to be at all
visible at runtime, the RetentionPolicy must be changed to RUNTIME, as demonstrated in the
example below:
@interface MyDefaultAnnotation {
@Retention(RetentionPolicy.RUNTIME)
@interface MyRuntimeVisibleAnnotation {
@MyDefaultAnnotation
static class RuntimeCheck1 {
}
@MyRuntimeVisibleAnnotation
static class RuntimeCheck2 {
}
Annotation types are defined with @interface. Parameters are defined similar to methods of a
regular interface.
@interface MyAnnotation {
String param1();
boolean param2();
int[] param3(); // array parameter
}
https://riptutorial.com/ 29
Default values
@interface MyAnnotation {
String param1() default "someValue";
boolean param2() default true;
int[] param3() default {};
}
Meta-Annotations
Meta-annotations are annotations that can be applied to annotation types. Special predefined
meta-annotation define how annotation types can be used.
@Target
The @Target meta-annotation restricts the types the annotation can be applied to.
@Target(ElementType.METHOD)
@interface MyAnnotation {
// this annotation can only be applied to methods
}
Available Values
@Retention(RetentionPolicy.RUNTIME)
ANNOTATION_TYPE annotation types @interface MyAnnotation
@MyAnnotation
CONSTRUCTOR constructors public MyClass() {}
@XmlAttribute
FIELD fields, enum constants private int count;
https://riptutorial.com/ 30
ElementType target example usage on target element
@XmlElement
METHOD methods public int getCount() {...}
public Rectangle(
@NamedArg("width") double
width,
method/constructor
PARAMETER @NamedArg("height") double
parameters height) {
...
}
Java SE 8
ElementType target example usage on target element
Object o = "42";
TYPE_USE Use of a type String s = (@MyAnnotation String) o;
@Retention
The @Retention meta-annotation defines the annotation visibility during the applications compilation
process or execution. By default, annotations are included in .class files, but are not visible at
runtime. To make an annotation accessible at runtime, RetentionPolicy.RUNTIME has to be set on
that annotation.
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
https://riptutorial.com/ 31
// this annotation can be accessed with reflections at runtime
}
Available values
RetentionPolicy Effect
CLASS The annotation is available in the .class file, but not at runtime
RUNTIME The annotation is available at runtime and can be accessed via reflection
The annotation is available at compile time, but not added to the .class
SOURCE
files. The annotation can be used e.g. by an annotation processor.
@Documented
The @Documented meta-annotation is used to mark annotations whose usage should be documented
by API documentation generators like javadoc. It has no values. With @Documented, all classes that
use the annotation will list it on their generated documentation page. Without @Documented, it's not
possible to see which classes use the annotation in the documentation.
@Inherited
The @Inherited meta-annotation is relevant to annotations that are applied to classes. It has no
values. Marking an annotation as @Inherited alters the way that annotation querying works.
• For a non-inherited annotation, the query only examines the class being examined.
• For an inherited annotation, the query will also check the super-class chain (recursively) until
an instance of the annotation is found.
Note that only the super-classes are queried: any annotations attached to interfaces in the classes
hierarchy will be ignored.
@Repeatable
The @Repeatable meta-annotation was added in Java 8. It indicates that multiple instances of the
annotation can be attached to the annotation's target. This meta-annotation has no values.
You can fetch the current properties of the Annotation by using Reflection to fetch the Method or
Field or Class which has an Annotation applied to it, and then fetching the desired properties.
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String key() default "foo";
https://riptutorial.com/ 32
String value() default "bar";
}
class AnnotationExample {
// Put the Annotation on the method, but leave the defaults
@MyAnnotation
public void testDefaults() throws Exception {
// Using reflection, get the public method "testDefaults", which is this method with
no args
Method method = AnnotationExample.class.getMethod("testDefaults", null);
foo = bar
baz = buzz
Repeating Annotations
https://riptutorial.com/ 33
Until Java 8, two instances of the same annotation could not be applied to a single element. The
standard workaround was to use a container annotation holding an array of some other
annotation:
// Author.java
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
String value();
}
// Authors.java
@Retention(RetentionPolicy.RUNTIME)
public @interface Authors {
Author[] value();
}
// Test.java
@Authors({
@Author("Mary"),
@Author("Sam")
})
public class Test {
public static void main(String[] args) {
Author[] authors = Test.class.getAnnotation(Authors.class).value();
for (Author author : authors) {
System.out.println(author.value());
// Output:
// Mary
// Sam
}
}
}
Java SE 8
Java 8 provides a cleaner, more transparent way of using container annotations, using the
@Repeatable annotation. First we add this to the Author class:
@Repeatable(Authors.class)
This tells Java to treat multiple @Author annotations as though they were surrounded by the
@Authors container. We can also use Class.getAnnotationsByType() to access the @Author array by its
own class, instead of through its container:
@Author("Mary")
@Author("Sam")
public class Test {
public static void main(String[] args) {
Author[] authors = Test.class.getAnnotationsByType(Author.class);
for (Author author : authors) {
System.out.println(author.value());
// Output:
// Mary
// Sam
}
}
https://riptutorial.com/ 34
}
Inherited Annotations
By default class annotations do not apply to types extending them. This can be changed by adding
the @Inherited annotation to the annotation definition
Example
Consider the following 2 Annotations:
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InheritedAnnotationType {
}
and
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface UninheritedAnnotationType {
}
@UninheritedAnnotationType
class A {
}
@InheritedAnnotationType
class B extends A {
}
class C extends B {
}
System.out.println(new A().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println(new B().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println(new C().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println("_________________________________");
System.out.println(new A().getClass().getAnnotation(UninheritedAnnotationType.class));
System.out.println(new B().getClass().getAnnotation(UninheritedAnnotationType.class));
System.out.println(new C().getClass().getAnnotation(UninheritedAnnotationType.class));
will print a result similar to this (depending on the packages of the annotation):
null
@InheritedAnnotationType()
@InheritedAnnotationType()
https://riptutorial.com/ 35
_________________________________
@UninheritedAnnotationType()
null
null
Note that annotations can only be inherited from classes, not interfaces.
The annotation
The @Setter annotation is a marker can be applied to methods. The annotation will be discarded
during compilation not be available afterwards.
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface Setter {
}
package annotation.processor;
import annotation.Setter;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
https://riptutorial.com/ 36
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes({"annotation.Setter"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class SetterProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
{
// get elements annotated with the @Setter annotation
Set<? extends Element> annotatedElements =
roundEnv.getElementsAnnotatedWith(Setter.class);
@Override
public void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
https://riptutorial.com/ 37
// get messager for printing errors
messager = processingEnvironment.getMessager();
}
Packaging
To be applied by the compiler, the annotation processor needs to be made available to the SPI
(see ServiceLoader).
annotation.processor.SetterProcessor
import annotation.Setter;
@Setter
private void setValue(String value) {}
@Setter
public void setString(String value) {}
@Setter
public static void main(String[] args) {}
https://riptutorial.com/ 38
yields the following output
This could be prevented by specifying the -proc:none option for javac. You could also forgo the
usual compilation by specifying -proc:only instead.
IDE integration
Netbeans
Annotation processors can be used in the NetBeans editor. To do this the annotation processor
needs to be specified in the project settings:
2. add check marks for Enable Annotation Processing and Enable Annotation Processing in
Editor
4. in the popup that appears enter the fully qualified class name of the annotation processor
and click Ok.
Result
https://riptutorial.com/ 39
The idea behind Annotations
Annotations may appear before types or declarations. It is possible for them to appear in a place
where they could apply to both a type or a declaration.
What exactly an annotation applies to is governed by the "meta-annotation" @Target. See "Defining
annotation types" for more information.
Annotations are used for a multitude of purposes. Frameworks like Spring and Spring-MVC make
use of annotations to define where Dependencies should be injected or where requests should be
routed.
Other frameworks use annotations for code-generation. Lombok and JPA are prime examples,
that use annotations to generate Java (and SQL) code.
When Java annotations were first introduced there was no provision for annotating the target of an
instance method or the hidden constructor parameter for an inner classes constructor. This was
remedied in Java 8 with addition of receiver parameter declarations; see JLS 8.4.1.
The following example illustrates the syntax for both kinds of receiver parameter:
https://riptutorial.com/ 40
// ...
}
public void doIt(Inner this) {
// ...
}
}
}
The sole purpose of receiver parameters is to allow you to add annotations. For example, you
might have a custom annotation @IsOpen whose purpose is to assert that a Closeable object has not
been closed when a method is called. For example:
At one level, the @IsOpen annotation on this could simply serve as documentation. However, we
could potentially do more. For example:
• An annotation processor could insert a runtime check that this is not in closed state when
update is called.
• A code checker could perform a static code analysis to find cases where this could be
closed when update is called.
An Annotation parameter can accept multiple values if it is defined as an array. For example the
standard annotation @SuppressWarnings is defined like this:
The value parameter is an array of Strings. You can set multiple values by using a notation similar
to Array initializers:
@SuppressWarnings({"unused"})
@SuppressWarnings({"unused", "javadoc"})
If you only need to set a single value, the brackets can be omitted:
@SuppressWarnings("unused")
https://riptutorial.com/ 41
Chapter 5: Apache Commons Lang
Examples
Implement equals() method
To implement the equals method of an object easily you could use the EqualsBuilder class.
@Override
public boolean equals(Object obj) {
return builder.isEquals();
}
Using reflection:
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj, false);
}
the boolean parameter is to indicates if the equals should check transient fields.
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj, "field1", "field2");
}
To implement the hashCode method of an object easily you could use the HashCodeBuilder class.
@Override
public int hashCode() {
https://riptutorial.com/ 42
HashCodeBuilder builder = new HashCodeBuilder();
builder.append(field1);
builder.append(field2);
builder.append(field3);
return builder.hashCode();
}
Using reflection:
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, false);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, "field1", "field2");
}
To implement the toString method of an object easily you could use the ToStringBuilder class.
@Override
public String toString() {
return builder.toString();
}
Example result:
ar.com.jonat.lang.MyClass@dd7123[<null>,0,false]
@Override
public String toString() {
https://riptutorial.com/ 43
builder.append("field2",field2);
builder.append("field3",field3);
return builder.toString();
}
Example result:
ar.com.jonat.lang.MyClass@dd7404[field1=<null>,field2=0,field3=false]
@Override
public String toString() {
return builder.toString();
}
Example result:
ar.com.bna.lang.MyClass@ebbf5c[
field1=<null>
field2=0
field3=false
]
There are some styles, for example JSON, no Classname, short, etc ...
Via reflection:
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
https://riptutorial.com/ 44
Chapter 6: AppDynamics and TIBCO
BusinessWorks Instrumentation for Easy
Integration
Introduction
As AppDynamics aims to provide a way to measure application performance, speed of
development, delivery (deployment) of applications is an essential factor in making DevOps efforts
a true success. Monitoring a TIBCO BW application with AppD is generally simple and not time
consuming but when deploying large sets of applications rapid instrumentation is key. This guide
shows how to instrument all of your BW applications in a single step without modifying each
application before deploying.
Examples
Example of Instrumentation of all BW Applications in a Single Step for
Appdynamics
4. Go to the end of the file and add (replace ? with your own values as needed or remove the
flag that does not apply): java.extended.properties=-
javaagent:/opt/appd/current/appagent/javaagent.jar -Dappdynamics.http.proxyHost=? -
Dappdynamics.http.proxyPort=? -Dappdynamics.agent.applicationName=? -
Dappdynamics.agent.tierName=? -Dappdynamics.agent.nodeName=%tibco.deployment% -
Dappdynamics.controller.ssl.enabled=? -Dappdynamics.controller.sslPort=? -
Dappdynamics.agent.logs.dir=? -Dappdynamics.agent.runtime.dir=? -
Dappdynamics.controller.hostName=? -Dappdynamics.controller.port=? -
Dappdynamics.agent.accountName=? -Dappdynamics.agent.accountAccessKey=?
5. Save file and redeploy. All your applications should now be instrumented automatically at
deployment time.
Read AppDynamics and TIBCO BusinessWorks Instrumentation for Easy Integration online:
https://riptutorial.com/java/topic/10602/appdynamics-and-tibco-businessworks-instrumentation-for-
https://riptutorial.com/ 45
easy-integration
https://riptutorial.com/ 46
Chapter 7: Applets
Introduction
Applets have been part of Java since its official release and have been used to teach Java and
programming for a number of years.
Recent years have seen an active push to move away from Applets and other browser plugins,
with some browsers blocking them or actively not supporting them.
In 2016, Oracle announced their plans to deprecate the plugin, Moving to a Plugin-Free Web
Remarks
An applet is a Java application that normally runs inside a web browser. The basic idea is to
interact with the user without the need to interact with the server and transfer information. This
concept was very successful around the year 2000 when internet communication was slow and
expensive.
destroy() is called once when the applet gets removed from memory
Examples
Minimal Applet
A very simple applet draws a rectangle and prints a string something on the screen.
@Override
https://riptutorial.com/ 47
public void init() {
setBackground(Color.gray);
}
@Override
public void destroy() {}
@Override
public void start() {}
@Override
public void stop() {}
@Override
public void paint(Graphics g) {
g.setColor(Color.yellow);
g.fillRect(1,1,300,150);
g.setColor(Color.red);
g.setFont(new Font("TimesRoman", Font.PLAIN, 48));
g.drawString(str, 10, 80);
}
}
Java SE 1.2
Before Java 1.2 and the introduction of the swing API applets had extended from
java.applet.Applet.
Applets don't require a main method. The entry point is controlled by the life cycle. To use them,
they need to be embedded in a HTML document. This is also the point where their size is defined.
<html>
<head></head>
<body>
<applet code="MyApplet.class" width="400" height="200"></applet>
</body>
</html>
Creating a GUI
Applets could easily be used to create a GUI. They act like a Container and have an add() method
that takes any awt or swing component.
@Override
public void init(){
panel = new JPanel();
button = new JButton("ClickMe!");
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent ae) {
if(((String)cmbBox.getSelectedItem()).equals("greet")) {
https://riptutorial.com/ 48
JOptionPane.showMessageDialog(null,"Hello " + textField.getText());
} else {
JOptionPane.showMessageDialog(null,textField.getText() + " stinks!");
}
}
});
cmbBox = new JComboBox<>(new String[]{"greet", "offend"});
textField = new JTextField("John Doe");
panel.add(cmbBox);
panel.add(textField);
panel.add(button);
add(panel);
}
}
You can use the method getAppletContext() to get an AppletContext object that allows you to
request the browser to open a link. For this you use the method showDocument(). Its second
parameter tells the browser to use a new window _blank or the one that shows the applet _self.
Java applets are able to load different resources. But since they are running in the web browser of
the client you need to make sure that these resources are accessible. Applets are not able to
access client resources as the local file system.
If you want to load resources from the same URL the Applet is stored you can use the method
getCodeBase() to retrieve the base URL. To load resources, applets offer the methods getImage()
and getAudioClip() to load images or audio files.
https://riptutorial.com/ 49
public class MyImgApplet extends JApplet{
@Override
public void init(){
try {
img = getImage(new URL("http://cdn.sstatic.net/stackexchange/img/logos/so/so-
logo.png"));
} catch (MalformedURLException e) { /* omitted for brevity */ }
}
@Override
public void paint(Graphics g) {
g.drawImage(img, 0, 0, this);
}
}
@Override
public void init(){
try {
audioClip = getAudioClip(new URL("URL/TO/AN/AUDIO/FILE.WAV"));
} catch (MalformedURLException e) { /* omitted for brevity */ }
}
@Override
public void start() {
audioClip.play();
}
@Override
public void stop(){
audioClip.stop();
}
}
https://riptutorial.com/ 50
String line = "";
while((line = bf.readLine()) != null) {
textArea.append(line + "\n");
}
} catch(Exception e) { /* omitted for brevity */ }
}
}
https://riptutorial.com/ 51
Chapter 8: Arrays
Introduction
Arrays allow for the storage and retrieval of an arbitrary quantity of values. They are analogous to
vectors in mathematics. Arrays of arrays are analogous to matrices, and act as multidimensional
arrays. Arrays can store any data of any type: primitives such as int or reference types such as
Object.
Syntax
• ArrayType[] myArray; // Declaring arrays
• ArrayType myArray[]; // Another valid syntax (less commonly used and discouraged)
• ArrayType[][][] myArray; // Declaring multi-dimensional jagged arrays (repeat []s)
• ArrayType myVar = myArray[index]; // Accessing (reading) element at index
• myArray[index] = value; // Assign value to position index of array
• ArrayType[] myArray = new ArrayType[arrayLength]; // Array initialization syntax
• int[] ints = {1, 2, 3}; // Array initialization syntax with values provided, length is inferred
from the number of provided values: {[value1[, value2]*]}
• new int[]{4, -5, 6} // Can be used as argument, without a local variable
• int[] ints = new int[3]; // same as {0, 0, 0}
• int[][] ints = {{1, 2}, {3}, null};// Multi-dimensional array initialization. int[] extends
Object (and so does anyType[]) so null is a valid value.
Parameters
Parameter Details
Type of the array. This can be primitive (int, long, byte) or Objects (String,
ArrayType
MyObject, etc).
Every array, when being created, needs a set length specified. This is either
length done when creating an empty array (new int[3]) or implied when specifying
values ({1, 2, 3}).
Examples
Creating and Initializing Arrays
Basic cases
https://riptutorial.com/ 52
int[] numbers1 = new int[3]; // Array for 3 int values, default value is 0
int[] numbers2 = { 1, 2, 3 }; // Array literal of 3 int values
int[] numbers3 = new int[] { 1, 2, 3 }; // Array of 3 int values initialized
int[][] numbers4 = { { 1, 2 }, { 3, 4, 5 } }; // Jagged array literal
int[][] numbers5 = new int[5][]; // Jagged array, one dimension 5 long
int[][] numbers6 = new int[5][4]; // Multidimensional array: 5x4
float[] boats = new float[5]; // Array of five 32-bit floating point numbers.
double[] header = new double[] { 4.56, 332.267, 7.0, 0.3367, 10.0 };
// Array of five 64-bit floating point numbers.
String[] theory = new String[] { "a", "b", "c" };
// Array of three strings (reference type).
Object[] dArt = new Object[] { new Object(), "We love Stack Overflow.", new Integer(3) };
// Array of three Objects (reference type).
For the last example, note that subtypes of the declared array type are allowed in the array.
Arrays for user defined types can also be built similar to primitive types
Java SE 8
// Streams - JDK 8+
Stream<Integer> toStream = Arrays.stream( initial );
Integer[] fromStream = toStream.toArray( Integer[]::new );
Intro
An array is a data structure that holds a fixed number of primitive values or references to object
instances.
https://riptutorial.com/ 53
Each item in an array is called an element, and each element is accessed by its numerical index.
The length of an array is established when the array is created:
The size of an array is fixed at runtime when initialized. It cannot be changed after
initialization. If the size must be mutable at runtime, a Collection class such as ArrayList should be
used instead. ArrayList stores elements in an array and supports resizing by allocating a new
array and copying elements from the old array.
the values are stored in the array itself. In the absence of an initializer (as in array2 above), the
default value assigned to each element is 0 (zero).
then the array contains references to objects of type SomeClassOrInterface. Those references can
refer to an instance of SomeClassOrInterface or any subclass (for classes) or implementing class
(for interfaces) of SomeClassOrInterface. If the array declaration has no initializer then the default
value of null is assigned to each element.
Because all arrays are int-indexed, the size of an array must be specified by an int. The size of
the array cannot be specified as a long:
Arrays use a zero-based index system, which means indexing starts at 0 and ends at length - 1.
For example, the following image represents an array with size 10. Here, the first element is at
index 0 and the last element is at index 9, instead of the first element being at index 1 and the last
element at index 10 (see figure below).
https://riptutorial.com/ 54
Accesses to elements of arrays are done in constant time. That means accessing to the first
element of the array has the same cost (in time) of accessing the second element, the third
element and so on.
Java offers several ways of defining and initializing arrays, including literal and constructor
notations. When declaring arrays using the new Type[length] constructor, each element will be
initialized with the following default values:
• 0 for primitive numerical types: byte, short, int, long, float, and double.
• '\u0000' (null character) for the char type.
• false for the boolean type.
• null for reference types.
When declaring an array, [] will appear as part of the type at the beginning of the declaration
(after the type name), or as part of the declarator for a particular variable (after variable name), or
both:
int array5[]; /*
equivalent to */ int[] array5;
int a, b[], c[][]; /*
equivalent to */ int a; int[] b; int[][] c;
int[] a, b[]; /*
equivalent to */ int[] a; int[][] b;
int a, []b, c[][]; /*
Compilation Error, because [] is not part of the type at beginning
of the declaration, rather it is before 'b'. */
// The same rules apply when declaring a method that returns an array:
int foo()[] { ... } /* equivalent to */ int[] foo() { ... }
In the following example, both declarations are correct and can compile and run without any
problems. However, both the Java Coding Convention and the Google Java Style Guide
discourage the form with brackets after the variable name—the brackets identify the array type
and should appear with the type designation. The same should be used for method return
signatures.
The discouraged type is meant to accommodate transitioning C users, who are familiar with the
syntax for C which has the brackets after the variable name.
https://riptutorial.com/ 55
int[] array2 = {}; // Equivalent syntax.
However, since it's an empty array, no elements can be read from it or assigned to it:
Such empty arrays are typically useful as return values, so that the calling code only has to worry
about dealing with an array, rather than a potential null value that may lead to a
NullPointerException.
The array size can be determined using a public final field called length:
Note: array.length returns the actual size of the array and not the number of array elements which
were assigned a value, unlike ArrayList.size() which returns the number of array elements which
were assigned a value.
It will create two three-length int arrays—a[0] and a[1]. This is very similar to the classical, C-style
initialization of rectangular multi-dimensional arrays.
Unlike C, where only rectangular multi-dimensional arrays are supported, inner arrays do not need
to be of the same length, or even defined:
Here, a[0] is a one-length int array, whereas a[1] is a two-length int array and a[2] is null. Arrays
like this are called jagged arrays or ragged arrays, that is, they are arrays of arrays. Multi-
dimensional arrays in Java are implemented as arrays of arrays, i.e. array[i][j][k] is equivalent to
https://riptutorial.com/ 56
((array[i])[j])[k]. Unlike C#, the syntax array[i,j] is not supported in Java.
Live on Ideone
In addition to the String literals and primitives shown above, the shortcut syntax for array
initialization also works with canonical Object types:
Because arrays are covariant, a reference type array can be initialized as an array of a subclass,
although an ArrayStoreException will be thrown if you try to set an element to something other than
a String:
The shortcut syntax cannot be used for this because the shortcut syntax would have an implicit
https://riptutorial.com/ 57
type of Object[].
An array can be initialized with zero elements by using String[] emptyArray = new String[0]. For
example, an array with zero length like this is used for Creating an Array from a Collection when
the method needs the runtime type of an object.
In both primitive and reference types, an empty array initialization (for example String[] array8 =
new String[3]) will initialize the array with the default value for each data type.
public MyGenericClass() {
a = new T[5]; // Compile time error: generic array creation
}
}
Instead, they can be created using one of the following methods: (note that these will generate
unchecked warnings)
This is the simplest method, but since the underlying array is still of type Object[], this
method does not provide type safety. Therefore, this method of creating an array is best
used only within the generic class - not exposed publicly.
Here the class of T has to be explicitly passed to the constructor. The return type of
Array.newInstance is always Object. However, this method is safer because the newly created
array is always of type T[], and therefore can be safely externalized.
Arrays.fill() can be used to fill an array with the same value after initialization:
https://riptutorial.com/ 58
Arrays.fill(array8, "abc"); // { "abc", "abc", "abc" }
Live on Ideone
fill() can also assign a value to each element of the specified range of the array:
Live on Ideone
Java SE 8
Since Java version 8, the method setAll, and its Concurrent equivalent parallelSetAll, can be used
to set every element of an array to generated values. These methods are passed a generator
function which accepts an index and returns the desired value for that position.
The following example creates an integer array and sets all of its elements to their respective
index value:
Live on Ideone
https://riptutorial.com/ 59
However, it is possible to create a new array and assign it to the variable being used to reference
the old array. While this results in the array referenced by that variable being re-initialized, the
variable contents are a completely new array. To do this, the new operator can be used with an
array initializer and assigned to the array variable:
Live on Ideone
• Object[] toArray()
Java SE 5
Java SE 5
// The array does not need to be created up front with the correct size.
// Only the array type matters. (If the size is wrong, a new array will
https://riptutorial.com/ 60
// be created with the same type.)
String[] stringArray = set.toArray(new String[0]);
The difference between them is more than just having untyped vs typed results. Their performance
can differ as well (for details please read this performance analysis section):
Java SE 8
Starting from Java SE 8+, where the concept of Stream has been introduced, it is possible to use
the Stream produced by the collection in order to create a new Array using the Stream.toArray
method.
Examples taken from two answers (1, 2) to Converting 'ArrayList to 'String[]' in Java on Stack
Overflow.
Arrays to a String
Java SE 5
Since Java 1.5 you can get a String representation of the contents of the specified array without
iterating over its every element. Just use Arrays.toString(Object[]) or
Arrays.deepToString(Object[]) for multidimentional arrays:
int[][] arr = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println(Arrays.deepToString(arr)); // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Arrays.toString() method uses Object.toString() method to produce String values of every item in
the array, beside primitive type array, it can be used for all type of arrays. For instance:
https://riptutorial.com/ 61
@Override
public String toString() {
return "CAT!";
}
}
If no overridden toString() exists for the class, then the inherited toString() from Object will be
used. Usually the output is then not very useful, for example:
The Arrays.asList() method can be used to return a fixed-size List containing the elements of the
given array. The resulting List will be of the same parameter type as the base type of the array.
Note: This list is backed by (a view of) the original array, meaning that any changes to the list will
change the array and vice versa. However, changes to the list that would change its size (and
hence the array length) will throw an exception.
To create a copy of the list, use the constructor of java.util.ArrayList taking a Collection as an
argument:
Java SE 5
Java SE 7
In Java SE 7 and later, a pair of angle brackets <> (empty set of type arguments) can be used,
which is called the Diamond. The compiler can determine the type arguments from the context.
This means the type information can be left out when calling the constructor of ArrayList and it will
be inferred automatically during compilation. This is called Type Inference which is a part of Java
Generics.
// Using Arrays.asList()
https://riptutorial.com/ 62
// Using ArrayList.addAll()
// Using Collections.addAll()
A point worth noting about the Diamond is that it cannot be used with Anonymous Classes.
Java SE 8
// Using Streams
• A new List can be created by passing an array-backed List to the constructor of a new List.
This creates a new copy of the data, which has changeable size and that is not backed by
the original array:
The reason for this behavior is that primitive types cannot be used in place of generic type
parameters, so the entire primitive array replaces the generic type parameter in this case. In
order to convert a primitive array to a List, first of all, convert the primitive array to an array
of the corresponding wrapper type (i.e. call Arrays.asList on an Integer[] instead of an int[]
).
https://riptutorial.com/ 63
int[] arr = {1, 2, 3}; // primitive array of int
System.out.println(Arrays.asList(arr).contains(1));
View Demo
Integer[] arr = {1, 2, 3}; // object array of Integer (wrapper for int)
System.out.println(Arrays.asList(arr).contains(1));
View Demo
This will also print true, because the array will be interpreted as an Integer[]):
System.out.println(Arrays.asList(1,2,3).contains(1));
View Demo
It is possible to define an array with more than one dimension. Instead of being accessed by
providing a single index, a multidimensional array is accessed by specifying an index for each
dimension.
The declaration of multidimensional array can be done by adding [] for each dimension to a
regular array decleration. For instance, to make a 2-dimensional int array, add another set of
brackets to the declaration, such as int[][]. This continues for 3-dimensional arrays (int[][][])
and so forth.
int rows = 3;
int columns = 3;
int[][] table = new int[rows][columns];
The array can be indexed and assign values to it with this construct. Note that the unassigned
values are the default values for the type of an array, in this case 0 for int.
table[0][0] = 0;
table[0][1] = 1;
table[0][2] = 2;
It is also possible to instantiate a dimension at a time, and even make non-rectangular arrays.
These are more commonly referred to as jagged arrays.
It is important to note that although it is possible to define any dimension of jagged array, it's
https://riptutorial.com/ 64
preceding level must be defined.
// valid
String[][] employeeGraph = new String[30][];
// invalid
int[][] unshapenMatrix = new int[][10];
// also invalid
int[][][] misshapenGrid = new int[100][][10];
Multidimensional arrays and jagged arrays can also be initialized with a literal expression. The
following declares and populates a 2x3 int array:
int[][] table = {
{1, 2, 3},
{4, 5, 6}
};
Note: Jagged subarrays may also be null. For instance, the following code declares and
populates a two dimensional int array whose first subarray is null, second subarray is of zero
length, third subarray is of one length and the last subarray is a two length array:
int[][] table = {
null,
https://riptutorial.com/ 65
{},
{1},
{1,2}
};
For multidimensional array it is possible to extract arrays of lower-level dimension by their indices:
ArrayIndexOutOfBoundsException
Arrays are zero-based indexed, so the index of the first element is 0 and the index of the last
element is the array capacity minus 1 (i.e. array.length - 1).
Therefore, any request for an array element by the index i has to satisfy the condition 0 <= i <
array.length, otherwise the ArrayIndexOutOfBoundsException will be thrown.
Output:
Note that the illegal index that is being accessed is also included in the exception (2 in the
example); this information could be useful to find the cause of the exception.
To avoid this, simply check that the index is within the limits of the array:
int index = 2;
if (index >= 0 && index < people.length) {
System.out.println(people[index]);
}
https://riptutorial.com/ 66
Getting the Length of an Array
Arrays are objects which provide space to store up to its size of elements of specified type. An
array's size can not be modified after the array is created.
The length field in an array stores the size of an array. It is a final field and cannot be modified.
This code shows the difference between the length of an array and amount of objects an array
stores.
Result:
Array types inherit their equals() (and hashCode()) implementations from java.lang.Object, so
equals() will only return true when comparing against the exact same array object. To compare
arrays for equality based on their values, use java.util.Arrays.equals, which is overloaded for all
array types.
https://riptutorial.com/ 67
the same values
When the element type is a reference type, Arrays.equals() calls equals() on the array elements to
determine equality. In particular, if the element type is itself an array type, identity comparison will
be used. To compare multidimensional arrays for equality, use Arrays.deepEquals() instead as
below:
int a[] = { 1, 2, 3 };
int b[] = { 1, 2, 3 };
Because sets and maps use equals() and hashCode(), arrays are generally not useful as set
elements or map keys. Either wrap them in a helper class that implements equals() and hashCode()
in terms of the array elements, or convert them to List instances and store the lists.
Arrays to Stream
Java SE 8
Converting an array of primitives to Stream using Arrays.stream() will transform the array to a
primitive specialization of Stream:
You can also limit the Stream to a range of elements in the array. The start index is inclusive and
the end index is exclusive:
A method similar to Arrays.stream() appears in the Stream class: Stream.of(). The difference is that
Stream.of() uses a varargs parameter, so you can write something like:
https://riptutorial.com/ 68
You can iterate over arrays either by using enhanced for loop (aka foreach) or by using array
indices:
Java SE 5
It is worth noting here that there is no direct way to use an Iterator on an Array, but through the
Arrays library it can be easily converted to a list to obtain an Iterable object.
For primitive arrays (using java 8) use streams (specifically in this example - Arrays.stream ->
IntStream):
If you can't use streams (no java 8), you can choose to use google's guava library:
In two-dimensional arrays or more, both techniques can be used in a slightly more complex
fashion.
Example:
Java SE 5
https://riptutorial.com/ 69
for (int[] numbers : array) {
for (int value : numbers) {
System.out.println(value);
}
}
It is impossible to set an Array to any non-uniform value without using an index based loop.
Of course you can also use while or do-while loops when iterating using indices.
One note of caution: when using array indices, make sure the index is between 0 and
array.length - 1 (both inclusive). Don't make hard coded assumptions on the array length
otherwise you might break your code if the array length changes but your hard coded values don't.
Example:
// DON'T DO THIS :
for (int i = 0; i < 4; i++) {
numbers[i] += 1;
}
}
It's also best if you don't use fancy calculations to get the index but use the index to iterate and if
you need different values calculate those.
Example:
// DON'T DO THIS :
int doubleLength = array.length * 2;
for (int i = 0; i < doubleLength; i += 2) {
array[i / 2] = i;
}
}
https://riptutorial.com/ 70
}
Iterating over a temporary array instead of repeating code can make your code cleaner. It can be
used where the same operation is performed on multiple variables.
// copy-paste approach:
System.out.println(name);
System.out.println(eyeCount);
System.out.println(height);
System.out.println(legs);
System.out.println(arms);
Keep in mind that this code should not be used in performance-critical sections, as an array is
created every time the loop is entered, and that primitive variables will be copied into the array and
thus cannot be modified.
Copying arrays
for loop
int[] a = { 4, 1, 3, 2 };
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
Note that using this option with an Object array instead of primitive array will fill the copy with
reference to the original content instead of copy of it.
https://riptutorial.com/ 71
Object.clone()
Since arrays are Objects in Java, you can use Object.clone().
int[] a = { 4, 1, 3, 2 };
int[] b = a.clone(); // [4, 1, 3, 2]
Note that the Object.clone method for an array performs a shallow copy, i.e. it returns a reference
to a new array which references the same elements as the source array.
Arrays.copyOf()
java.util.Arrays provides an easy way to perform the copy of an array to another. Here is the
basic usage:
Note that Arrays.copyOf also provides an overload which allows you to change the type of the
array:
System.arraycopy()
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int
length) Copies an array from the specified source array, beginning at the specified
position, to the specified position of the destination array.
int[] a = { 4, 1, 3, 2 };
int[] b = new int[a.length];
System.arraycopy(a, 0, b, 0, a.length); // [4, 1, 3, 2]
Arrays.copyOfRange()
Mainly used to copy a part of an Array, you can also use it to copy whole array to another as
below:
https://riptutorial.com/ 72
int[] a = { 4, 1, 3, 2 };
int[] b = Arrays.copyOfRange(a, 0, a.length); // [4, 1, 3, 2]
Casting Arrays
Arrays are objects, but their type is defined by the type of the contained objects. Therefore, one
cannot just cast A[] to T[], but each A member of the specific A[] must be cast to a T object.
Generic example:
Java SE provides the method Arrays.copyOf(original, newLength, newType) for this purpose:
Java doesn't provide a direct method in java.util.Arrays to remove an element from an array. To
perform it, you can either copy the original array to a new one without the element to remove or
convert your array to another structure allowing the removal.
Using ArrayList
You can convert the array to a java.util.List, remove the element and convert the list back to an
array as follows:
// Creates a new array with the same size as the list and copies the list
// elements to it.
array = list.toArray(new String[list.size()]);
https://riptutorial.com/ 73
Using System.arraycopy
can be used to make a copy of the original array and remove the element you
System.arraycopy()
want. Below an example:
System.out.println(Arrays.toString(result)); //[1, 3, 4]
Array Covariance
Object arrays are covariant, which means that just as Integer is a subclass of Number, Integer[] is a
subclass of Number[]. This may seem intuitive, but can result in surprising behavior:
Although Integer[] is a subclass of Number[], it can only hold Integers, and trying to assign a Long
element throws a runtime exception.
Note that this behavior is unique to arrays, and can be avoided by using a generic List instead:
It's not necessary for all of the array elements to share the same type, as long as they are a
subclass of the array's type:
https://riptutorial.com/ 74
interface I {}
class A implements I {}
class B implements I {}
class C implements I {}
I[] array10 = new I[] { new A(), new B(), new C() }; // Create an array with new
// operator and array initializer.
I[] array11 = { new A(), new B(), new C() }; // Shortcut syntax with array
// initializer.
I[] array13 = new A[] { new A(), new A() }; // Works because A implements I.
Object[] array14 = new Object[] { "Hello, World!", 3.14159, 42 }; // Create an array with
// new operator and array initializer.
The simple answer is that you cannot do this. Once an array has been created, its size cannot be
changed. Instead, an array can only be "resized" by creating a new array with the appropriate size
and copying the elements from the existing array to the new one.
Suppose (for example) that a new element needs to be added to the listOfCities array defined as
above. To do this, you will need to:
There are various ways to do the above. Prior to Java 6, the most concise way was:
From Java 6 onwards, the Arrays.copyOf and Arrays.copyOfRange methods can do this more simply:
For other ways to copy an array, refer to the following example. Bear in mind that you need an
array copy with a different length to the original when resizing.
https://riptutorial.com/ 75
• Copying arrays
• It is inefficient. Making an array bigger (or smaller) involves copying many or all of the
existing array elements, and allocating a new array object. The larger the array, the more
expensive it gets.
• You need to be able to update any "live" variables that contain references to the old array.
One alternative is to create the array with a large enough size to start with. This is only viable if
you can determine that size accurately before allocating the array. If you cannot do that, then the
problem of resizing the array arises again.
The other alternative is to use a data structure class provided by the Java SE class library or a
third-party library. For example, the Java SE "collections" framework provides a number of
implementations of the List, Set and Map APIs with different runtime properties. The ArrayList class
is closest to performance characteristics of a plain array (e.g. O(N) lookup, O(1) get and set, O(N)
random insertion and deletion) while providing more efficient resizing without the reference update
problem.
(The resize efficiency for ArrayList comes from its strategy of doubling the size of the backing
array on each resize. For a typical use-case, this means that you only resize occasionally. When
you amortize over the lifetime of the list, the resize cost per insert is O(1). It may be possible to use
the same strategy when resizing a plain array.)
There are many ways find the location of a value in an array. The following example snippets all
assume that the array is one of the following:
In addition, each one sets index or index2 to either the index of required element, or -1 if the
element is not present.
https://riptutorial.com/ 76
int index2 = Arrays.asList(ints).indexOf(1); // compilation error
Using a Stream
Java SE 8
Note: Using a direct linear search is more efficient than wrapping in a list.
Java SE 8
https://riptutorial.com/ 77
isPresent = true;
break;
}
}
Sorting arrays
import java.util.Arrays;
String is not a numeric data, it defines it's own order which is called lexicographic order, also
known as alphabetic order. When you sort an array of String using sort() method, it sorts array
into natural order defined by Comparable interface, as shown below :
Increasing Order
Output:
Decreasing Order
Output:
String array after sorting in descending order : [Steve, Shane, John, Ben, Adam]
https://riptutorial.com/ 78
In order to sort an object array, all elements must implement either Comparable or Comparator
interface to define the order of the sorting.
We can use either sort(Object[]) method to sort an object array on its natural order, but you must
ensure that all elements in the array must implement Comparable.
Furthermore, they must be mutually comparable as well, for example e1.compareTo(e2) must not
throw a ClassCastException for any elements e1 and e2 in the array. Alternatively you can sort an
Object array on custom order using sort(T[], Comparator) method as shown in following example.
Arrays.sort(courses);
System.out.println("Object array after sorting in natural order : " +
Arrays.toString(courses));
Output:
Object array before sorting : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 , #401
Scala@500 ]
Object array after sorting in natural order : [#101 Java@200 , #201 Ruby@300 , #301 Python@400
, #401 Scala@500 ]
Object array after sorting by price : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 , #401
Scala@500 ]
Object array after sorting by name : [#101 Java@200 , #301 Python@400 , #201 Ruby@300 , #401
Scala@500 ]
To convert the array, it's possible to use streams (in Java 8 and above):
Java SE 8
With lower versions it can be by iterating the primitive array and explicitly copying it to the boxed
array:
https://riptutorial.com/ 79
Java SE 8
Java SE 8
Java SE 8
https://riptutorial.com/ 80
Chapter 9: Asserting
Syntax
• assert expression1;
• assert expression1 : expression2;
Parameters
Parameter Details
Optional. When used, AssertionErrors thrown by the assert statement have this
expression2
message.
Remarks
By default, assertions are disabled at runtime.
Assertions are statements that will throw an error if their expression evaluates to false. Assertions
should only be used to test code; they should never be used in production.
Examples
Checking arithmetic with assert
a = 1 - Math.abs(1 - a % 2);
return a;
https://riptutorial.com/ 81
Chapter 10: Atomic Types
Introduction
Java Atomic Types are simple mutable types that provide basic operations that are thread-safe
and atomic without resorting to locking. They are intended for use in cases where locking would be
a concurrency bottleneck, or where there is risk of deadlock or livelock.
Parameters
Parameter Description
compareAndSet If the value is the expeed value then sent it to the new value
Remarks
Many on essentially combinations of volatile reads or writes and CAS operations. Best way to
understand this is to look at the source code directly. E.g. AtomicInteger, Unsafe.getAndSet
Examples
Creating Atomic Types
In cases of more complex concurrency, using Atomic Variables is often a better alternative, as it
allows an individual variable to be accessed in a thread-safe manner without the overhead of
using synchronized methods or code blocks.
https://riptutorial.com/ 82
Similarly for other instance types.
There is a notable exception that there is no float and double types. These can be simulated
through the use of Float.floatToIntBits(float) and Float.intBitsToFloat(int) for float as well as
Double.doubleToLongBits(double) and Double.longBitsToDouble(long) for doubles.
If you are willing to use sun.misc.Unsafe you can use any primitive variable as atomic by using the
atomic operation in sun.misc.Unsafe. All primitive types should be converted or encoded in int or
longs to so use it in this way. For more on this see: sun.misc.Unsafe.
The simple way to implement multi-threaded applications is to use Java's built-in synchronization
and locking primitives; e.g. the synchronized keyword. The following example shows how we might
use synchronized to accumulate counts.
/**
* Increments the integer at the given index
*/
public synchronized void count(int number) {
if (number >= 0 && number < counters.length) {
counters[number]++;
}
}
/**
* Obtains the current count of the number at the given index,
* or if there is no number at that index, returns 0.
*/
public synchronized int getCount(int number) {
return (number >= 0 && number < counters.length) ? counters[number] : 0;
}
}
This implementation will work correctly. However, if you have a large number of threads making
lots of simultaneous calls on the same Counters object, the synchronization is liable to be a
bottleneck. Specifically:
1. Each synchronized method call will start with the current thread acquiring the lock for the
Counters instance.
https://riptutorial.com/ 83
2. The thread will hold the lock while it checks number value and updates the counter.
3. Finally, the it will release the lock, allowing other threads access.
If one thread attempts to acquire the lock while another one holds it, the attempting thread will be
blocked (stopped) at step 1 until the lock is released. If multiple threads are waiting, one of them
will get it, and the others will continue to be blocked.
• If there is a lot of contention for the lock (i.e. lots of thread try to acquire it), then some
threads can be blocked for a long time.
• When a thread is blocked waiting for the lock, the operating system will typically try switch
execution to a different thread. This context switching incurs a relatively large performance
impact on the processor.
• When there are multiple threads blocked on the same lock, there are no guarantees that any
one of them will be treated "fairly" (i.e. each thread is guaranteed to be scheduled to run).
This can lead to thread starvation.
/**
* Increments the integer at the given index
*/
public void count(int number) {
if (number >= 0 && number < counters.length) {
counters[number].incrementAndGet();
}
}
/**
* Obtains the current count of the object at the given index,
* or if there is no number at that index, returns 0.
*/
public int getCount(int number) {
return (number >= 0 && number < counters.length) ?
counters[number].get() : 0;
}
}
We have replaced the int[] with an AtomicInteger[], and initialized it with an instance in each
https://riptutorial.com/ 84
element. We have also added calls to incrementAndGet() and get() in place of operations on int
values.
But the most important thing is that we can remove the synchronized keyword because locking is
no longer required. This works because the incrementAndGet() and get() operations are atomic and
thread-safe. In this context, it means that:
• Each counter in the array will only be observable in the either the "before" state for an
operation (like an "increment") or in the "after" state.
• Assuming that the operation occurs at time T, no thread will be able to see the "before" state
after time T.
Furthermore, while two threads might actually attempt to update the same AtomicInteger instance
at the same time, the implementations of the operations ensure that only one increment happens
at a time on the given instance. This is done without locking, often resulting in better performance.
These low-level instructions are are used to implement higher-level operations in the APIs of the
respective AtomicXxx classes. For example, (again, in C-like pseudocode):
int increment() {
while (TRUE) {
int old = num;
int new = old + 1;
if (old == compare_and_swap(&num, old, new)) {
return new;
}
}
}
If there is no contention on the AtomicXxxx, the if test will succeed and the loop will end
immediately. If there is contention, then the if will fail for all but one of the threads, and they will
"spin" in the loop for a small number of cycles of the loop. In practice, the spinning is orders of
magnitude faster (except at unrealistically high levels of contention, where synchronized performs
better than atomic classes because when the CAS operation fails, then the retry will only add more
contention) than suspending the thread and switching to another one.
Incidentally, CAS instructions are typically used by the JVM to implement uncontended locking. If
the JVM can see that a lock is not currently locked, it will attempt to use a CAS to acquire the lock.
If the CAS succeeds, then there is no need to do the expensive thread scheduling, context
switching and so on. For more information on the techniques used, see Biased Locking in HotSpot
.
https://riptutorial.com/ 85
Read Atomic Types online: https://riptutorial.com/java/topic/5963/atomic-types
https://riptutorial.com/ 86
Chapter 11: Audio
Remarks
Instead of using the javax.sound.sampled Clip, you can also use the AudioClip which is from the
applet API. It is however recommended to use Clip since AudioClip is just older and presents
limited functionalities.
Examples
Play an Audio file Looped
Needed imports:
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
This code will create a clip and play it continuously once started:
MIDI files can be played by using several classes from the javax.sound.midi package. A Sequencer
performs playback of the MIDI file, and many of its methods can be used to set playback controls
such as loop count, tempo, track muting, and others.
import java.io.File;
import java.io.IOException;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
https://riptutorial.com/ 87
if (sequencer==null) {
System.err.println("Sequencer device not supported");
return;
}
sequencer.open(); // Open device
// Create sequence, the File must contain MIDI file data.
Sequence sequence = MidiSystem.getSequence(new File(args[0]));
sequencer.setSequence(sequence); // load it into sequencer
sequencer.start(); // start the playback
} catch (MidiUnavailableException | InvalidMidiDataException | IOException ex) {
ex.printStackTrace();
}
}
}
A sequencer can be set to mute one or more of the sequence's tracks during playback so none of
the instruments in those specified play. The following example sets the first track in the sequence
to be muted:
import javax.sound.midi.Track;
// ...
A sequencer can play a sequence repeatedly if the loop count is given. The following sets the
sequencer to play a sequence four times and indefinitely:
sequencer.setLoopCount(3);
sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
The sequencer does not always have to play the sequence from the beginning, nor does it have to
play the sequence until the end. It can start and end at any point by specifying the tick in the
sequence to start and end at. It is also possible to specify manually which tick in the sequence the
sequencer should play from:
sequencer.setLoopStartPoint(512);
sequencer.setLoopEndPoint(32768);
sequencer.setTickPosition(8192);
Sequencers can also play a MIDI file at a certain tempo, which can be controlled by specifying the
tempo in beats per minute (BPM) or microseconds per quarter note (MPQ). The factor at which the
sequence is played can be adjusted as well.
sequencer.setTempoInBPM(1250f);
sequencer.setTempoInMPQ(4750f);
sequencer.setTempoFactor(1.5f);
https://riptutorial.com/ 88
When you finished using the Sequencer, remeber to close it
sequencer.close();
You can also go almost bare-metal when producing sound with java. This code will write raw
binary data into the OS audio buffer to generate sound. It's extremely important to understand the
limitations and necessary calculations to generating sound like this. Since playback is basically
instantaneous, calculations need to be performed at almost real-time.
As such this method is unusable for more complicated sound-sampling. For such purposes using
specialized tools is the better approach.
The following method generates and directly outputs a rectangle-wave of a given frequency in a
given volume for a given duration.
For a more differentiated way to generate different soundwaves sinus calculations and possibly
larger sample sizes are necessary. This results in significantly more complex code and is
accordingly omitted here.
The Hello Audio! of Java that plays a sound file from local or internet storage looks as follows. It
https://riptutorial.com/ 89
works for uncompressed .wav files and should not be used for playing mp3 or compressed files.
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
// Constructor
public SoundClipTest() {
try {
// Open an audio input stream.
File soundFile = new File("/usr/share/sounds/alsa/Front_Center.wav"); //you could
also get the sound file with an URL
AudioInputStream audioIn = AudioSystem.getAudioInputStream(soundFile);
AudioFormat format = audioIn.getFormat();
// Get a sound clip resource.
DataLine.Info info = new DataLine.Info(Clip.class, format);
Clip clip = (Clip)AudioSystem.getLine(info);
// Open audio clip and load samples from the audio input stream.
clip.open(audioIn);
clip.start();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
https://riptutorial.com/ 90
Chapter 12: Autoboxing
Introduction
Autoboxing is the automatic conversion that Java compiler makes between primitive types and
their corresponding object wrapper classes. Example, converting int -> Integer, double -> Double...
If the conversion goes the other way, this is called unboxing. Typically, this is used in Collections
that cannot hold other than Objects, where boxing primitive types is needed before setting them in
the collection.
Remarks
Autoboxing can have performance issues when used frequently in your code.
• http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html
• Integer auto-unboxing and auto-boxing gives performance issues?
Examples
Using int and Integer interchangeably
As you use generic types with utility classes, you may often find that number types aren't very
helpful when specified as the object types, as they aren't equal to their primitive counterparts.
Java SE 7
Fortunately, expressions that evaluate to int can be used in place of an Integer when it is needed.
ints.add(Integer.valueOf(i));
And retains properties from Integer#valueOf such as having the same Integer objects cached by
the JVM when it is within the number caching range.
https://riptutorial.com/ 91
• short and Short
• float and Float
• double and Double
• long and Long
• char and Character
• boolean and Boolean
Care must be taken, however, in ambiguous situations. Consider the following code:
The java.util.List interface contains both a remove(int index) (List interface method) and a
remove(Object o) (method inherited from java.util.Collection). In this case no boxing takes place
and remove(int index) is called.
One more example of strange Java code behavior caused by autoboxing Integers with values in
range from -128 to 127:
Integer a = 127;
Integer b = 127;
Integer c = 128;
Integer d = 128;
System.out.println(a == b); // true
System.out.println(c <= d); // true
System.out.println(c >= d); // true
System.out.println(c == d); // false
This happens because >= operator implicitly calls intValue() which returns int while == compares
references, not the int values.
By default, Java caches values in range [-128, 127], so the operator == works because the
Integers in this range reference to the same objects if their values are same. Maximal value of the
cacheable range can be defined with -XX:AutoBoxCacheMax JVM option. So, if you run the program
with -XX:AutoBoxCacheMax=1000, the following code will print true:
Integer a = 1000;
Integer b = 1000;
System.out.println(a == b); // true
Boolean a = Boolean.TRUE;
if (a) { // a gets converted to boolean
System.out.println("It works!");
}
https://riptutorial.com/ 92
That works for while, do while and the condition in the for statements as well.
Note that, if the Boolean is null, a NullPointerException will be thrown in the conversion.
This is a minimalistic example, but in practice it often manifests in more sophisticated forms. The
NullPointerException is not very intuitive and is often little help in locating such bugs.
Rely on autoboxing and auto-unboxing with care, make sure that unboxed values will not have
null values at runtime.
will typically consume substantial amount of memory (about 60kb for 6k of actual data).
Furthermore, boxed integers usually require additional round-trips in the memory, and thus make
CPU caches less effective. In above example, the memory accessed is spread out to five different
locations that may be in entirely different regions of the memory: 1. the HashMap object, 2. the map's
Entry[] table object, 3. the Entry object, 4. the entrys key object (boxing the primitive key), 5. the
entrys value object (boxing the primitive value).
class Example {
int primitive; // Stored directly in the class `Example`
Integer boxed; // Reference to another memory location
}
Reading boxed requires two memory accesses, accessing primitive only one.
When getting data from this map, the seemingly innocent code
int sumOfSquares = 0;
for(int i = 256; i < 1024; i++) {
sumOfSquares += square.get(i);
https://riptutorial.com/ 93
}
is equivalent to:
int sumOfSquares = 0;
for(int i = 256; i < 1024; i++) {
sumOfSquares += square.get(Integer.valueOf(i)).intValue();
}
Typically, the above code causes the creation and garbage collection of an Integer object for
every Map#get(Integer) operation. (See Note below for more details.)
To reduce this overhead, several libraries offer optimized collections for primitive types that do not
require boxing. In addition to avoiding the boxing overhead, these collection will require about 4x
less memory per entry. While Java Hotspot may be able to optimize the autoboxing by working
with objects on the stack instead of the heap, it is not possible to optimize the memory overhead
and resulting memory indirection.
Java 8 streams also have optimized interfaces for primitive data types, such as IntStream that do
not require boxing.
Note: a typical Java runtime maintains a simple cache of Integer and other primitive wrapper
object that is used by the valueOf factory methods, and by autoboxing. For Integer, the default
range of this cache is -128 to +127. Some JVMs provide a JVM command-line option for changing
the cache size / range.
Example:
int i;
Integer j;
void ex_method(Integer i)//Is a valid statement
void ex_method1(int j)//Is a valid statement
When a method returns a primitive type variable then an object of corresponding wrapper class
can be passed as the return value interchangeably and vice versa.
Example:
int i;
Integer j;
int ex_method()
https://riptutorial.com/ 94
{...
return j;}//Is a valid statement
Integer ex_method1()
{...
return i;//Is a valid statement
}
Whenever performing operations on numbers the primitive type variable and object of respective
wrapper class can be used interchangeably.
int i=5;
Integer j=new Integer(7);
int k=i+j;//Is a valid statement
Integer m=i+j;//Is also a valid statement
While using wrapper class object and primitive variable interchangeably never forget or miss to
initialize or assign a value to the wrapper class object else it may lead to null pointer exception at
runtime.
Example:
In the above example, the value of the object is unassigned and uninitialized and thus at runtime
the program will run into null pointer exception.So as clear from the above example the value of
object should never be left uninitialized and unassigned.
https://riptutorial.com/ 95
Chapter 13: Basic Control Structures
Remarks
All control structures, unless otherwise noted, make use of block statements. These are denoted
by curly braces {}.
This differs from normal statements, which do not require curly braces, but also come with a stiff
caveat in that only the line immediately following the previous statement would be considered.
Thus, it is perfectly valid to write any of these control structures without curly braces, so long as
only one statement follows the beginning, but it is strongly discouraged, as it can lead to buggy
implementations, or broken code.
Example:
Examples
If / Else If / Else Control
if (i < 2) {
System.out.println("i is less than 2");
} else if (i > 2) {
System.out.println("i is more than 2");
} else {
System.out.println("i is not less than 2, and not more than 2");
}
The else if condition is checked only if all the conditions before it (in previous else if constructs,
and the parent if constructs) have been tested to false. In this example, the else if condition will
only be checked if i is greater than or equal to 2.
If its result is true, its block is run, and any else if and else constructs after it will be skipped.
https://riptutorial.com/ 96
If none of the if and else if conditions have been tested to true, the else block at the end will be
run.
For Loops
The three components of the for loop (separated by ;) are variable declaration/initialization (here
int i = 0), the condition (here i < 100), and the increment statement (here i++). The variable
declaration is done once as if placed just inside the { on the first run. Then the condition is
checked, if it is true the body of the loop will execute, if it is false the loop will stop. Assuming the
loop continues, the body will execute and finally when the } is reached the increment statement
will execute just before the condition is checked again.
The curly braces are optional (you can one line with a semicolon) if the loop contains just one
statement. But, it's always recommended to use braces to avoid misunderstandings and bugs.
The for loop components are optional. If your business logic contains one of these parts, you can
omit the corresponding component from your for loop.
Any looping statement having another loop statement inside called nested loop. The same way for
looping having more inner loop is called 'nested for loop'.
for(;;){
//Outer Loop Statements
for(;;){
//Inner Loop Statements
}
//Outer Loop Statements
}
https://riptutorial.com/ 97
}
}
While Loops
int i = 0;
while (i < 100) { // condition gets checked BEFORE the loop body executes
System.out.println(i);
i++;
}
A while loop runs as long as the condition inside the parentheses is true. This is also called the
"pre-test loop" structure because the conditional statement must be met before the main loop body
is performed every time.
The curly braces are optional if the loop contains just one statement, but some coding style
conventions prefers having the braces regardless.
do...while Loop
The do...while loop differs from other loops in that it is guaranteed to execute at least once. It is
also called the "post-test loop" structure because the conditional statement is performed after the
main loop body.
int i = 0;
do {
i++;
System.out.println(i);
} while (i < 100); // Condition gets checked AFTER the content of the loop executes.
In this example, the loop will run until the number 100 is printed (even though the condition is i <
100 and not i <= 100), because the loop condition is evaluated after the loop executes.
With the guarantee of at least one execution, it is possible to declare variables outside of the loop
and initialize them inside.
String theWord;
Scanner scan = new Scanner(System.in);
do {
theWord = scan.nextLine();
} while (!theWord.equals("Bird"));
System.out.println(theWord);
In this context, theWord is defined outside of the loop, but since it's guaranteed to have a value
based on its natural flow, theWord will be initialized.
For Each
Java SE 5
https://riptutorial.com/ 98
With Java 5 and up, one can use for-each loops, also known as enhanced for-loops:
strings.add("This");
strings.add("is");
strings.add("a for-each loop");
For each loops can be used to iterate over Arrays and implementations of the Iterable interface,
the later includes Collections classes, such as List or Set.
The loop variable can be of any type that is assignable from the source type.
The loop variable for a enhanced for loop for Iterable<T> or T[] can be of type S, if
• T extends S
• both T and S are primitive types and assignable without a cast
• S is a primitive type and T can be converted to a type assignable to S after unboxing
conversion.
• T is a primitive type and can be converted to S by autoboxing conversion.
Examples:
T elements = ...
for (S s : elements) {
}
T S Compiles
long[] int no
Iterable<CharSequence> String no
int[] Long no
If / Else
int i = 2;
https://riptutorial.com/ 99
if (i < 2) {
System.out.println("i is less than 2");
} else {
System.out.println("i is greater than 2");
}
The else block is optional and can be omitted. It runs if the if statement is false and does not run
if the if statement is true Because in that case if statement executes.
Switch statement
The switch statement is Java's multi-way branch statement. It is used to take the place of long if-
else if-else chains, and make them more readable. However, unlike if statements, one may not
use inequalities; each value must be concretely defined.
• case:
This is the value that is evaluated for equivalence with the argument to the switch
statement.
• default: This is an optional, catch-all expression, should none of the case statements
evaluate to true.
• Abrupt completion of the case statement; usually break: This is required to prevent the
undesired evaluation of further case statements.
With the exception of continue, it is possible to use any statement which would cause the abrupt
completion of a statement. This includes:
• break
• return
• throw
In the example below, a typical switch statement is written with four possible cases, including
default.
https://riptutorial.com/ 100
break;
default:
System.out.println("i is less than zero or greater than two");
}
By omitting break or any statement which would an abrupt completion, we can leverage what are
known as "fall-through" cases, which evaluate against several values. This can be used to create
ranges for a value to be successful against, but is still not as flexible as inequalities.
Java SE 5
enum Option {
BLUE_PILL,
RED_PILL
}
}
}
Java SE 7
https://riptutorial.com/ 101
public void rhymingGame(String phrase) {
switch (phrase) {
case "apples and pears":
System.out.println("Stairs");
break;
case "lorry":
System.out.println("truck");
break;
default:
System.out.println("Don't know any more");
}
}
Ternary Operator
Sometimes you have to check for a condition and set the value of a variable.
For ex.
String name;
if (A > B) {
name = "Billy";
} else {
name = "Jimmy";
}
The value of the variable is set to the value immediately after the condition, if the condition is true.
If the condition is false, the second value will be given to the variable.
Break
The break statement ends a loop (like for, while) or the evaluation of a switch statement.
Loop:
while(true) {
if(someCondition == 5) {
break;
}
}
The loop in the example would run forever. But when someCondition equals 5 at some point of
execution, then the loop ends.
If multiple loops are cascaded, only the most inner loop ends using break.
https://riptutorial.com/ 102
The try { ... } catch ( ... ) { ... } control structure is used for handling Exceptions.
A finally clause can be added after the catch. The finally clause would always be executed,
regardless of whether an exception was thrown.
outerloop:
for(...) {
innerloop:
for(...) {
if(condition1)
break outerloop;
if(condition2)
continue innerloop; // equivalent to: continue;
https://riptutorial.com/ 103
}
}
The continue statement is used to skip the remaining steps in the current iteration and start with
the next loop iteration. The control goes from the continue statement to the step value (increment
or decrement), if any.
The continue statement can also make the control of the program shift to the step value (if any) of
a named loop:
https://riptutorial.com/ 104
Chapter 14: Benchmarks
Introduction
Writing performance benchmarks in java is not as simple as getting System.currentTimeMillis() in
the beginning and in the end and calculating the difference. To write valid performance
benchmarks, one should use proper tools.
Examples
Simple JMH example
One of the tools for writing proper benchmark tests is JMH. Let's say we want to compare
performance of searching an element in HashSet vs TreeSet.
The easiest way to get JHM into your project - is to use maven and shade plugin. Also you can
see pom.xml from JHM examples.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>/benchmarks</finalName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
https://riptutorial.com/ 105
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.18</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.18</version>
</dependency>
</dependencies>
package benchmark;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
@State(Scope.Thread)
public class CollectionFinderBenchmarkTest {
private static final int SET_SIZE = 10000;
@Setup
public void setupCollections() {
hashSet = new HashSet<>(SET_SIZE);
treeSet = new TreeSet<>();
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void testHashSet(Blackhole blackhole) {
blackhole.consume(hashSet.contains(stringToFind));
}
@Benchmark
https://riptutorial.com/ 106
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void testTreeSet(Blackhole blackhole) {
blackhole.consume(treeSet.contains(stringToFind));
}
}
Please keep in mind this blackhole.consume(), we'll get back to it later. Also we need main class for
running benchmark:
package benchmark;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
new Runner(options).run();
}
}
And we're all set. We just need to run mvn package (it will create benchmarks.jar in your /target
folder) and run our benchmark test:
And after some warmup and calculation iterations, we will have our results:
About that blackhole.consume(). If your calculations do not change the state of your application,
java will most likely just ignore it. So, in order to avoid it, you can either make your benchmark
methods return some value, or use Blackhole object to consume it.
You can find more information about writing proper benchmarks in Aleksey Shipilëv's blog, in
Jacob Jenkov's blog and in java-performance blog: 1, 2.
https://riptutorial.com/ 107
Chapter 15: BigDecimal
Introduction
The BigDecimal class provides operations for arithmetic (add, subtract, multiply, divide), scale
manipulation, rounding, comparison, hashing, and format conversion. The BigDecimal represents
immutable, arbitrary-precision signed decimal numbers. This class shall be used in a necessity of
high-precision calculation.
Examples
BigDecimal objects are immutable
If you want to calculate with BigDecimal you have to use the returned value because BigDecimal
objects are immutable:
Comparing BigDecimals
Commonly you should not use the equals method since it considers two BigDecimals equal only if
they are equal in value and also scale:
This example shows how to perform basic mathematical operations using BigDecimals.
1.Addition
https://riptutorial.com/ 108
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a + b
BigDecimal result = a.add(b);
System.out.println(result);
Result : 12
2.Subtraction
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a - b
BigDecimal result = a.subtract(b);
System.out.println(result);
Result : -2
3.Multiplication
When multiplying two BigDecimals the result is going to have scale equal to the sum of the scales
of operands.
//Equivalent to result = a * b
BigDecimal result = a.multiply(b);
System.out.println(result);
Result : 36.89931
To change the scale of the result use the overloaded multiply method which allows passing
MathContext - an object describing the rules for operators, in particular the precision and rounding
mode of the result. For more information about available rounding modes please refer to the
Oracle Documentation.
//Equivalent to result = a * b
BigDecimal result = a.multiply(b, returnRules);
System.out.println(result);
Result : 36.90
https://riptutorial.com/ 109
4.Division
Division is a bit more complicated than the other arithmetic operations, for instance consider the
below example:
We would expect this to give something similar to : 0.7142857142857143, but we would get:
This would work perfectly well when the result would be a terminating decimal say if I wanted to
divide 5 by 2, but for those numbers which upon dividing would give a non terminating result we
would get an ArithmeticException. In the real world scenario, one cannot predict the values that
would be encountered during the division, so we need to specify the Scale and the Rounding
Mode for BigDecimal division. For more information on the Scale and Rounding Mode, refer the
Oracle Documentation.
Result : 0.7142857143
5.Remainder or Modulus
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a % b
BigDecimal result = a.remainder(b);
System.out.println(result);
Result : 5
6.Power
https://riptutorial.com/ 110
BigDecimal a = new BigDecimal("5");
Result : 9765625
7.Max
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
Result : 7
8.Min
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
Result : 5
Result : 52.3449843776
https://riptutorial.com/ 111
System.out.println(result);
Result : 5234498.43776
There are many more options and combination of parameters for the above mentioned examples
(For instance, there are 6 variations of the divide method), this set is a non-exhaustive list and
covers a few basic examples.
Due to way that the float type is represented in computer memory, results of operations using this
type can be inaccurate - some values are stored as approximations. Good examples of this are
monetary calculations. If high precision is necessary, other types should be used. e.g. Java 7
provides BigDecimal.
import java.math.BigDecimal;
For a starting balance of 10000.00, after 1000 operations for 1.99, we expect the balance to be
8010.00. Using the float type gives us an answer around 8009.77, which is unacceptably
imprecise in the case of monetary calculations. Using BigDecimal gives us the proper result.
https://riptutorial.com/ 112
BigDecimal.valueOf()
The BigDecimal class contains an internal cache of frequently used numbers e.g. 0 to 10. The
BigDecimal.valueOf() methods are provided in preference to constructors with similar type
parameters i.e. in the below example a is preferred to b.
BigDecimal provides static properties for the numbers zero, one and ten. It's good practise to use
these instead of using the actual numbers:
• BigDecimal.ZERO
• BigDecimal.ONE
• BigDecimal.TEN
By using the static properties, you avoid an unnecessary instantiation, also you've got a literal in
your code instead of a 'magic number'.
//Bad example:
BigDecimal bad0 = new BigDecimal(0);
BigDecimal bad1 = new BigDecimal(1);
BigDecimal bad10 = new BigDecimal(10);
//Good Example:
BigDecimal good0 = BigDecimal.ZERO;
BigDecimal good1 = BigDecimal.ONE;
BigDecimal good10 = BigDecimal.TEN;
https://riptutorial.com/ 113
Chapter 16: BigInteger
Introduction
The BigInteger class is used for mathematical operations involving large integers with magnitudes
too large for primitive data types. For example 100-factorial is 158 digits - much larger than a long
can represent. BigInteger provides analogues to all of Java's primitive integer operators, and all
relevant methods from java.lang.Math as well as few other operations.
Syntax
• BigInteger variable_name = new BigInteger("12345678901234567890"); // a decimal integer
as a string
• BigInteger variable_name = new
BigInteger("1010101101010100101010011000110011101011000111110000101011010010",
2) // a binary integer as a string
• BigInteger variable_name = new BigInteger("ab54a98ceb1f0800", 16) // a hexadecimal
integer as a string
• BigInteger variable_name = new BigInteger(64, new Random()); // a pseudorandom number
generator supplying 64 bits to construct an integer
• BigInteger variable_name = new BigInteger(new byte[]{0, -85, 84, -87, -116, -21, 31, 10, -
46}); // signed two's complement representation of an integer (big endian)
• BigInteger variable_name = new BigInteger(1, new byte[]{-85, 84, -87, -116, -21, 31, 10, -
46}); // unsigned two's complement representation of a positive integer (big endian)
Remarks
BigIntegeris immutable. Therefore you can't change its state. For example, the following won't
work as sum won't be updated due to immutability.
sum = sum.add(BigInteger.valueOf(i));
Java SE 8
The official documentation of BigInteger states that BigInteger implementations should support all
integers between -22147483647 and 22147483647 (exclusive). This means BigIntegers can have
more than 2 billion bits!
https://riptutorial.com/ 114
Examples
Initialization
The java.math.BigInteger class provides operations analogues to all of Java's primitive integer
operators and for all relevant methods from java.lang.Math. As the java.math package is not
automatically made available you may have to import java.math.BigInteger before you can use the
simple class name.
which will widen the intValue integer to long, using sign bit extension for negative values, so that
negative values will stay negative.
Following constructor is used to translate the String representation of a BigInteger in the specified
radix into a BigInteger.
Java also supports direct conversion of bytes to an instance of BigInteger. Currently only signed
and unsigned big endian encoding may be used:
This will generate a BigInteger instance with value -128 as the first bit is interpreted as the sign bit.
This will generate a BigInteger instance with value 128 as the bytes are interpreted as unsigned
https://riptutorial.com/ 115
number, and the sign is explicitly set to 1, a positive number.
There's also BigInteger.TWO (value of "2"), but you can't use it in your code because it's private.
Comparing BigIntegers
You can compare BigIntegers same as you compare String or other objects in Java.
For example:
if(one.equals(two)){
System.out.println("Equal");
}
else{
System.out.println("Not Equal");
}
Output:
Not Equal
Note:
• == operator: compares references; i.e. whether two values refer to the same object
• equals() method: compares the content of two BigIntegers.
if (firstBigInteger == secondBigInteger) {
// Only checks for reference equality, not content equality!
}
Doing so may lead to unexpected behavior, as the == operator only checks for reference equality.
If both BigIntegers contain the same content, but do not refer to the same object, this will fail.
Instead, compare BigIntegers using the equals methods, as explained above.
You can also compare your BigInteger to constant values like 0,1,10.
for example:
https://riptutorial.com/ 116
BigInteger reallyBig = BigInteger.valueOf(1);
if(BigInteger.ONE.equals(reallyBig)){
//code when they are equal.
}
You can also compare two BigIntegers by using compareTo() method, as following: compareTo()
returns 3 values.
if(reallyBig.compareTo(reallyBig1) == 0){
//code when both are equal.
}
else if(reallyBig.compareTo(reallyBig1) == 1){
//code when reallyBig is greater than reallyBig1.
}
else if(reallyBig.compareTo(reallyBig1) == -1){
//code when reallyBig is less than reallyBig1.
}
BigInteger is in an immutable object, so you need to assign the results of any mathematical
operation, to a new BigInteger instance.
Addition: 10 + 10 = 20
output: 20
Substraction: 10 - 9 = 1
output: 1
Division: 10 / 5 = 2
https://riptutorial.com/ 117
BigInteger value1 = new BigInteger("10");
BigInteger value2 = new BigInteger("5");
output: 2
Division: 17/4 = 4
output: 4
Multiplication: 10 * 5 = 50
output: 50
Power: 10 ^ 3 = 1000
output: 1000
Remainder: 10 % 6 = 4
output: 4
System.out.println(value1.gcd(value2));
https://riptutorial.com/ 118
Output: 6
System.out.println(value1.max(value2));
Output: 11
System.out.println(value1.min(value2));
Output: 10
BigInteger supports the binary logic operations that are available to Number types as well. As with
all operations they are implemented by calling a method.
Binary Or:
val1.or(val2);
Binary And:
val1.and(val2);
Binary Xor:
val1.xor(val2);
https://riptutorial.com/ 119
RightShift:
LeftShift:
val1.not();
Output: 5
NAND (And-Not):*
val1.andNot(val2);
Output: 7
The BigInteger class has a constructor dedicated to generate random BigIntegers, given an
instance of java.util.Random and an int that specifies how many bits will the BigInteger have. Its
usage is quite simple - when you call the constructor BigInteger(int, Random) like this:
then you'll end up with a BigInteger whose value is between 0 (inclusive) and 2bitCount
(exclusive).
This also means that new BigInteger(2147483647, sourceOfRandomness) may return all positive
BigIntegers given enough time.
What will the sourceOfRandomness be is up to you. For example, a new Random() is good enough in
most cases:
https://riptutorial.com/ 120
new BigInteger(32, new Random());
If you're willing to give up speed for higher-quality random numbers, you can use a new
SecureRandom() instead:
import java.security.SecureRandom;
You can even implement an algorithm on-the-fly with an anonymous class! Note that rolling out
your own RNG algorithm will end you up with low quality randomness, so always be sure to
use an algorithm that is proven to be decent unless you want the resulting BigInteger(s) to be
predictable.
@Override
protected int next(int bits) {
seed = ((22695477 * seed) + 1) & 2147483647; // Values shamelessly stolen from
Wikipedia
return seed;
}
});
https://riptutorial.com/ 121
Chapter 17: Bit Manipulation
Remarks
• Unlike C/C++, Java is completely endian-neutral with respect to the underlying machine
hardware. You do not get big or little endian behavior by default; you have to explicitly
specify which behavior you want.
• The byte type is signed, with the range -128 to +127. To convert a byte value to its unsigned
equivalent, mask it with 0xFF like this: (b & 0xFF).
Examples
Packing / unpacking values as bit fragments
It is common for memory performance to compress multiple values into a single primitive value.
This may be useful to pass various information into a single variable.
For example, one can pack 3 bytes - such as color code in RGB - into an single int.
https://riptutorial.com/ 122
(byte)(x >> 16)
};
Checking, setting, clearing, and toggling individual bits. Using long as bit
mask
Assuming we want to modify bit n of an integer primitive, i (byte, short, char, int, or long):
Prints
FIRST_BIT: true
SECOND_BIT: false
THIRD_BIT: true
FOURTh_BIT: false
FIFTH_BIT: true
BIT_55: true
which matches that mask we passed as checkBitMask parameter: FIRST_BIT | THIRD_BIT | FIFTH_BIT
| BIT_55.
For expressing the power of 2 (2^n) of integers, one may use a bitshift operation that allows to
explicitly specify the n.
https://riptutorial.com/ 123
The syntax is basically:
Examples:
This is especially useful when defining constant values that should make it apparent, that a power
of 2 is used, instead of using hexadecimal or decimal values.
If an integer x is a power of 2, only one bit is set, whereas x-1 has all bits set after that. For
example: 4 is 100 and 3 is 011 as binary number, which satisfies the aforementioned condition. Zero
is not a power of 2 and has to be checked explicitly.
boolean isPowerOfTwo(int x)
{
return (x != 0) && ((x & (x - 1)) == 0);
}
Let’s suppose, we have three kind of permissions, READ, WRITE and EXECUTE. Each
permission can range from 0 to 7. (Let’s assume 4 bit number system)
How can we get the (12 bit number) permissions, set on above (12 bit number)?
https://riptutorial.com/ 124
0000 0000 0111 (&)
So, this is how we can get the EXECUTE permissions of the RESOURCE. Now, what if we want
to get READ permissions of the RESOURCE?
Right? You are probably assuming this? But, permissions are resulted in 1024. We want to get
only READ permissions for the resource. Don’t worry, that’s why we had the shift operators. If we
see, READ permissions are 8 bits behind the actual result, so if apply some shift operator, which
will bring READ permissions to the very right of the result? What if we do:
0100 0000 0000 >> 8 => 0000 0000 0100 (Because it’s a positive number so replaced
with 0’s, if you don’t care about sign, just use unsigned right shift operator)
Now, for example, we are given READ, WRITE, EXECUTE permissions for a RESOURCE, what
can we do to make permissions for this RESOURCE?
Let’s first take the example of binary permissions. (Still assuming 4 bit number system)
READ = 0001
WRITE = 0100
EXECUTE = 0110
But permissions are actually being represented (in our example) as 0001 0100 0110
So, in order to do this, we know that READ is placed 8 bits behind, WRITE is placed 4 bits behind
and PERMISSIONS is placed at the last. The number system being used for RESOURCE
permissions is actually 12 bit (in our example). It can(will) be different in different systems.
https://riptutorial.com/ 125
0001 0000 0000 (Left shift by 8 bits)
java.util.BitSet class
Since 1.7 there's a java.util.BitSet class that provides simple and user-friendly bit storage and
manipulation interface:
final BitSet bitSet = new BitSet(8); // by default all bits are unset
bitSet.set(3); // {0, 2, 3, 4, 6}
bitSet.flip(6); // {0, 2, 4}
BitSet implements Clonable and Serializable, and under the hood all bit values are stored in long[]
words field, that expands automatically.
bitSet.and(new BitSet(8));
bitSet.or(new BitSet(8));
bitSet.xor(new BitSet(8));
bitSet.andNot(new BitSet(8));
In Java, all number primitives are signed. For example, an int always represent values from [-2^31
- 1, 2^31], keeping the first bit to sign the value - 1 for negative value, 0 for positive.
https://riptutorial.com/ 126
Basic shift operators >> and << are signed operators. They will conserve the sign of the value.
But it is common for programmers to use numbers to store unsigned values. For an int, it means
shifting the range to [0, 2^32 - 1], to have twice as much value as with a signed int.
For those power users, the bit for sign as no meaning. That's why Java added >>>, a left-shift
operator, disregarding that sign bit.
This comes from the intended definition of right-shift. As it fills the emptied places on the left, there
are no decision to take regarding the bit of sign. As a consequence, there is no need for 2 different
operators.
https://riptutorial.com/ 127
Chapter 18: BufferedWriter
Syntax
• new BufferedWriter(Writer); //The default constructor
• BufferedWriter.write(int c); //Writes a single character
• BufferedWriter.write(String str); //Writes a string
• BufferedWriter.newLine(); //Writes a line separator
• BufferedWriter.close(); //Closes the BufferedWriter
Remarks
• If you try to write from a BufferedWriter (using BufferedWriter.write()) after closing the
BufferedWriter (using BufferedWriter.close()), it will throw an IOException.
• The BufferedWriter(Writer) constructor does NOT throw an IOException. However, the
FileWriter(File) constructor throws a FileNotFoundException, which extends IOException. So
catching IOException will also catch FileNotFoundException, there is never a need for a second
catch statement unless you plan on doing something different with the FileNotFoundException.
Examples
Write a line of text to File
This code writes the string to a file. It is important to close the writer, so this is done in a finally
block.
Also note that write(String s) does not place newline character after string has been written. To
put it use newLine() method.
Java SE 7
https://riptutorial.com/ 128
Path path = Paths.get("file.txt");
try (BufferedWriter bw = Files.newBufferedWriter(path)) {
bw.write(str);
}
}
https://riptutorial.com/ 129
Chapter 19: ByteBuffer
Introduction
The ByteBuffer class was introduced in java 1.4 to ease working on binary data. It's especially
suited to use with primitive type data. It allows the creation, but also subsequent manipulation of a
byte[]s on a higher abstraction level
Syntax
• byte[] arr = new byte[1000];
• ByteBuffer buffer = ByteBuffer.wrap(arr);
• ByteBuffer buffer = ByteBuffer.allocate(1024);
• ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
• byte b = buffer.get();
• byte b = buffer.get(10);
• short s = buffer.getShort(10);
• buffer.put((byte) 120);
• buffer.putChar('a');
Examples
Basic Usage - Creating a ByteBuffer
There's two ways to create a ByteBuffer, where one can be subdivided again.
If you have an already existing byte[], you can "wrap" it into a ByteBuffer to simplify processing:
This would be a possibility for code that handles low-level networking interactions
If you do not have an already existing byte[], you can create a ByteBuffer over an array that's
specifically allocated for the buffer like this:
If the code-path is extremely performance critical and you need direct system memory access,
the ByteBuffer can even allocate direct buffers using #allocateDirect()
https://riptutorial.com/ 130
Basic Usage - Write Data to the Buffer
Given a ByteBuffer instance one can write primitive-type data to it using relative and absolute put.
The striking difference is that putting data using the relative method keeps track of the index the
data is inserted at for you, while the absolute method always requires giving an index to put the
data at.
Both methods allow "chaining" calls. Given a sufficiently sized buffer one can accordingly do the
following:
buffer.putInt(0xCAFEBABE).putChar('c').putFloat(0.25).putLong(0xDEADBEEFCAFEBABE);
buffer.putInt(0xCAFEBABE);
buffer.putChar('c');
buffer.putFloat(0.25);
buffer.putLong(0xDEADBEEFCAFEBABE);
Do note that the method operating on bytes is not named specially. Additionally note that it's also
valid to pass both a ByteBuffer and a byte[] to put. Other than that, all primitive types have
specialized put-methods.
An additional note: The index given when using absolute put* is always counted in bytes.
This operation will allocate 16 bytes of memory. The contents of direct buffers may reside outside
of the normal garbage-collected heap.
directBuffer.isDirect(); // true
The main characteristics of DirectByteBuffer is that JVM will try to natively work on allocated
memory without any additional buffering so operations performed on it may be faster then those
performed on ByteBuffers with arrays lying underneath.
It is recomended to use DirectByteBuffer with heavy IO operations that rely on speed of execution,
like real time communication.
We have to be aware that if we try using array() method we will get UnsupportedOperationException.
https://riptutorial.com/ 131
So it is a good practice to chech whether our ByteBuffer has it (byte array) before we try to access
it:
byte[] arrayOfBytes;
if(buffer.hasArray()) {
arrayOfBytes = buffer.array();
}
Another use of direct byte buffer is interop through JNI. Since a direct byte buffer does not use a
byte[], but an actual block of memory, it is possible to access that memory directly through a
pointer in native code. This can save a bit of trouble and overhead on marshalling between the
Java and native representation of data.
The JNI interface defines several functions to handle direct byte buffers: NIO Support.
https://riptutorial.com/ 132
Chapter 20: Bytecode Modification
Examples
What is Bytecode?
Bytecode is the set of instructions used by the JVM. To illustrate this let's take this Hello World
program.
ldc - Push a constant onto the stack. In this case, the String "Hello World"
invokevirtual - Invokes a method on a loaded reference on the stack and puts the result on the
stack. Parameters of the method are also taken from the stack.
For writing:
• Jasmin
https://riptutorial.com/ 133
• Krakatau
For editing:
• Libraries
○ASM
○Javassist
○BCEL - Doesn't support Java 8+
• Tools
○Bytecode-Viewer
○JBytedit
○reJ - Doesn't support Java 8+
○JBE - Doesn't support Java 8+
Firstly the classes from the jar need to be loaded. We'll use three methods for this process:
• loadClasses(File)
• readJar(JarFile, JarEntry, Map)
• getNode(byte[])
https://riptutorial.com/ 134
}
}
} catch (IOException e) {
e.printStackTrace();
}
return classes;
}
With these methods loading and changing a jar file becomes a simple matter of changing
ClassNodes in a map. In this example we will replace all Strings in the jar with capitalized ones
using the Tree API.
Now that all of the ClassNode's strings have been modified we need to save the changes. In order
to save the changes and have a working output a few things have to be done:
https://riptutorial.com/ 135
• saveAsJar(Map<String, byte[]> outBytes, String fileName)
Usage:
https://riptutorial.com/ 136
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Load a class by from a ClassNode
*
* @param cn
* ClassNode to load
* @return
*/
public static Class<?> load(ClassNode cn) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
return new ClassDefiner(ClassLoader.getSystemClassLoader()).get(cn.name.replace("/", "."),
cw.toByteArray());
}
/**
* Classloader that loads a class from bytes.
*/
static class ClassDefiner extends ClassLoader {
public ClassDefiner(ClassLoader parent) {
super(parent);
}
https://riptutorial.com/ 137
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassVisitor remapper = new ClassRemapper(cw, mapper);
cn.accept(remapper);
out.put(mappings.containsKey(cn.name) ? mappings.get(cn.name) : cn.name,
cw.toByteArray());
}
return out;
}
SimpleRemapper is an existing class in the ASM library. However it only allows for class names to
be changed. If you wish to rename fields and methods you should create your own implemenation
of the Remapper class.
Javassist Basic
Javassist is a bytecode instrumentation library that allows you to modify bytecode injecting Java
code that will be converted to bytecode by Javassist and added to the instrumented class/method
at runtime.
Lets write the first transformer that actually take an hypothetical class
"com.my.to.be.instrumented.MyClass" and add to the instructions of each method a log call.
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
try {
// retrive default Javassist class pool
ClassPool cp = ClassPool.getDefault();
// get from the class pool our class with this qualified name
CtClass cc = cp.get("com.my.to.be.instrumented.MyClass");
// get all the methods of the retrieved class
CtMethod[] methods = cc.getDeclaredMethods()
for(CtMethod meth : methods) {
// The instrumentation code to be returned and injected
final StringBuffer buffer = new StringBuffer();
String name = meth.getName();
// just print into the buffer a log for example
buffer.append("System.out.println(\"Method " + name + " executed\" );");
meth.insertBefore(buffer.toString())
}
// create the byteclode of the class
https://riptutorial.com/ 138
byteCode = cc.toBytecode();
// remove the CtClass from the ClassPool
cc.detach();
} catch (Exception ex) {
ex.printStackTrace();
}
}
return byteCode;
}
}
Now in order to use this transformer (so that our JVM will call the method transform on each class
at load time) we need to add this instrumentor this with an agent:
import java.lang.instrument.Instrumentation;
Last step to start our first instrumentor experiment is to actually register this agent class to the
JVM machine execution. The easiest way to actually do it is to register it with an option into the
shell command:
As we can see the agent/transformer project is added as a jar to the execution of any application
named MyJavaApplication that is supposed to contain a class named
"com.my.to.be.instrumented.MyClass" to actually execute our injected code.
https://riptutorial.com/ 139
Chapter 21: C++ Comparison
Introduction
Java and C++ are similar languages. This topic serves as a quick reference guide for Java and
C++ Engineers.
Remarks
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Java
[non-static] Nested Class (aka Inner Class or Member Class)
class OuterClass {
...
class InnerClass {
...
}
}
https://riptutorial.com/ 140
Static Nested Class
class Outer {
class Inner {
...
};
};
Java
Static Nested Class (aka Static Member Class)[ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
C++
Local Class[ref]
void fun() {
class Test {
/* members of Test class */
};
}
Java
Local Class[ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
https://riptutorial.com/ 141
Overriding vs Overloading
The following Overriding vs Overloading points apply to both C++ and Java:
• An overridden method has the same name and arguments as its base method.
• An overloaded method has the same name but different arguments and does not rely on
inheritance.
• Two methods with the same name and arguments but different return type are illegal. See
related Stackoverflow questions about "overloading with different return type in Java" -
Question 1; Question 2
Polymorphism
Polymorphism is the ability for objects of different classes related by inheritance to respond
differently to the same method call. Here's an example:
In C++, polymorphism is enabled by virtual methods. In Java, methods are virtual by default.
Order of Construction/Destruction
Object Cleanup
In C++, it's a good idea to declare a destructor as virtual to ensure that the subclass' destructor will
be called if the base-class pointer is deleted.
In Java, a finalize method is similar a destructor in C++; however, finalizers are unpredictable
(they rely on GC). Best practice - use a "close" method to explicitly cleanup.
https://riptutorial.com/ 142
finally {
super.finalize();
}
}
Abstract Method
declared without an pure virtual method abstract method
virtual void eat(void) = 0; abstract void draw();
implementation
Accessibility Modifiers
Modifier C++ Java
Public - accessible
no special notes no special notes
by all
Protected -
also accessible within
accessible by also accessible by friends
same package
subclasses
Private - accessible
also accessible by friends no special notes
by members
https://riptutorial.com/ 143
class Node {
private:
int key; Node *next;
// LinkedList::search() can access "key" & "next"
friend int LinkedList::search();
};
While C++ has always been susceptible to the diamond problem, Java was susceptible until Java
8. Originally, Java didn't support multiple inheritance, but with the advent of default interface
methods, Java classes can not inherit "implementation" from more than one class.
java.lang.Object Class
In Java all classes inherit, either implicitly or explicitly, from the Object class. Any Java reference
can be cast to the Object type.
Integer Types
C++ Type
Bits Min Max (on LLP64 or Java Type
LP64)
https://riptutorial.com/ 144
C++ Type
Bits Min Max (on LLP64 or Java Type
LP64)
-2(32-1) = -2.147
32 2(32-1)-1 = 2.147 billion int int
billion
unsigned long*
64 0 2(16)-1 --
unsigned long long
Examples
Static Class Members
C++ Example
// define in header
class Singleton {
public:
static Singleton *getInstance();
private:
Singleton() {}
static Singleton *instance;
};
// initialize in .cpp
Singleton* Singleton::instance = 0;
Java Example
https://riptutorial.com/ 145
private Singleton() {}
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Java
[non-static] Nested Class (aka Inner Class or Member Class)
class OuterClass {
...
class InnerClass {
...
}
}
class Outer {
class Inner {
...
https://riptutorial.com/ 146
};
};
Java
Static Nested Class (aka Static Member Class)[ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
C++
Local Class[ref]
void fun() {
class Test {
/* members of Test class */
};
}
Java
Local Class[ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
Many argue that Java is ONLY pass-by-value, but it's more nuanced than that. Compare the
following C++ and Java examples to see the many flavors of pass-by-value (aka copy) and pass-
by-reference (aka alias).
https://riptutorial.com/ 147
C++ Example (complete code)
// passes a COPY of the object
static void passByCopy(PassIt obj) {
obj.i = 22; // only a "local" change
}
// passes a pointer
static void passByPointer(PassIt* ptr) {
ptr->i = 33;
ptr = 0; // better to use nullptr instead if '0'
}
https://riptutorial.com/ 148
Inheritance vs Composition
C++ & Java are both object-oriented languages, thus the following diagram applies to both.
Outcast Downcasting
Beware of using "downcasting" - Downcasting is casting down the inheritance hierarchy from a
base class to a subclass (i.e. opposite of polymorphism). In general, use polymorphism &
overriding instead of instanceof & downcasting.
C++ Example
// explicit type case required
Child *pChild = (Child *) &parent;
Java Example
if(mySubClass instanceof SubClass) {
SubClass mySubClass = (SubClass)someBaseClass;
mySubClass.nonInheritedMethod();
}
Abstract Method
declared without an implementation
C++
pure virtual method
Java
abstract method
https://riptutorial.com/ 149
Abstract Class
cannot be instantiated
C++
cannot be instantiated; has at least 1 pure virtual method
Java
cannot be instantiated; can have non-abstract methods
Interface
no instance fields
C++
nothing comparable to Java
Java
very similar to abstract class, but 1) supports multiple inheritance; 2) no instance fields
interface TestInterface {}
https://riptutorial.com/ 150
Chapter 22: Calendar and its Subclasses
Remarks
As of Java 8, Calendar and its subclasses have been superseded by the java.time package and its
subpackages. They should be preferred, unless a legacy API requires Calendar.
Examples
Creating Calendar objects
It's important to notice that months in Calendar are zero based, which means that JANUARY is
represented by an int value 0. In order to provide a better code, always use Calendar constants,
such as Calendar.JANUARY to avoid misunderstandings.
Note: Always use the month constants: The numeric representation is misleading, e.g.
Calendar.JANUARY has the value 0
The add() method affects all fields, and behaves effectively if one were to add or subtract actual
dates from the calendar
calendar.add(Calendar.MONTH, -6);
The above operation removes six months from the calendar, taking us back to 30 September
2015.
To change a particular field without affecting the other fields, use roll().
calendar.roll(Calendar.MONTH, -6);
The above operation removes six months from the current month, so the month is identified as
https://riptutorial.com/ 151
September. No other fields have been adjusted; the year has not changed with this operation.
Finding AM/PM
Subtracting calendars
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c2.set(Calendar.DATE, c2.get(Calendar.DATE) + 1);
https://riptutorial.com/ 152
Chapter 23: Character encoding
Examples
Reading text from a file encoded in UTF-8
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
String line;
while ((line = reader.readLine()) != null) {
System.out.print(line);
}
}
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
https://riptutorial.com/ 153
wr.write("Cyrillic symbol Ы");
}
}
}
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
System.out.println(Arrays.toString(textInUtf8));
}
}
https://riptutorial.com/ 154
Chapter 24: Choosing Collections
Introduction
Java offers a wide variety of Collections. Choosing which Collection to use can be tricky. See the
Examples section for an easy-to-follow flowchart to choose the right Collection for the job.
Examples
Java Collections Flowchart
Use the following flowchart to choose the right Collection for the job.
https://riptutorial.com/ 155
Chapter 25: Class - Java Reflection
Introduction
The java.lang.Class class provides many methods that can be used to get metadata, examine and
change the run time behavior of a class.
The java.lang and java.lang.reflect packages provide classes for java reflection.
Where it is used
IDE (Integrated Development Environment) e.g. Eclipse, MyEclipse, NetBeans etc. Debugger Test
Tools etc.
Examples
getClass() method of Object class
class Simple { }
class Test {
void printName(Object obj){
Class c = obj.getClass();
System.out.println(c.getName());
}
public static void main(String args[]){
Simple s = new Simple();
https://riptutorial.com/ 156
Chapter 26: Classes and Objects
Introduction
Objects have states and behaviors. Example: A dog has states - color, name, breed as well as
behaviors – wagging the tail, barking, eating. An object is an instance of a class.
Class − A class can be defined as a template/blueprint that describes the behavior/state that the
object of its type support.
Syntax
• class Example {} //class keyword, name, body
Examples
Simplest Possible Class
class TrivialClass {}
A class consists at a minimum of the class keyword, a name, and a body, which might be empty.
class ObjectMemberVsStaticMember {
void increment() {
staticCounter ++;
memberCounter++;
}
}
o1.increment();
https://riptutorial.com/ 157
o2.increment();
o2.increment();
System.out.println("ObjectMemberVsStaticMember.staticCounter = " +
ObjectMemberVsStaticMember.staticCounter);
o1 static counter 3
o1 member counter 1
o2 static counter 3
o2 member counter 2
ObjectMemberVsStaticMember.staticCounter = 3
Note: You should not call static members on objects, but on classes. While it does not make a
difference for the JVM, human readers will appreciate it.
static members are part of the class and exists only once per class. Non-static members exist on
instances, there is an independent copy for each instance. This also means that you need access
to an object of that class to access its members.
Overloading Methods
Sometimes the same functionality has to be written for different kinds of inputs. At that time, one
can use the same method name with a different set of parameters. Each different set of
parameters is known as a method signature. As seen per the example, a single method can have
multiple signatures.
https://riptutorial.com/ 158
Displayer displayer = new Displayer();
displayer.displayName("Ram"); //prints "Name is: Ram"
displayer.displayName("Jon", "Skeet"); //prints "Name is: Jon Skeet"
}
}
The advantage is that the same functionality is called with two different numbers of inputs. While
invoking the method according to the input we are passing, (In this case either one string value or
two string values) the corresponding method is executed.
Note: Methods cannot be overloaded by changing just the return type (int method() is considered
the same as String method() and will throw a RuntimeException if attempted). If you change the
return type you must also change the parameters in order to overload.
Objects come in their own class, so a simple example would be a car (detailed explanations
below):
public Car(){
milesPerGallon = 0;
name = "";
color = "";
numGallonsInTank = 0;
}
https://riptutorial.com/ 159
public void drive(int distanceInMiles){
//get miles left in car
int miles = numGallonsInTank * milesPerGallon;
Objects are instances of their class. So, the way you would create an object would be by calling
the Car class in one of two ways in your main class (main method in Java or onCreate in
Android).
Option 1
Option 1 is where you essentially tell the program everything about the Car upon creation of the
object. Changing any property of the car would require calling one of the methods such as the
repaintCar method. Example:
https://riptutorial.com/ 160
newCar.repaintCar("Blue");
Note: Make sure you pass the correct data type to the method. In the example above, you may
also pass a variable to the repaintCar method as long as the data type is correct`.
That was an example of changing properties of an object, receiving properties of an object would
require using a method from the Car class that has a return value (meaning a method that is not
void). Example:
Option 1 is the best option when you have all the object's data at the time of creation.
Option 2
Option 2 gets the same effect but required more work to create an object correctly. I want to recall
this Constructor in the Car class:
Notice that you do not have to actually pass any parameters into the object to create it. This is
very useful for when you do not have all the aspects of the object but you need to use the parts
that you do have. This sets generic data into each of the instance variables of the object so that, if
you call for a piece of data that does not exist, no errors are thrown.
Note: Do not forget that you have to set the parts of the object later that you did not initialize it
with. For example,
This is a common mistake amongst objects that are not initialized with all their data. Errors were
avoided because there is a Constructor that allows an empty Car object to be created with stand-
in variables (public Car(){}), but no part of the myCar was actually customized. Correct example
of creating Car Object:
https://riptutorial.com/ 161
And, as a reminder, get an object's properties by calling a method in your main class. Example:
Constructors
Constructors are special methods named after the class and without a return type, and are used to
construct objects. Constructors, like methods, can take input parameters. Constructors are used to
initialize objects. Abstract classes can have constructors also.
It is important to understand that constructors are different from methods in several ways:
1. Constructors can only take the modifiers public, private, and protected, and cannot be
declared abstract, final, static, or synchronized.
3. Constructors MUST be named the same as the class name. In the Hello example, the Hello
object's constructor name is the same as the class name.
4. The this keyword has an additional usage inside constructors. this.method(...) calls a
method on the current instance, while this(...) refers to another constructor in the current
class with different signatures.
Constructors also can be called through inheritance using the keyword super.
public SuperManClass(){
// some implementation
}
// ... methods
}
https://riptutorial.com/ 162
}
To initialize a static final fields that require using more than a single expression, a static
initializer can be used to assign the value. The following example initializes a unmodifiable set of
Strings:
static {
Set<String> set = new HashSet<>();
set.add("Hello");
set.add("World");
set.add("foo");
set.add("bar");
set.add("42");
WORDS = Collections.unmodifiableSet(set);
}
}
Method Overriding and Overloading are two forms of polymorphism supported by Java.
Method Overloading
Method overloading (also known as static Polymorphism) is a way you can have two (or more)
methods (functions) with same name in a single class. Yes its as simple as that.
This way user can call the same method for area depending on the type of shape it has.
But the real question now is, how will java compiler will distinguish which method body is to be
executed?
https://riptutorial.com/ 163
Well Java have made it clear that even though the method names (area() in our case) can be
same but the arguments method is taking should be different.
Overloaded methods must have different arguments list (quantity and types).
That being said we cannot add another method to calculate area of a square like this : public
Double area(Long side) because in this case, it will conflict with area method of circle and will cause
ambiguity for java compiler.
Thank god, there are some relaxations while writing overloaded methods like
Well that's because which overloaded methods is to be invoked is decided at compile time, based
on the actual number of arguments and the compile-time types of the arguments.
Method Overriding
Well, method overriding (yes you guess it right, it is also known as dynamic polymorphism) is
somewhat more interesting and complex topic.
In method overriding we overwrite the method body provided by the parent class. Got it? No? Let's
go through an example.
So we have a class called Shape and it has method called area which will probably return the area
https://riptutorial.com/ 164
of the shape.
Let's say now we have two classes called Circle and Rectangle.
// See this annotation @Override, it is telling that this method is from parent
// class Shape and is overridden here
@Override
public Double area(){
return 3.14 * radius * radius;
}
}
// See this annotation @Override, it is telling that this method is from parent
// class Shape and is overridden here
@Override
public Double area(){
return length * breadth;
}
}
So, now both of your children classes have updated method body provided by the parent (Shape)
class. Now question is how to see the result? Well lets do it the old psvm way.
// Drumbeats ......
//This should print 78.5
System.out.println("Shape of circle : "+circle.area());
}
}
Wow! isn't it great? Two objects of same type calling same methods and returning different values.
My friend, that's the power of dynamic polymorphism.
https://riptutorial.com/ 165
Method Overloading Method Overriding
Method overloading is the example of compile time Method overriding is the example of
polymorphism. run time polymorphism.
https://riptutorial.com/ 166
Chapter 27: Classloaders
Remarks
A classloader is a class whose primary purpose is to mediate the location and loading of classes
used by an application. A class loader can also find and loaded resources.
The standard classloader classes can load classes and resources from directories in the file
system and from JAR and ZIP files. They can also download and cache JAR and ZIP files from a
remote server.
Classloaders are normally chained, so that the JVM will try to load classes from the standard class
libraries in preference to application-provided sources. Custom classloaders allow the programmer
to alter this. The also can do such things as decrypting bytecode files and bytecode modification.
Examples
Instantiating and using a classloader
This basic example shows how an application can instantiate a classloader and use it to
dynamically load a class.
The classloader created in this example will have the default classloader as its parent, and will first
try to find any class in the parent classloader before looking in "extra.jar". If the requested class
has already been loaded, the findClass call will return the reference to the previously loaded class.
The findClass call can fail in a variety of ways. The most common are:
• If the named class cannot be found, the call with throw ClassNotFoundException.
• If the named class depends on some other class that cannot be found, the call will throw
NoClassDefFoundError.
Every custom loader must directly or indirectly extend the java.lang.ClassLoader class. The main
extension points are the following methods:
https://riptutorial.com/ 167
The defineClass methods which are responsible for actually loading the class from a byte array are
final to prevent overloading. Any custom behavior needs to be performed prior to calling
defineClass.
@Override
protected Class findClass(String classname) throws ClassNotFoundException {
if (classname.equals(this.classname)) {
return defineClass(classname, classfile, 0, classfile.length);
} else {
throw new ClassNotFoundException(classname);
}
}
}
Since we have only overridden the findClass method, this custom class loader is going to behave
as follows when loadClass is called.
1. The classloader's loadClass method calls findLoadedClass to see if a class with this name has
already been loaded by this classloader. If that succeeds, the resulting Class object is
returned to the requestor.
2. The loadClass method then delegates to the parent classloader by calling its loadClass call. If
the parent can deal with the request, it will return a Class object which is then returned to the
requestor.
3. If the parent classloader cannot load the class, findClass then calls our override findClass
method, passing the name of the class to be loaded.
4. If the requested name matches this.classname, we call defineClass to load the actual class
from the this.classfile byte array. The resulting Class object is then returned.
5. If the name did not match, we throw ClassNotFoundException.
To load a class we first need to define it. The class is defined by the ClassLoader. There's just one
problem, Oracle didn't write the ClassLoader's code with this feature available. To define the class
we will need to access a method named defineClass() which is a private method of the ClassLoader
.
To access it, what we will do is create a new class, ByteClassLoader, and extend it to ClassLoader.
Now that we have extended our class to ClassLoader, we can access the ClassLoader's private
methods. To make defineClass() available, we will create a new method that will act like a mirror
for the private defineClass() method. To call the private method we will need the class name, name,
https://riptutorial.com/ 168
the class bytes, classBytes, the first byte's offset, which will be 0 because classBytes' data starts at
classBytes[0], and the last byte's offset, which will be classBytes.lenght because it represents the
size of the data, which will be the last offset.
Now, we have a public defineClass() method. It can be called by passing the name of the class
and the class bytes as arguments.
To call the method we need the class bytes so we create a Path object representing our class' path
by using the Paths.get() method and passing the path of the binary class as an argument. Now,
we can get the class bytes with Files.readAllBytes(path). So we create a ByteClassLoader instance
and use the method we created, defineClass(). We already have the class bytes but to call our
method we also need the class name which is given by the package name (dot) the class
canonical name, in this case stackoverflow.MyClass.
Note: The defineClass() method returns a Class<?> object. You can save it if you want.
To load the class, we just call loadClass() and pass the class name. This method can throw an
ClassNotFoundException so we need to use a try cath block
try{
loader.loadClass("stackoverflow.MyClass");
} catch(ClassNotFoundException e){
e.printStackTrace();
}
https://riptutorial.com/ 169
Chapter 28: Collection Factory Methods
Introduction
The arrival of Java 9 brings many new features to Java's Collections API, one of which being
collection factory methods. These methods allow for easy initialization of immutable collections,
whether they be empty or nonempty.
Note that these factory methods are only available for the following interfaces: List<E>, Set<E>, and
Map<K, V>
Syntax
• static <E> List<E> of()
• static <E> List<E> of(E e1)
• static <E> List<E> of(E e1, E e2)
• static <E> List<E> of(E e1, E e2, ..., E e9, E e10)
• static <E> List<E> of(E... elements)
• static <E> Set<E> of()
• static <E> Set<E> of(E e1)
• static <E> Set<E> of(E e1, E e2)
• static <E> Set<E> of(E e1, E e2, ..., E e9, E e10)
• static <E> Set<E> of(E... elements)
• static <K,V> Map<K,V> of()
• static <K,V> Map<K,V> of(K k1, V v1)
• static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2)
• static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, ..., K k9, V v9, K k10, V v10)
• static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)
Parameters
Map.of(Map.Entry<? extends K, ? A Map.Entry instance where its key can be K or one of its
extends V> entry) children, and its value can be V or any of its children.
Examples
List Factory Method Examples
https://riptutorial.com/ 170
• List<Integer> immutableEmptyList = List.of();
○ Initializes an empty, immutable List<Integer>.
• List<Integer> immutableList = List.of(1, 2, 3, 4, 5);
○ Initializes an immutable List<Integer> with five initial elements.
• List<Integer> mutableList = new ArrayList<>(immutableList);
○ Initializes a mutable List<Integer> from an immutable List<Integer>.
https://riptutorial.com/ 171
Chapter 29: Collections
Introduction
The collections framework in java.util provides a number of generic classes for sets of data with
functionality that can't be provided by regular arrays.
Collections framework contains interfaces for Collection<O>, with main sub-interfaces List<O> and
Set<O>, and mapping collection Map<K,V>. Collections are the root interface and are being
implemented by many other collection frameworks.
Remarks
Collections are objects that can store collections of other objects inside of them. You can specify
the type of data stored in a collection using Generics.
Java SE 1.4
Java 1.4.2 and below do not support generics. As such, you can not specify the type parameters
that a collection contains. In addition to not having type safety, you must also use casts to get the
correct type back from a collection.
In addition to Collection<E>, there are multiple major types of collections, some of which have
subtypes.
• List<E> is an ordered collection of objects. It is similar to an array, but does not define a size
limit. Implementations will usually grow in size internally to accomodate new elements.
• Set<E> is a collection of objects that does not allow duplicates.
○ SortedSet<E> is a Set<E> that also specifies element ordering.
• Map<K,V> is a collection of key/value pairs.
○ SortedMap<K,V> is a Map<K,V> that also specifies element ordering.
Java SE 5
Java SE 6
https://riptutorial.com/ 172
• Deque<E> is a Queue<E> that can be read from either end.
Note that the above items are all interfaces. In order to use them, you must find the appropriate
implementing classes, such as ArrayList, HashSet, HashMap, or PriorityQueue.
Each type of collection has multiple implementations that have different performance metrics and
use cases.
Note that the Liskov Substitution Principle applies to the collection subtypes. That is, a
SortedSet<E> can be passed to a function expecting a Set<E>. It is also useful to read about
Bounded Parameters in the Generics section for more information on how to use collections with
class inheritance.
If you want to create your own collections, it may be easier to inherit one of the abstract classes
(such as AbstractList) instead of implementing the interface.
Java SE 1.2
• instead of ArrayList
Vector
• Dictionary instead of Map. Note that Dictionary is also an abstract class rather than an
interface.
• Hashtable instead of HashMap
These classes are obsolete and should not be used in modern code.
Examples
Declaring an ArrayList and adding objects
Java SE 5
Java SE 7
aListOfFruits.add("Melon");
aListOfFruits.add("Strawberry");
In the above example, the ArrayList will contain the String "Melon" at index 0 and the String
https://riptutorial.com/ 173
"Strawberry" at index 1.
Also we can add multiple elements with addAll(Collection<? extends E> c) method
Standard Collections
Java Collections framework
A simple way to construct a List from individual data values is to use java.utils.Arrays method
Arrays.asList:
All standard collection implementations provide constructors that take another collection as an
argument adding all elements to the new collection at the time of construction:
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
...
List<String> list1 = Lists.newArrayList("ab", "bc", "cd");
List<String> list2 = Lists.newArrayList(data);
Set<String> set4 = Sets.newHashSet(data);
SortedSet<String> set5 = Sets.newTreeSet("bc", "cd", "ab", "bc", "cd");
Mapping Collections
https://riptutorial.com/ 174
Java Collections framework
Similarly for maps, given a Map<String, Object> map a new map can be constructed with all
elements as follows:
import org.apache.commons.lang3.ArrayUtils;
...
// Taken from org.apache.commons.lang.ArrayUtils#toMap JavaDoc
Each element of the array must be either a Map.Entry or an Array, containing at least two
elements, where the first element is used as key and the second as value.
import com.google.common.collect.Maps;
...
void howToCreateMapsMethod(Function<? super K,V> valueFunction,
Iterable<K> keys1,
Set<K> keys2,
SortedSet<K> keys3) {
ImmutableMap<K, V> map1 = toMap(keys1, valueFunction); // Immutable copy
Map<K, V> map2 = asMap(keys2, valueFunction); // Live Map view
SortedMap<K, V> map3 = toMap(keys3, valueFunction); // Live Map view
}
Java SE 8
Using Stream,
Stream.of("xyz", "abc").collect(Collectors.toList());
or
Arrays.stream("xyz", "abc").collect(Collectors.toList());
https://riptutorial.com/ 175
Join lists
Following ways can be used for joining lists without modifying source list(s).
ListUtils.union(listOne,listTwo);
Java SE 8
It is tricky to remove items from a list while within a loop, this is due to the fact that the index and
length of the list gets changed.
Given the following list, here are some examples that will give an unexpected result and some that
will give the correct result.
INCORRECT
Removing in iteration of for statement Skips "Banana":
The code sample will only print Apple and Strawberry. Banana is skipped because it moves to index 0
once Apple is deleted, but at the same time i gets incremented to 1.
https://riptutorial.com/ 176
for (int i = 0; i < fruits.size(); i++) {
System.out.println (fruits.get(i));
if ("Apple".equals(fruits.get(i))) {
fruits.remove(i);
}
}
Throws: java.util.ConcurrentModificationException
CORRECT
Removing in while loop using an Iterator
The Iterator interface has a remove() method built in just for this case. However, this method is
marked as "optional" in the documentation, and it might throw an UnsupportedOperationException.
Therefore, it is advisable to check the documentation to make sure this operation is supported (in
practice, unless the collection is an immutable one obtained through a 3rd party library or the use
of one of the Collections.unmodifiable...() method, the operation is almost always supported).
While using an Iterator a ConcurrentModificationException is thrown when the modCount of the List
is changed from when the Iterator was created. This could have happened in the same thread or
in a multi-threaded application sharing the same list.
A modCount is an int variable which counts the number of times this list has been structurally
https://riptutorial.com/ 177
modified. A structural change essentially means an add() or remove() operation being invoked on
Collection object (changes made by Iterator are not counted). When the Iterator is created, it
stores this modCount and on every iteration of the List checks if the current modCount is same as and
when the Iterator was created. If there is a change in the modCount value it throws a
ConcurrentModificationException.
Hence for the above-declared list, an operation like below will not throw any exception:
But adding a new element to the List after initializing an Iterator will throw a
ConcurrentModificationException:
Iterating backwards
This does not skip anything. The downside of this approach is that the output is reverse. However,
in most cases where you remove items that will not matter. You should never do this with
LinkedList.
This does not skip anything. When the ith element is removed from the List, the element originally
positioned at index i+1 becomes the new ith element. Therefore, the loop can decrement i in
order for the next iteration to process the next element, without skipping.
https://riptutorial.com/ 178
Using a "should-be-removed" list
This solution enables the developer to check if the correct elements are removed in a cleaner way.
Java SE 8
In Java 8 the following alternatives are possible. These are cleaner and more straight forward if
the removing does not have to happen in a loop.
Filtering a Stream
A List can be streamed and filtered. A proper filter can be used to remove all undesired elements.
List<String> filteredList =
fruits.stream().filter(p -> !"Apple".equals(p)).collect(Collectors.toList());
Note that unlike all the other examples here, this example produces a new List instance and
keeps the original List unchanged.
Using removeIf
Saves the overhead of constructing a stream if all that is needed is to remove a set of items.
Unmodifiable Collection
Sometimes it's not a good practice expose an internal collection since it can lead to a malicious
code vulnerability due to it's mutable characteristic. In order to provide "read-only" collections java
provides its unmodifiable versions.
An unmodifiable collection is often a copy of a modifiable collection which guarantees that the
collection itself cannot be altered. Attempts to modify it will result in an
UnsupportedOperationException exception.
It is important to notice that objects which are present inside the collection can still be altered.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
https://riptutorial.com/ 179
public class MyPojoClass {
private List<Integer> intList = new ArrayList<>();
import java.util.List;
output:
Java SE 8
names.forEach(System.out::println);
names.parallelStream().forEach(System.out::println);
Java SE 5
https://riptutorial.com/ 180
System.out.println(name);
}
Java SE 5
Java SE 1.2
//Iterates list in backward direction once reaches the last element from above iterator in
forward direction
while(listIterator.hasPrevious()){
System.out.println(listIterator.previous());
}
Java SE 8
names.forEach(System.out::println);
Java SE 5
Java SE 5
Java SE 8
names.forEach((key, value) -> System.out.println("Key: " + key + " Value: " + value));
Java SE 5
Java SE 5
Sometimes it is appropriate to use an immutable empty collection. The Collections class provides
methods to get such collections in an efficient way:
These methods are generic and will automatically convert the returned collection to the type it is
assigned to. That is, an invocation of e.g. emptyList() can be assigned to any type of List and
likewise for emptySet() and emptyMap().
The collections returned by these methods are immutable in that they will throw
UnsupportedOperationException if you attempt to call methods which would change their contents (
add, put, etc.). These collections are primarily useful as substitutes for empty method results or
other default values, instead of using null or creating objects with new.
https://riptutorial.com/ 182
Collections in Java only work for objects. I.e. there is no Map<int, int> in Java. Instead, primitive
values need to be boxed into objects, as in Map<Integer, Integer>. Java auto-boxing will enable
transparent use of these collections:
Unfortunately, the overhead of this is substantial. A HashMap<Integer, Integer> will require about 72
bytes per entry (e.g. on 64-bit JVM with compressed pointers, and assuming integers larger than
256, and assuming 50% load of the map). Because the actual data is only 8 bytes, this yields a
massive overhead. Furthermore, it requires two level of indirection (Map -> Entry -> Value) it is
unnecessarily slow.
There exist several libraries with optimized collections for primitive data types (that require only
~16 bytes per entry at 50% load, i.e. 4x less memory, and one level of indirection less), that can
yield substantial performance benefits when using large collections of primitive values in Java.
Above I noticed an example to remove items from a List within a Loop and I thought of another
example that may come in handy this time using the Iterator interface.
This is a demonstration of a trick that might come in handy when dealing with duplicate items in
lists that you want to get rid of.
Note: This is only adding on to the Removing items from a List within a loop example:
The following method takes in two Collection objects and performs the magic of removing the
elements in our removeNameList that match with elements in nameList.
https://riptutorial.com/ 183
iterator.remove(); //remove the current Name or Item
}
}
Calling the method and passing in the nameList and the removeNameListas follows
removeNames(nameList,removeNameList);
Will produce the following output:
Array List before removing names: James Smith Sonny Huckle Berry Finn Allan
Array List after removing names: James Smith Finn Allan
A simple neat use for Collections that may come in handy to remove repeating elements within
lists.
Creating your own Iterable structure for use with Iterator or for-each loop.
To ensure that our collection can be iterated using iterator or for-each loop, we have to take care
of following steps:
1. The stuff we want to iterate upon has to be Iterable and expose iterator().
2. Design a java.util.Iterator by overriding hasNext(), next() and remove().
I have added a simple generic linked list implementation below that uses above entities to make
the linked list iterable.
package org.algorithms.linkedlist;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LinkedList<T> implements Iterable<T> {
Node<T> head, current;
private static class Node<T> {
T data;
Node<T> next;
Node(T data) {
this.data = data;
}
}
public LinkedList(T data) {
head = new Node<>(data);
}
public Iterator<T> iterator() {
return new LinkedListIterator();
}
private class LinkedListIterator implements Iterator<T> {
Node<T> node = head;
https://riptutorial.com/ 184
@Override
public boolean hasNext() {
return node != null;
}
@Override
public T next() {
if (!hasNext())
throw new NoSuchElementException();
Node<T> prevNode = node;
node = node.next;
return prevNode.data;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Removal logic not implemented.");
}
}
public void add(T data) {
Node current = head;
while (current.next != null)
current = current.next;
current.next = new Node<>(data);
}
}
class App {
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>(1);
list.add(2);
list.add(4);
list.add(3);
//Test #1
System.out.println("using Iterator:");
Iterator<Integer> itr = list.iterator();
while (itr.hasNext()) {
Integer i = itr.next();
System.out.print(i + " ");
}
//Test #2
System.out.println("\n\nusing for-each:");
for (Integer data : list) {
System.out.print(data + " ");
}
}
}
Output
using Iterator:
1 2 4 3
using for-each:
1 2 4 3
https://riptutorial.com/ 185
This will run in Java 7+. You can make it run on Java 5 and Java 6 also by substituting:
with
This exception occurs when a collection is modified while iterating over it using methods other
than those provided by the iterator object. For example, we have a list of hats and we want to
remove all those that have ear flaps:
If we run this code, ConcurrentModificationException will be raised since the code modifies the
collection while iterating it. The same exception may occur if one of the multiple threads working
with the same list is trying to modify the collection while others iterate over it. Concurrent
modification of collections in multiple threads is a natural thing, but should be treated with usual
tools from the concurrent programming toolbox such as synchronization locks, special collections
adopted for concurrent modification, modifying the cloned collection from initial etc.
Sub Collections
https://riptutorial.com/ 186
Example:
Output:
Before Sublist [Hello1, Hello2]
After sublist changes [Hello1, Hello3, Hello2]
Set subSet(fromIndex,toIndex)
Here fromIndex is inclusive and toIndex is exclusive.
Map subMap(fromKey,toKey)
fromKey is inclusive and toKey is exclusive
If fromKey is greater than toKey or if this map itself has a restricted range, and fromKey or toKey
lies outside the bounds of the range then it throws IllegalArgumentException.
All the collections support backed collections means changes made on the sub collection will have
same change on the main collection.
https://riptutorial.com/ 187
Chapter 30: Command line Argument
Processing
Syntax
• public static void main(String[] args)
Parameters
Parameter Details
The command line arguments. Assuming that the main method is invoked by the
args
Java launcher, args will be non-null, and will have no null elements.
Remarks
When a regular Java application is launched using the java command (or equivalent), a main
method will be called, passing the arguments from the command line in the args array.
Unfortunately, the Java SE class libraries do not provide any direct support for command
argument processing. This leaves you two alternatives:
This Topic will attempt to cover some of the more popular 3rd-party libraries. For an extensive list
of the alternatives, see this answer to the StackOverflow Question "How to parse command line
arguments in Java?".
Examples
Argument processing using GWT ToolBase
If you want to parse more complex command-line arguments, e.g. with optional parameters, than
the best is to use google's GWT approach. All classes are public available at:
https://gwt.googlesource.com/gwt/+/2.8.0-
beta1/dev/core/src/com/google/gwt/util/tools/ToolBase.java
An example for handling the command-line myprogram -dir "~/Documents" -port 8888 is:
https://riptutorial.com/ 188
protected int port;
// getters for dir and port
...
public MyProgramHandler() {
this.registerHandler(new ArgHandlerDir() {
@Override
public void setDir(File dir) {
this.dir = dir;
}
});
this.registerHandler(new ArgHandlerInt() {
@Override
public String[] getTagArgs() {
return new String[]{"port"};
}
@Override
public void setInt(int value) {
this.port = value;
}
});
}
public static void main(String[] args) {
MyProgramHandler myShell = new MyProgramHandler();
if (myShell.processArgs(args)) {
// main program operation
System.out.println(String.format("port: %d; dir: %s",
myShell.getPort(), myShell.getDir()));
}
System.exit(1);
}
}
ArgHandleralso has a method isRequired() which can be overwritten to say that the command-line
argument is required (default return is false so that the argument is optional.
When the command-line syntax for an application is simple, it is reasonable to do the command
argument processing entirely in custom code.
In this example, we will present a series of simple case studies. In each case, the code will
produce error messages if the arguments are unacceptable, and then call System.exit(1) to tell the
shell that the command has failed. (We will assume in each case that the Java code is invoked
using a wrapper whose name is "myapp".)
https://riptutorial.com/ 189
System.exit(1);
}
// Run the application
System.out.println("It worked");
}
}
Note that if we neglected to check args.length, the command would crash if the user ran it with too
few command-line arguments.
package tommy;
public class Main {
public static void main(String[] args) {
boolean feelMe = false;
boolean seeMe = false;
int index;
loop: for (index = 0; index < args.length; index++) {
String opt = args[index];
switch (opt) {
case "-c":
seeMe = true;
break;
case "-f":
feelMe = true;
break;
default:
if (!opts.isEmpty() && opts.charAt(0) == '-') {
error("Unknown option: '" + opt + "');
}
break loop;
}
}
if (index >= args.length) {
error("Missing argument(s)");
}
https://riptutorial.com/ 190
// Run the application
// ...
}
As you can see, processing the arguments and options gets rather cumbersome if the command
syntax is complicated. It is advisable to use a "command line parsing" library; see the other
examples.
https://riptutorial.com/ 191
Chapter 31: Common Java Pitfalls
Introduction
This topic outlines some of the common mistakes made by beginners in Java.
This includes any common mistakes in use of the Java language or understanding of the run-time
environment.
Mistakes associated with specific APIs can be described in topics specific to those APIs. Strings
are a special case; they're covered in the Java Language Specification. Details other than
common mistakes can be described in this topic on Strings.
Examples
Pitfall: using == to compare primitive wrappers objects such as Integer
(This pitfall applies equally to all primitive wrapper types, but we will illustrate it for Integer and int
.)
When working with Integer objects, it is tempting to use == to compare values, because that is
what you would do with int values. And in some cases this will seem to work:
Here we created two Integer objects with the value 1 and compare them (In this case we created
one from a String and one from an int literal. There are other alternatives). Also, we observe that
the two comparison methods (== and equals) both yield true.
In this case, only the equals comparison yields the correct result.
The reason for this difference in behavior is, that the JVM maintains a cache of Integer objects for
the range -128 to 127. (The upper value can be overridden with the system property
"java.lang.Integer.IntegerCache.high" or the JVM argument "-XX:AutoBoxCacheMax=size"). For
values in this range, the Integer.valueOf() will return the cached value rather than creating a new
https://riptutorial.com/ 192
one.
Thus, in the first example the Integer.valueOf(1) and Integer.valueOf("1") calls returned the same
cached Integer instance. By contrast, in the second example the Integer.valueOf(1000) and
Integer.valueOf("1000") both created and returned new Integer objects.
The == operator for reference types tests for reference equality (i.e. the same object). Therefore, in
the first example int1_1 == int1_2 is true because the references are the same. In the second
example int2_1 == int2_2 is false because the references are different.
Every time a program opens a resource, such as a file or network connection, it is important to
free the resource once you are done using it. Similar caution should be taken if any exception
were to be thrown during operations on such resources. One could argue that the FileInputStream
has a finalizer that invokes the close() method on a garbage collection event; however, since we
can’t be sure when a garbage collection cycle will start, the input stream can consume computer
resources for an indefinite period of time. The resource must be closed in a finally section of a
try-catch block:
Java SE 7
Since Java 7 there is a really useful and neat statement introduced in Java 7 particularly for this
case, called try-with-resources:
Java SE 7
https://riptutorial.com/ 193
The try-with-resources statement can be used with any object that implements the Closeable or
AutoCloseable interface. It ensures that each resource is closed by the end of the statement. The
difference between the two interfaces is, that the close() method of Closeable throws an
IOException which has to be handled in some way.
In cases where the resource has already been opened but should be safely closed after use, one
can assign it to a local variable inside the try-with-resources
Java SE 7
The local resource variable created in the try-with-resources constructor is effectively final.
Java manages memory automatically. You are not required to free memory manually. An object's
memory on the heap may be freed by a garbage collector when the object is no longer reachable
by a live thread.
However, you can prevent memory from being freed, by allowing objects to be reachable that are
no longer needed. Whether you call this a memory leak or memory packratting, the result is the
same -- an unnecessary increase in allocated memory.
Memory leaks in Java can happen in various ways, but the most common reason is everlasting
object references, because the garbage collector can’t remove objects from the heap while there
are still references to them.
Static fields
One can create such a reference by defining class with a static field containing some collection of
objects, and forgetting to set that static field to null after the collection is no longer needed. static
fields are considered GC roots and are never collected. Another issue is leaks in non-heap
memory when JNI is used.
Classloader leak
By far, though, the most insidious type of memory leak is the classloader leak. A classloader holds
a reference to every class it has loaded, and every class holds a reference to its classloader.
Every object holds a reference to its class as well. Therefore, if even a single object of a class
loaded by a classloader is not garbage, not a single class that that classloader has loaded can be
collected. Since each class also refers to its static fields, they cannot be collected either.
Accumulation leak The accumulation leak example could look like the following:
https://riptutorial.com/ 194
final Deque<BigDecimal> numbers = new LinkedBlockingDeque<>();
final BigDecimal divisor = new BigDecimal(51);
scheduledExecutorService.scheduleAtFixedRate(() -> {
BigDecimal number = numbers.peekLast();
if (number != null && number.remainder(divisor).byteValue() == 0) {
System.out.println("Number: " + number);
System.out.println("Deque size: " + numbers.size());
}
}, 10, 10, TimeUnit.MILLISECONDS);
scheduledExecutorService.scheduleAtFixedRate(() -> {
numbers.add(new BigDecimal(System.currentTimeMillis()));
}, 10, 10, TimeUnit.MILLISECONDS);
try {
scheduledExecutorService.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
This example creates two scheduled tasks. The first task takes the last number from a deque
called numbers, and, if the number is divisible by 51, it prints the number and the deque's size. The
second task puts numbers into the deque. Both tasks are scheduled at a fixed rate, and they run
every 10 ms.
If the code is executed, you’ll see that the size of the deque is permanently increasing. This will
eventually cause the deque to be filled with objects that consume all available heap memory.
To prevent this while preserving the semantics of this program, we can use a different method for
taking numbers from the deque: pollLast. Contrary to the method peekLast, pollLast returns the
element and removes it from the deque while peekLast only returns the last element.
A common mistake for Java beginners is to use the == operator to test if two strings are equal. For
example:
The above program is supposed to test the first command line argument and print different
messages when it and isn't the word "hello". But the problem is that it won't work. That program
will output "Are you feeling grumpy today?" no matter what the first command line argument is.
https://riptutorial.com/ 195
In this particular case the String "hello" is put in the string pool while the String args[0] resides on
the heap. This means there are two objects representing the same literal, each with its reference.
Since == tests for references, not actual equality, the comparison will yield a false most of the
times. This doesn't mean that it will always do so.
When you use == to test strings, what you are actually testing is if two String objects are the same
Java object. Unfortunately, that is not what string equality means in Java. In fact, the correct way
to test strings is to use the equals(Object) method. For a pair of strings, we usually want to test if
they consist of the same characters in the same order.
But it actually gets worse. The problem is that == will give the expected answer in some
circumstances. For example
Interestingly, this will print "same", even though we are testing the strings the wrong way. Why is
that? Because the Java Language Specification (Section 3.10.5: String Literals) stipulates that any
two string >>literals<< consisting of the same characters will actually be represented by the same
Java object. Hence, the == test will give true for equal literals. (The string literals are "interned" and
added to a shared "string pool" when your code is loaded, but that is actually an implementation
detail.)
To add to the confusion, the Java Language Specification also stipulates that when you have a
compile-time constant expression that concatenates two string literals, that is equivalent to a
single literal. Thus:
https://riptutorial.com/ 196
if (s1 == s2) {
System.out.println("1. same");
} else {
System.out.println("1. different");
}
if (s1 + s3 == "hello mum") {
System.out.println("2. same");
} else {
System.out.println("2. different");
}
}
}
This will output "1. same" and "2. different". In the first case, the + expression is evaluated at
compile time and we compare one String object with itself. In the second case, it is evaluated at
run time and we compare two different String objects
In summary, using == to test strings in Java is almost always incorrect, but it is not guaranteed to
give the wrong answer.
Some people recommend that you should apply various tests to a file before attempting to open it
either to provide better diagnostics or avoid dealing with exceptions. For example, this method
attempts to check if path corresponds to a readable file:
File f = null;
try {
f = getValidatedFile("somefile");
} catch (IOException ex) {
System.err.println(ex.getMessage());
return;
}
try (InputStream is = new FileInputStream(file)) {
// Read data etc.
}
The first problem is in the signature for FileInputStream(File) because the compiler will still insist
we catch IOException here, or further up the stack.
The second problem is that checks performed by getValidatedFile do not guarantee that the
FileInputStream will succeed.
https://riptutorial.com/ 197
• Race conditions: another thread or a separate process could rename the file, delete the file,
or remove read access after the getValidatedFile returns. That would lead to a "plain"
IOException without the custom message.
• There are edge cases not covered by those tests. For example, on a system with SELinux in
"enforcing" mode, an attempt to read a file can fail despite canRead() returning true.
The third problem is that the tests are inefficient. For example, the exists, isFile and canRead calls
will each make a syscall to perform the required check. Another syscall is then made to open the
file, which repeats the same checks behind the scenes.
In short, methods like getValidatedFile are misguided. It is better to simply attempt to open the file
and handle the exception:
If you wanted to distinguish IO errors thrown while opening and reading, you could use a nested
try / catch. If you wanted to produce better diagnostics for open failures, you could perform the
exists, isFile and canRead checks in the handler.
If you mistakenly think of variables as objects, the actual behavior of the Java language will
surprise you.
• For Java variables which have a primitive type (such as int or float) the variable holds a
copy of the value. All copies of a primitive value are indistinguishable; i.e. there is only one
int value for the number one. Primitive values are not objects and they do not behave like
objects.
• For Java variables which have a reference type (either a class or an array type) the variable
holds a reference. All copies of a reference are indistinguishable. References may point to
objects, or they may be null which means that they point to no object. However, they are not
objects and they don't behave like objects.
Variables are not objects in either case, and they don't contain objects in either case. They may
https://riptutorial.com/ 198
contain references to objects, but that is saying something different.
Example class
The examples that follow use this class, which represents a point in 2D space.
An instance of this class is an object that has two fields x and y which have the type int.
We can have many instances of the MutableLocation class. Some will represent the same locations
in 2D space; i.e. the respective values of x and y will match. Others will represent different
locations.
In the above, we have declared three variables here, there and elsewhere that can hold references
to MutableLocation objects.
If you (incorrectly) think of these variables as being objects, then you are likely to misread the
statements as saying:
From that, you are likely to infer we have three independent objects in the three variables. In fact
there are only two objects created by the above. The variables here and there actually refer to the
same object.
https://riptutorial.com/ 199
System.out.println("BEFORE: here.x is " + here.x + ", there.x is " + there.x +
"elsewhere.x is " + elsewhere.x);
here.x = 42;
System.out.println("AFTER: here.x is " + here.x + ", there.x is " + there.x +
"elsewhere.x is " + elsewhere.x);
We assigned a new value to here.x and it changed the value that we see via there.x. They are
referring to the same object. But the value that we see via elsewhere.x has not changed, so
elsewhere must refer to a different object.
If a variable was an object, then the assignment here.x = 42 would not change there.x.
The equality operator does NOT test that two objects are
equal
Applying the equality (==) operator to reference values tests if the values refer to the same object.
It does not test whether two (different) objects are "equal" in the intuitive sense.
if (here == there) {
System.out.println("here is there");
}
if (here == elsewhere) {
System.out.println("here is elsewhere");
}
This will print "here is there", but it won't print "here is elsewhere". (The references in here and
elsewhere are for two distinct objects.)
By contrast, if we call the equals(Object) method that we implemented above, we are going to test
if two MutableLocation instances have an equal location.
if (here.equals(there)) {
System.out.println("here equals there");
}
if (here.equals(elsewhere)) {
System.out.println("here equals elsewhere");
}
This will print both messages. In particular, here.equals(elsewhere) returns true because the
semantic criteria we chose for equality of two MutableLocation objects has been satisfied.
https://riptutorial.com/ 200
Method calls do NOT pass objects at all
Java method calls use pass by value1 to pass arguments and return a result.
When you pass a reference value to a method, you're actually passing a reference to an object by
value, which means that it is creating a copy of the object reference.
As long as both object references are still pointing to the same object, you can modify that object
from either reference, and this is what causes confusion for some.
However, you are not passing an object by reference2. The distinction is that if the object
reference copy is modified to point to another object, the original object reference will still point to
the original object.
void g() {
MutableLocation foo = MutableLocation(1, 2);
f(foo);
System.out.println("foo.x is " + foo.x); // Prints "foo.x is 1".
}
void g() {
MutableLocation foo = new MutableLocation(0, 0);
f(foo);
System.out.println("foo.x is " + foo.x); // Prints "foo.x is 42"
}
1 - In languages like Python and Ruby, the term "pass by sharing" is preferred for "pass by value" of an object /
reference.
2 - The term "pass by reference" or "call by reference" has a very specific meaning in programming language
terminology. In effect, it means that you pass the address of a variable or an array element, so that when the called
method assigns a new value to the formal argument, it changes the value in the original variable. Java does not
support this. For a more fulsome description of different mechanisms for passing parameters, please refer to
https://en.wikipedia.org/wiki/Evaluation_strategy.
Occasionally we see StackOverflow Java questions (and C or C++ questions) that ask what
something like this:
i += a[i++] + b[i--];
https://riptutorial.com/ 201
evaluates to ... for some known initial states of i, a and b.
Generally speaking:
• for Java the answer is always specified1, but non-obvious, and often difficult to figure out
• for C and C++ the answer is often unspecified.
Such examples are often used in exams or job interviews as an attempt to see if the student or
interviewee understands how expression evaluation really works in the Java programming
language. This is arguably legitimate as a "test of knowledge", but that does not mean that you
should ever do this in a real program.
To illustrate, the following seemingly simple example has appeared a few times in StackOverflow
questions (like this one). In some cases, it appears as a genuine mistake in someone's code.
int a = 1;
a = a++;
System.out.println(a); // What does this print.
Most programmers (including Java experts) reading those statements quickly would say that it
outputs 2. In fact, it outputs 1. For a detailed explanation of why, please read this Answer.
However the real takeaway from this and similar examples is that any Java statement that both
assigns to and side-effects the same variable is going to be at best hard to understand, and at
worst downright misleading. You should avoid writing code like this.
1 - modulo potential issues with the Java Memory Model if the variables or objects are visible to other threads.
New Java programmers often forget, or fail to fully comprehend, that the Java String class is
immutable. This leads to problems like the one in the following example:
The above code is supposed to print command line arguments in upper case. Unfortunately, it
does not work, the case of the arguments is not changed. The problem is this statement:
s.toUpperCase();
You might think that calling toUpperCase() is going to change s to an uppercase string. It doesn't. It
https://riptutorial.com/ 202
can't! String objects are immutable. They cannot be changed.
In reality, the toUpperCase() method returns a String object which is an uppercase version of the
String that you call it on. This will probably be a new String object, but if s was already all
uppercase, the result could be the existing string.
So in order to use this method effectively, you need to use the object returned by the method call;
for example:
s = s.toUpperCase();
In fact, the "strings never change" rule applies to all String methods. If you remember that, then
you can avoid a whole category of beginner's mistakes.
https://riptutorial.com/ 203
Chapter 32: Comparable and Comparator
Syntax
• public class MyClass implements Comparable<MyClass>
• public class MyComparator implements Comparator<SomeOtherClass>
• public int compareTo(MyClass other)
• public int compare(SomeOtherClass o1, SomeOtherClass o2)
Remarks
When implementing a compareTo(..) method which depends upon a double, do not do the
following:
The truncation caused by the (int) cast will cause the method to sometimes incorrectly return 0
instead of a positive or negative number, and can thus lead to comparison and sorting bugs.
A non-generic version of Comparable<T>, simply Comparable, has existed since Java 1.2. Other than
for interfacing with legacy code, it's always better to implement the generic version Comparable<T>,
as it doesn't require casting upon comparison.
While it is possible to break from this paradigm, be cautious when doing so.
A Comparator<T> can still be used on instances of a class if that class implements Comparable<T>. In
this case, the Comparator's logic will be used; the natural ordering specified by the Comparable
implementation will be ignored.
Examples
https://riptutorial.com/ 204
Sorting a List using Comparable or a Comparator
Say we are working on a class representing a Person by their first and last names. We have
created a basic class to do this and implemented proper equals and hashCode methods.
@Override
public boolean equals(Object o) {
if (! (o instanceof Person)) return false;
Person p = (Person)o;
return firstName.equals(p.firstName) && lastName.equals(p.lastName);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName);
}
}
Now we would like to sort a list of Person objects by their name, such as in the following scenario:
Unfortunately, as marked, the above currently won't compile. Collections.sort(..) only knows how
to sort a list if the elements in that list are comparable, or a custom method of comparison is given.
If you were asked to sort the following list : 1,3,5,4,2, you'd have no problem saying the answer is
1,2,3,4,5. This is because Integers (both in Java and mathematically) have a natural ordering, a
https://riptutorial.com/ 205
standard, default comparison base ordering. To give our Person class a natural ordering, we
implement Comparable<Person>, which requires implementing the method compareTo(Person p):
@Override
public boolean equals(Object o) {
if (! (o instanceof Person)) return false;
Person p = (Person)o;
return firstName.equals(p.firstName) && lastName.equals(p.lastName);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName);
}
@Override
public int compareTo(Person other) {
// If this' lastName and other's lastName are not comparably equivalent,
// Compare this to other by comparing their last names.
// Otherwise, compare this to other by comparing their first names
int lastNameCompare = lastName.compareTo(other.lastName);
if (lastNameCompare != 0) {
return lastNameCompare;
} else {
return firstName.compareTo(other.firstName);
}
}
}
https://riptutorial.com/ 206
Collections.sort(people); //Now functions correctly
If, however, you either do not want or are unable to modify class Person, you can provide a custom
Comparator<T> that handles the comparison of any two Person objects. If you were asked to sort the
following list: circle, square, rectangle, triangle, hexagon you could not, but if you were asked to
sort that list based on the number of corners, you could. Just so, providing a comparator instructs
Java how to compare two normally not comparable objects.
//Assume the first version of Person (that does not implement Comparable) is used here
public static void main(String[] args) {
List<Person> people = Arrays.asList(new Person("John", "Doe"),
new Person("Bob", "Dole"),
new Person("Ronald", "McDonald"),
new Person("Alice", "McDonald"),
new Person("Jill", "Doe"));
Collections.sort(people); //Illegal, Person doesn't implement Comparable.
Collections.sort(people, new PersonComparator()); //Legal
//Assume the first version of Person (that does not implement Comparable) is used here
public static void main(String[] args) {
List<Person> people = Arrays.asList(new Person("John", "Doe"),
new Person("Bob", "Dole"),
new Person("Ronald", "McDonald"),
new Person("Alice", "McDonald"),
new Person("Jill", "Doe"));
Collections.sort(people); //Illegal, Person doesn't implement Comparable.
//Anonymous Class
https://riptutorial.com/ 207
Collections.sort(people, new Comparator<Person>() { //Legal
public int compare(Person p1, Person p2) {
//Method code...
}
});
}
Java SE 8
//Lambda
Collections.sort(people, (p1, p2) -> { //Legal
//Method code....
});
Collections.sort(people, Comparator.comparing(Person::getLastName)
.thenComparing(Person::getFirstName));
https://riptutorial.com/ 208
}
These two methods do essentially the same thing, with one minor difference: compareTo compares
this to other, whereas compare compares t1 to t2, not caring at all about this.
Aside from that difference, the two methods have similar requirements. Specifically (for
compareTo), Compares this object with the specified object for order. Returns a negative integer,
zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
Thus, for the comparison of a and b:
• If a < b, a.compareTo(b) and compare(a,b) should return a negative integer, and b.compareTo(a)
and compare(b,a) should return a positive integer
• If a > b, a.compareTo(b) and compare(a,b) should return a positive integer, and b.compareTo(a)
and compare(b,a) should return a negative integer
• If a equals b for comparison, all comparisons should return 0.
• One that takes a List<T> as a parameter where T must implement Comparable and override
the compareTo() method that determines sort order.
• One that takes a List and a Comparator as the arguments, where the Comparator
determines the sort order.
@Override
public int compareTo(Person o) {
return this.getAge() - o.getAge();
}
@Override
public String toString() {
return this.getAge()+"-"+this.getName();
}
https://riptutorial.com/ 209
Here is how you would use the above class to sort a List in the natural ordering of its elements,
defined by the compareTo() method override:
//-- usage
List<Person> pList = new ArrayList<Person>();
Person p = new Person();
p.setName("A");
p.setAge(10);
pList.add(p);
p = new Person();
p.setName("Z");
p.setAge(20);
pList.add(p);
p = new Person();
p.setName("D");
p.setAge(30);
pList.add(p);
System.out.println(pList);
Here is how you would use an anonymous inline Comparator to sort a List that does not
implement Comparable, or in this case, to sort a List in an order other than the natural ordering:
//-- explicit sorting, define sort on another property here goes with name
Collections.sort(pList, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getName().compareTo(o2.getName());
}
});
System.out.println(pList);
As of Java 8, there are default methods on the Map.Entry interface to allow sorting of map
iterations.
Java SE 8
https://riptutorial.com/ 210
Of course, these can also be used outside of the stream api :
Java SE 8
Comparator.comparing(Person::getName)
This creates a comparator for the class Person that uses this person name as the comparison
source. Also it is possible to use method version to compare long, int and double. For example:
Comparator.comparingInt(Person::getAge)
Reversed order
To create a comparator that imposes the reverse ordering use reversed() method:
Comparator.comparing(Person::getName).reversed()
Chain of comparators
Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName)
This will create a comparator that firs compares with last name then compares with first name.
You can chain as many comparators as you want.
https://riptutorial.com/ 211
Chapter 33: CompletableFuture
Introduction
CompletableFuture is a class added to Java SE 8 which implements the Future interface from
Java SE 5. In addition to supporting the Future interface it adds many methods that allow
asynchronous callback when the future is completed.
Examples
Convert blocking method to asynchonous
The following method will take a second or two depending on your connection to retrieve a web
page and count the text length. Whatever thread calls it will block for that period of time. Also it
rethrows an exception which is useful later on.
This converts it to a method that will return immediately by moving the blocking method call to
another thread. By default the supplyAsync method will run the supplier on the common pool. For
a blocking method this is probably not a good choice since one might exhaust the threads in that
pool which is why I added the optional service parameter.
To use the function in an asynchronous fashion one should use on of the methods that accepts a
lamda to be called with the result of the of the supplier when it completes such as thenAccept.
Also it is important to use exceptionally or handle method to log any exceptions that might have
happened.
https://riptutorial.com/ 212
asyncGetWebPageLength("https://stackoverflow.com/")
.thenAccept(l -> {
System.out.println("Stack Overflow returned " + l);
})
.exceptionally((Throwable throwable) -> {
Logger.getLogger("myclass").log(Level.SEVERE, "", throwable);
return null;
});
In the example below, the calculateShippingPrice method calculates shipping cost, which takes
some processing time. In a real world example, this would e.g. be contacting another server which
returns the price based on the weight of the product and the shipping method.
By modeling this in an async way via CompletableFuture, we can continue different work in the
method (i.e. calculating packaging costs).
// Let's just say each 200 grams is a new dollar on your shipping costs
int shippingCosts = weightInGrams / 200;
try {
Thread.sleep(2000L); // Now let's simulate some waiting time...
} catch(InterruptedException e) { /* We can safely ignore that */ }
https://riptutorial.com/ 213
Chapter 34: Concurrent Collections
Introduction
A concurrent collection is a [collection][1] which permits access by more than one thread at the
same time. Different threads can typically iterate through the contents of the collection and add or
remove elements. The collection is responsible for ensuring that the collection doesn't become
corrupt. [1]:
http://stackoverflow.com/documentation/java/90/collections#t=201612221936497298484
Examples
Thread-safe Collections
When you make a thread-safe collection, you should never access it through the original
collection, only through the thread-safe wrapper.
Java SE 5
Starting in Java 5, java.util.collections has several new thread-safe collections that don't need
the various Collections.synchronized methods.
Concurrent Collections
Concurrent collections are a generalization of thread-safe collections, that allow for a broader
usage in a concurrent environment.
While thread-safe collections have safe element addition or removal from multiple threads, they do
not necessarily have safe iteration in the same context (one may not be able to safely iterate
through the collection in one thread, while another one modifies it by adding/removing elements).
As iteration is often the base implementation of several bulk methods in collections, like addAll,
https://riptutorial.com/ 214
removeAll,or also collection copying (through a constructor, or other means), sorting, ... the use
case for concurrent collections is actually pretty large.
The "snapshot" style iterator method uses a reference to the state of the array at the
point that the iterator was created. This array never changes during the lifetime of the
iterator, so interference is impossible and the iterator is guaranteed not to throw
ConcurrentModificationException.
https://riptutorial.com/ 215
Another concurrent collection regarding iteration is ConcurrentLinkedQueue, which states :
Iterators are weakly consistent, returning elements reflecting the state of the queue at
some point at or since the creation of the iterator. They do not throw
java.util.ConcurrentModificationException, and may proceed concurrently with other
operations. Elements contained in the queue since the creation of the iterator will be
returned exactly once.
One should check the javadocs to see if a collection is concurrent, or not. The attributes of the
iterator returned by the iterator() method ("fail fast", "weakly consistent", ...) is the most important
attribute to look for.
Could (and statistically will on most modern, multi CPU/core architectures) lead to exceptions.
Synchronized collections from the Collections utility methods are thread safe for addition/removal
of elements, but not iteration (unless the underlying collection being passed to it already is).
else
{
//'value' reference is mapped to key = 1.
}
}
}
https://riptutorial.com/ 216
Read Concurrent Collections online: https://riptutorial.com/java/topic/8363/concurrent-collections
https://riptutorial.com/ 217
Chapter 35: Concurrent Programming
(Threads)
Introduction
Concurrent computing is a form of computing in which several computations are executed
concurrently instead of sequentially. Java language is designed to support concurrent
programming through the usage of threads. Objects and resources can be accessed by multiple
threads; each thread can potentially access any object in the program and the programmer must
ensure read and write access to objects is properly synchronized between threads.
Remarks
Related topic(s) on StackOverflow:
• Atomic Types
• Executor, ExecutorService and Thread pools
• Extending Thread versus implementing Runnable
Examples
Basic Multithreading
If you have many tasks to execute, and all these tasks are not dependent of the result of the
precedent ones, you can use Multithreading for your computer to do all this tasks at the same
time using more processors if your computer can. This can make your program execution faster if
you have some big independent tasks.
CountAndPrint(String name) {
this.name = name;
}
https://riptutorial.com/ 218
// of CountAndPrint in another thread
new Thread(new CountAndPrint("Instance " + i)).start();
}
The code of the run method of the various CountAndPrint instances will execute in non predictable
order. A snippet of a sample execution might look like this:
Instance 4: 1
Instance 2: 1
Instance 4: 2
Instance 1: 1
Instance 1: 2
Main: 1
Instance 4: 3
Main: 2
Instance 3: 1
Instance 4: 4
...
Producer-Consumer
A simple example of producer-consumer problem solution. Notice that JDK classes (AtomicBoolean
and BlockingQueue) are used for synchronization, which reduces the chance of creating an invalid
solution. Consult Javadoc for various types of BlockingQueue; choosing different implementation
may drastically change the behavior of this example (like DelayQueue or Priority Queue).
https://riptutorial.com/ 219
}
}
producer.start();
consumer.start();
Thread.sleep(1000);
producer.interrupt();
Thread.sleep(10);
consumer.interrupt();
}
}
Using ThreadLocal
A useful tool in Java Concurrency is ThreadLocal – this allows you to have a variable that will be
unique to a given thread. Thus, if the same code runs in different threads, these executions will not
share the value, but instead each thread has its own variable that is local to the thread.
https://riptutorial.com/ 220
For example, this is frequently used to establish the context (such as authorization information) of
handling a request in a servlet. You might do something like this:
Now, instead of passing MyUserContext into every single method, you can instead use
MyServlet.getContext() where you need it. Now of course, this does introduce a variable that needs
to be documented, but it’s thread-safe, which eliminates a lot of the downsides to using such a
highly scoped variable.
The key advantage here is that every thread has its own thread local variable in that contexts
container. As long as you use it from a defined entry point (like demanding that each servlet
maintains its context, or perhaps by adding a servlet filter) you can rely on this context being there
when you need it.
CountDownLatch
CountDownLatch
A synchronization aid that allows one or more threads to wait until a set of operations
being performed in other threads completes.
Key Methods:
Causes the current thread to wait until the latch has counted down to zero, unless the
thread is interrupted.
https://riptutorial.com/ 221
public void countDown()
Decrements the count of the latch, releasing all waiting threads if the count reaches
zero.
Example:
import java.util.concurrent.*;
}
CountDownLatch latch = new CountDownLatch(numberOfThreads);
for (int n = 0; n < numberOfThreads; n++) {
Thread t = new Thread(new DoSomethingInAThread(latch));
t.start();
}
latch.await();
System.out.println("In Main thread after completion of " + numberOfThreads + "
threads");
} catch(Exception err) {
err.printStackTrace();
}
}
}
output:
java CountDownLatchDemo 5
Do some thing
Do some thing
Do some thing
Do some thing
https://riptutorial.com/ 222
Do some thing
In Main thread after completion of 5 threads
Explanation:
Synchronization
In Java, there is a built-in language-level locking mechanism: the synchronized block, which can
use any Java object as an intrinsic lock (i.e. every Java object may have a monitor associated with
it).
Intrinsic locks provide atomicity to groups of statements. To understand what that means for us,
let's have a look at an example where synchronized is useful:
In this case, if it weren't for the synchronized block, there would have been multiple concurrency
issues involved. The first one would be with the post increment operator (it isn't atomic in itself),
and the second would be that we would be observing the value of t after an arbitrary amount of
other threads has had the chance to modify it. However, since we acquired an intrinsic lock, there
will be no race conditions here and the output will contain numbers from 1 to 100 in their normal
order.
Intrinsic locks in Java are mutexes (i.e. mutual execution locks). Mutual execution means that if
one thread has acquired the lock, the second will be forced to wait for the first one to release it
before it can acquire the lock for itself. Note: An operation that may put the thread into the wait
(sleep) state is called a blocking operation. Thus, acquiring a lock is a blocking operation.
Intrinsic locks in Java are reentrant. This means that if a thread attempts to acquire a lock it
already owns, it will not block and it will successfully acquire it. For instance, the following code will
https://riptutorial.com/ 223
not block when called:
The following blocks of code are practically equivalent (even though the bytecode seems to be
different):
2. synchronized method:
class MyClass {
...
public static void bar() {
synchronized(MyClass.class) {
doSomeOtherStuff();
}
}
}
class MyClass {
...
public static synchronized void bar() {
doSomeOtherStuff();
}
}
Atomic operations
https://riptutorial.com/ 224
An atomic operation is an operation that is executed "all at once", without any chance of other
threads observing or modifying state during the atomic operation's execution.
In this case, there are two issues. The first issue is that the post increment operator is not atomic.
It is comprised of multiple operations: get the value, add 1 to the value, set the value. That's why if
we run the example, it is likely that we won't see t: 100 in the output - two threads may
concurrently get the value, increment it, and set it: let's say the value of t is 10, and two threads
are incrementing t. Both threads will set the value of t to 11, since the second thread observes the
value of t before the first thread had finished incrementing it.
The second issue is with how we are observing t. When we are printing the value of t, the value
may have already been changed by a different thread after this thread's increment operation.
To fix those issues, we'll use the java.util.concurrent.atomic.AtomicInteger, which has many
atomic operations for us to use.
The incrementAndGet method of AtomicInteger atomically increments and returns the new value,
thus eliminating the previous race condition. Please note that in this example the lines will still be
out of order because we make no effort to sequence the println calls and that this falls outside the
scope of this example, since it would require synchronization and the goal of this example is to
show how to use AtomicInteger to eliminate race conditions concerning state.
https://riptutorial.com/ 225
A deadlock occurs when two competing actions wait for the other to finish, and thus neither ever
does. In java there is one lock associated with each object. To avoid concurrent modification done
by multiple threads on single object we can use synchronized keyword, but everything comes at a
cost. Using synchronized keyword wrongly can lead to stuck systems called as deadlocked system.
Consider there are 2 threads working on 1 instance, Lets call threads as First and Second, and
lets say we have 2 resources R1 and R2. First acquires R1 and also needs R2 for its completion
while Second acquires R2 and needs R1 for completion.
First has R1 and Second has R2. now First is waiting for R2 while Second is waiting for R1. this
wait is indefinite and this leads to deadlock.
@Override
public void run() {
// TODO Auto-generated method stub
dl.methodA();
}
});
@Override
public void run() {
// TODO Auto-generated method stub
try {
dl.method2();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t1.setName("First");
t2.setName("Second");
t1.start();
t2.start();
}
}
class DeadLock {
https://riptutorial.com/ 226
try {
Thread.sleep(100);
method2();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void method2() throws InterruptedException {
System.out.println("method2 wait for mLock2 " + Thread.currentThread().getName());
synchronized (mLock2) {
System.out.println("method2 mLock2 acquired " +
Thread.currentThread().getName());
Thread.sleep(100);
method3();
}
}
public void method3() throws InterruptedException {
System.out.println("method3 mLock1 "+ Thread.currentThread().getName());
synchronized (mLock1) {
System.out.println("method3 mLock1 acquired " +
Thread.currentThread().getName());
}
}
}
Pausing Execution
Thread.sleep causes the current thread to suspend execution for a specified period. This is an
efficient means of making processor time available to the other threads of an application or other
applications that might be running on a computer system. There are two overloaded sleep
methods in the Thread class.
https://riptutorial.com/ 227
Thread.sleep(1000);
It is important to note that this is a hint to the operating system's kernel's scheduler. This may not
necessarily be precise, and some implementations do not even consider the nanosecond
parameter (possibly rounding to the nearest millisecond).
As we know that we should use synchronized keyword to make execution of a method or block
exclusive. But few of us may not be aware of one more important aspect of using synchronized and
volatile keyword: apart from making a unit of code atomic, it also provides read / write barrier.
What is this read / write barrier? Let's discuss this using an example:
class Counter {
Let's suppose a thread A calls incrementCount() first then another thread B calls getCount(). In this
scenario there is no guarantee that B will see updated value of count. It may still see count as 10,
even it is also possible that it never sees updated value of count ever.
To understand this behavior we need to understand how Java memory model integrates with
hardware architecture. In Java, each thread has it's own thread stack. This stack contains: method
call stack and local variable created in that thread. In a multi core system, it is quite possible that
two threads are running concurrently in separate cores. In such scenario it is possible that part of
a thread's stack lies inside register / cache of a core. If inside a thread, an object is accessed
using synchronized (or volatile) keyword, after synchronized block that thread syncs it's local copy
of that variable with the main memory. This creates a read / write barrier and makes sure that the
thread is seeing the latest value of that object.
But in our case, since thread B has not used synchronized access to count, it might be refering
value of count stored in register and may never see updates from thread A. To make sure that B
sees latest value of count we need to make getCount() synchronized as well.
Now when thread A is done with updating count it unlocks Counter instance, at the same time
https://riptutorial.com/ 228
creates write barrier and flushes all changes done inside that block to the main memory. Similarly
when thread B acquires lock on the same instance of Counter, it enters into read barrier and reads
value of count from main memory and sees all updates.
Same visibility effect goes for volatile read / writes as well. All variables updated prior to write to
volatile will be flushed to main memory and all reads after volatile variable read will be from
main memory.
There are two main approaches to creating a thread in Java. In essence, creating a thread is as
easy as writing the code that will be executed in it. The two approaches differ in where you define
that code.
Note: I'll use Thread to refer to the java.lang.Thread class and thread to refer to the logical
concept of threads.
https://riptutorial.com/ 229
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread running!");
}
}
}
Now since we've already defined the code to be executed, the thread can be created simply as:
The Thread class also contains a constructor accepting a string, which will be used as the thread's
name. This can be particulary useful when debugging a multi thread program.
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread running! ");
}
}
}
The second approach is to define the code using java.lang.Runnable and its only method run().
The Thread class then allows you to execute that method in a separated thread. To achieve this,
create the thread using a constructor accepting an instance of the Runnable interface.
This can be very powerful when combined with lambdas or methods references (Java 8 only):
Practicaly speaking, you can use both approaches without worries. However the general wisdom
says to use the latter.
For every of the four mentioned constructors, there is also an alternative accepting an instance of
java.lang.ThreadGroup as the first parameter.
https://riptutorial.com/ 230
ThreadGroup tg = new ThreadGroup("Operators");
Thread t = new Thread(tg, operator::hardWork, "PI operator");
The ThreadGroup represents a set of threads. You can only add a Thread to a ThreadGroup using
a Thread's constructor. The ThreadGroup can then be used to manage all its Threads together, as
well as the Thread can gain information from its ThreadGroup.
So to sumarize, the Thread can be created with one of these public constructors:
Thread()
Thread(String name)
Thread(Runnable target)
Thread(Runnable target, String name)
Thread(ThreadGroup group, String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
The last one allows us to define desired stack size for the new thread.
Often the code readability suffers when creating and configuring many Threads with same
properties or from the same pattern. That's when java.util.concurrent.ThreadFactory can be used.
This interface allows you to encapsulate the procedure of creating the thread through the factory
pattern and its only method newThread(Runnable).
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Worker " + id++);
}
}
Each Java Thread has an interrupt flag, which is initially false. Interrupting a thread, is essentially
nothing more than setting that flag to true. The code running on that thread can check the flag on
occasion and act upon it. The code can also ignore it completely. But why would each Thread
have such a flag? After all, having a boolean flag on a thread is something we can just organize
ourselves, if and when we need it. Well, there are methods that behave in a special way when the
thread they're running on is interrupted. These methods are called blocking methods. These are
methods that put the thread in the WAITING or TIMED_WAITING state. When a thread is in this
state, interrupting it, will cause an InterruptedException to be thrown on the interrupted thread,
rather than the interrupt flag being set to true, and the thread becomes RUNNABLE again. Code
that invokes a blocking method is forced to deal with the InterruptedException, since it is a
checked exception. So, and hence its name, an interrupt can have the effect of interrupting a
WAIT, effectively ending it. Note that not all methods that are somehow waiting (e.g. blocking IO)
respond to interruption in that way, as they don't put the thread in a waiting state. Lastly a thread
https://riptutorial.com/ 231
that has its interrupt flag set, that enters a blocking method (i.e. tries to get into a waiting state),
will immediately throw an InterruptedException and the interrupt flag will be cleared.
Other than these mechanics, Java does not assign any special semantic meaning to interruption.
Code is free to interpret an interrupt any way it likes. But most often interruption is used to signal
to a thread it should stop running at its earliest convenience. But, as should be clear from the
above, it is up to the code on that thread to react to that interruption appropriately in order to stop
running. Stopping a thread is a collaboration. When a thread is interrupted its running code can be
several levels deep into the stacktrace. Most code doesn't call a blocking method, and finishes
timely enough to not delay the stopping of the thread unduly. The code that should mostly be
concerned with being responsive to interruption, is code that is in a loop handling tasks until there
are none left, or until a flag is set signalling it to stop that loop. Loops that handle possibly infinite
tasks (i.e. they keep running in principle) should check the interrupt flag in order to exit the loop.
For finite loops the semantics may dictate that all tasks must be finished before ending, or it may
be appropriate to leave some tasks unhandled. Code that calls blocking methods will be forced to
deal with the InterruptedException. If at all semantically possible, it can simply propagate the
InterruptedException and declare to throw it. As such it becomes a blocking method itself in regard
to its callers. If it cannot propagate the exception, it should at the very least set the interrupted flag,
so callers higher up the stack also know the thread was interrupted. In some cases the method
needs to continue waiting regardless of the InterruptedException, in which case it must delay
setting the interrupted flag until after it is done waiting, this may involve setting a local variable,
which is to be checked prior to exiting the method to then interrupt its thread.
Examples :
TaskHandler(BlockingQueue<Task> queue) {
this.queue = queue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) { // check for interrupt flag, exit
loop when interrupted
try {
Task task = queue.take(); // blocking call, responsive to interruption
handle(task);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // cannot throw InterruptedException (due
to Runnable interface restriction) so indicating interruption by setting the flag
}
}
}
https://riptutorial.com/ 232
Example of code that delays setting the interrupt flag until completely done :
MustFinishHandler(BlockingQueue<Task> queue) {
this.queue = queue;
}
@Override
public void run() {
boolean shouldInterrupt = false;
while (true) {
try {
Task task = queue.take();
if (task.isEndOfTasks()) {
if (shouldInterrupt) {
Thread.currentThread().interrupt();
}
return;
}
handle(task);
} catch (InterruptedException e) {
shouldInterrupt = true; // must finish, remember to set interrupt flag when
we're done
}
}
}
Example of code that has a fixed list of tasks but may quit early when interrupted
@Override
public void run() {
for (Task task : tasks) {
if (Thread.currentThread().isInterrupted()) {
return;
}
handle(task);
}
}
https://riptutorial.com/ 233
Below code showcases multiple Producer/Consumer program. Both Producer and Consumer
threads share same global queue.
import java.util.concurrent.*;
import java.util.Random;
pes.shutdown();
ces.shutdown();
}
}
https://riptutorial.com/ 234
// Consumer consumes numbers generated from Producer threads continuously
while(true){
try {
int num = sharedQueue.take();
System.out.println("Consumed: "+ num + ":by thread:"+threadNo);
} catch (Exception err) {
err.printStackTrace();
}
}
}
}
output:
Produced:69:by thread:2
Produced:553:by thread:1
Consumed: 69:by thread:1
Consumed: 553:by thread:2
Produced:41:by thread:2
Produced:796:by thread:1
Consumed: 41:by thread:1
Consumed: 796:by thread:2
Produced:728:by thread:2
Consumed: 728:by thread:1
and so on ................
Explanation:
It is sometimes required for a process to concurrently write and read the same "data".
The ReadWriteLock interface, and its ReentrantReadWriteLock implementation allows for an access
pattern that can be described as follow :
1. There can be any number of concurrent readers of the data. If there is at least one reader
access granted, then no writer access is possible.
https://riptutorial.com/ 235
2. There can be at most one single writer to the data. If there is a writer access granted, then
no reader can access the data.
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Sample {
// Our lock. The constructor allows a "fairness" setting, which guarantees the chronology of
lock attributions.
protected static final ReadWriteLock RW_LOCK = new ReentrantReadWriteLock();
NOTE 1 : This precise use case has a cleaner solution using AtomicInteger, but what is described
here is an access pattern, that works regardless of the fact that data here is an integer that as an
Atomic variant.
NOTE 2 : The lock on the reading part is really needed, although it might not look so to the casual
reader. Indeed, if you do not lock on the reader side, any number of things can go wrong, amongst
which :
1. The writes of primitive values are not guaranteed to be atomic on all JVMs, so the reader
could see e.g. only 32bits of a 64bits write if data were a 64bits long type
2. The visibility of the write from a thread that did not perform it is guaranteed by the JVM only if
we establish Happen Before relationship between the writes and the reads. This relationship
is established when both readers and writers use their respective locks, but not otherwise
Java SE 8
In case higher performance is required, an under certain types of usage, there is a faster lock type
available, called the StampedLock, that amongst other things implements an optimistic lock mode.
https://riptutorial.com/ 236
This lock works very differently from the ReadWriteLock, and this sample is not transposable.
Runnable Object
The Runnable interface defines a single method, run(), meant to contain the code executed in the
thread.
The Runnable object is passed to the Thread constructor. And Thread's start() method is called.
Example
@Override
public void run() {
System.out.println("Hello from a thread");
}
Example in Java8:
A Runnable object employment is more general, because the Runnable object can subclass a class
other than Thread.
Thread subclassing is easier to use in simple applications, but is limited by the fact that your task
class must be a descendant of Thread.
Semaphore
A Semaphore is a high-level synchronizer that maintains a set of permits that can be acquired and
released by threads. A Semaphore can be imagined as a counter of permits that will be
decremented when a thread acquires, and incremented when a thread releases. If the amount of
permits is 0 when a thread attempts to acquire, then the thread will block until a permit is made
available (or until the thread is interrupted).
Semaphore semaphore = new Semaphore(1); // The int value being the number of permits
https://riptutorial.com/ 237
The Semaphore constructor accepts an additional boolean parameter for fairness. When set false,
this class makes no guarantees about the order in which threads acquire permits. When fairness
is set true, the semaphore guarantees that threads invoking any of the acquire methods are
selected to obtain permits in the order in which their invocation of those methods was processed.
It is declared in the following manner:
Now let's look at an example from javadocs, where Semaphore is used to control access to a pool
of items. A Semaphore is used in this example to provide blocking functionality in order to ensure
that there are always items to be obtained when getItem() is called.
class Pool {
/*
* Note that this DOES NOT bound the amount that may be released!
* This is only a starting value for the Semaphore and has no other
* significant meaning UNLESS you enforce this inside of the
* getNextAvailableItem() and markAsUnused() methods
*/
private static final int MAX_AVAILABLE = 100;
private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
/**
* Obtains the next available item and reduces the permit count by 1.
* If there are no items available, block.
*/
public Object getItem() throws InterruptedException {
available.acquire();
return getNextAvailableItem();
}
/**
* Puts the item into the pool and add 1 permit.
*/
public void putItem(Object x) {
if (markAsUnused(x))
available.release();
}
A Threadpool has a Queue of tasks, of which each will be executed on one these Threads.
The following example shows how to add two int arrays using a Threadpool.
Java SE 8
https://riptutorial.com/ 238
int[] firstArray = { 2, 4, 6, 8 };
int[] secondArray = { 1, 3, 5, 7 };
int[] result = { 0, 0, 0, 0 };
System.out.println(Arrays.toString(result));
Notes:
1. This example is purely illustrative. In practice, there won't be any speedup by using threads
for a task this small. A slowdown is likely, since the overheads of task creation and
scheduling will swamp the time taken to run a task.
2. If you were using Java 7 and earlier, you would use anonymous classes instead of lambdas
to implement the tasks.
Get status of all threads started by your program excluding system threads
Code snippet:
import java.util.Set;
https://riptutorial.com/ 239
}
}
Output:
Thread :Thread[MyThread:1,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:3,5,main]:state:TIMED_WAITING
Thread :Thread[main,5,main]:state:RUNNABLE
Thread :Thread[MyThread:4,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:0,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:2,5,main]:state:TIMED_WAITING
Thread count started by Main thread:6
Explanation:
In absence of above ThreadGroup condition, the program returns status of below System
Threads:
Reference Handler
Signal Dispatcher
Attach Listener
Finalizer
While Runnable provides a means to wrap code to be executed in a different thread, it has a
limitation in that it cannot return a result from the execution. The only way to get some return value
from the execution of a Runnable is to assign the result to a variable accessible in a scope outside
of the Runnable.
Callable was introduced in Java 5 as a peer to Runnable. Callable is essentially the same except it
has a call method instead of run. The call method has the additional capability to return a result
and is also allowed to throw checked exceptions.
The result from a Callable task submission is available to be tapped via a Future
can be considered a container of sorts that houses the result of the Callable computation.
Future
Computation of the callable can carry on in another thread, and any attempt to tap the result of a
Future
https://riptutorial.com/ 240
will block and will only return the result once it is available.
Callable Interface
Future
interface Future<V> {
V get();
V get(long timeout, TimeUnit unit);
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
}
@Override
public String call() throws Exception {
// just sleep for 10 secs to simulate a lengthy computation
Thread.sleep(10000);
System.out.println("Result after a lengthy 10sec calculation");
return "Complex Result"; // the result
}
}
Output
While get() is the method to extract the actual result Future has provision
https://riptutorial.com/ 241
• get(long timeout, TimeUnit unit) defines maximum time period during current thread will wait
for a result;
• To cancel the task call cancel(mayInterruptIfRunning). The flag mayInterrupt indicates that
task should be interrupted if it was started and is running right now;
• To check if task is completed/finished by calling isDone();
• To check if the lengthy task were cancelled isCancelled().
Prior to Java 5's concurrent package introduction threading was more low level.The introduction of
this package provided several higher level concurrent programming aids/constructs.
Locks are thread synchronisation mechanisms that essentially serve the same purpose as
synchronized blocks or key words.
Intrinsic Locking
Locks also have functionality available that intrinsic locking does not offer, such as locking but
remaining responsive to interruption, or trying to lock, and not block when unable to.
class Locky {
int count = 0; // shared among multiple threads
https://riptutorial.com/ 242
++count; // a non-atomic operation
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // stopping
}
} finally {
if (!Thread.currentThread().isInterrupted()) {
lockObj.unlock(); // sure to release the lock without fail
}
}
}
}
There are several variants of lock available.For more details refer the api docs here
https://riptutorial.com/ 243
Chapter 36: Console I/O
Examples
Reading user input from the console
Using BufferedReader:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
Using Scanner:
Java SE 5
import java.util.Scanner;
System.out.println("Please enter your first and your last name, on separate lines.");
https://riptutorial.com/ 244
There are two methods for obtaining Strings, next() and nextLine(). next() returns text up until the
first space (also known as a "token"), and nextLine() returns all text that the user inputted until
pressing enter.
Scanner also provides utility methods for reading data types other than String. These include:
scanner.nextByte();
scanner.nextShort();
scanner.nextInt();
scanner.nextLong();
scanner.nextFloat();
scanner.nextDouble();
scanner.nextBigInteger();
scanner.nextBigDecimal();
Prefixing any of these methods with has (as in hasNextLine(), hasNextInt()) returns true if the
stream has any more of the request type. Note: These methods will crash the program if the input
is not of the requested type (for example, typing "a" for nextInt() ). You can use a try {} catch()
{} to prevent this (see: Exceptions)
Using System.console:
Java SE 6
Advantages:
Note: This will only work if the program is run from a real command line without redirecting the
standard input and output streams. It does not work when the program is run from within certain
IDEs, such as Eclipse. For code that works within IDEs and with stream redirection, see the other
examples.
https://riptutorial.com/ 245
Implementing Basic Command-Line Behavior
For basic prototypes or basic command-line behavior, the following loop comes in handy.
private static final String CMD_QUIT = "quit"; //string for exiting the program
private static final String CMD_HELLO = "hello"; //string for printing "Hello World!"
on the screen
private static final String CMD_ANSWER = "answer"; //string for printing 42 on the
screen
try {
claimCli.start(); //calls the start function to do the work like console
}
catch (IOException e) {
e.printStackTrace(); //prints the exception log if it is failed to do get the
user input or something like that
}
}
cmd = reader.readLine(); //takes input from user. user input should be started
with "hello", "answer" or "quit"
String[] cmdArr = cmd.split(" ");
// prints "Hello World!" on the screen if user input starts with "hello"
private void hello(String[] cmdArr) {
System.out.println("Hello World!");
}
https://riptutorial.com/ 246
Aligning strings in console
The method PrintWriter.format (called through System.out.format) can be used to print aligned
strings in console. The method receives a String with the format information and a series of
objects to format:
Output:
1 1 1
1234 1234 1234
1234567 1234567 123456
123456789 12345678 123456
Using format strings with fixed size permits to print the strings in a table-like appearance with fixed
size columns:
Output:
1 1 1
123 1234 1234
123 1234567 123456
123 12345678 123456
https://riptutorial.com/ 247
Format strings examples
• %s:just a string with no formatting
• %5s: format the string with a minimum of 5 characters; if the string is shorter it will be
padded to 5 characters and right aligned
• %-5s: format the string with a minimum of 5 characters; if the string is shorter it will be
padded to 5 characters and left aligned
• %5.10s: format the string with a minimum of 5 characters and a maximum of 10 characters;
if the string is shorter than 5 it will be padded to 5 characters and right aligned; if the string
is longer than 10 it will be truncated to 10 characters and right aligned
• %-5.5s: format the string with a fixed size of 5 characters (minimum and maximum are
equals); if the string is shorter than 5 it will be padded to 5 characters and left aligned; if the
string is longer than 5 it will be truncated to 5 characters and left aligned
https://riptutorial.com/ 248
Chapter 37: Constructors
Introduction
While not required, constructors in Java are methods recognized by the compiler to instantiate
specific values for the class which may be essential to the role of the object. This topic
demonstrates proper usage of Java class constructors.
Remarks
The Java Language Specification talks at length about the exact nature of constructor semantics.
They can be found in JLS §8.8
Examples
Default Constructor
The "default" for constructors is that they do not have any arguments. In case you do not specify
any constructor, the compiler will generate a default constructor for you.
This means the following two snippets are semantically equivalent:
}
}
The visibility of the default constructor is the same as the visibility of the class. Thus a class
defined package-privately has a package-private default constructor
However, if you have non-default constructor, the compiler will not generate a default constructor
for you. So these are not equivalent:
https://riptutorial.com/ 249
}
public TestClass(String arg) {
}
}
Beware that the generated constructor performs no non-standard initialization. This means all
fields of your class will have their default value, unless they have an initializer.
public TestClass() {
testData = "Test"
}
}
A class can have multiple constructors with different signatures. To chain constructor calls (call a
different constructor of the same class when instantiating) use this().
public TestClass() {
this("Test"); // testData defaults to "Test"
}
}
https://riptutorial.com/ 250
Called like this:
Say you have a Parent class and a Child class. To construct a Child instance always requires
some Parent constructor to be run at the very gebinning of the Child constructor. We can select
the Parent constructor we want by explicitly calling super(...) with the appropriate arguments as
our first Child constructor statement. Doing this saves us time by reusing the Parent classes'
constructor instead of rewriting the same code in the Child classes' constructor.
class Parent {
private String name;
private int age;
// This does not even compile, because name and age are private,
// making them invisible even to the child class.
class Child extends Parent {
public Child() {
// compiler implicitly calls super() here
name = "John";
age = 42;
}
}
class Parent {
private String name;
private int age;
public Parent(String tName, int tAge) {
name = tName;
age = tAge;
}
}
https://riptutorial.com/ 251
Note: Calls to another constructor (chaining) or the super constructor MUST be the first statement
inside the constructor.
If you call the super(...) constructor explicitly, a matching parent constructor must exist (that's
straightforward, isn't it?).
If you don't call any super(...) constructor explicitly, your parent class must have a no-args
constructor - and this can be either written explicitly or created as a default by the compiler if the
parent class doesn't provide any constructor.
class Parent{
public Parent(String tName, int tAge) {}
}
The class Parent has no default constructor, so, the compiler can't add super in the Child
constructor. This code will not compile. You must change the constructors to fit both sides, or write
your own super call, like that:
https://riptutorial.com/ 252
Chapter 38: Converting to and from Strings
Examples
Converting other datatypes to String
• You can get the value of other primitive data types as a String using one the String class's
valueOf methods.
For example:
int i = 42;
String string = String.valueOf(i);
//string now equals "42”.
This method is also overloaded for other datatypes, such as float, double, boolean, and even
Object.
• You can also get any other Object (any instance of any class) as a String by calling .toString
on it. For this to give useful output, the class must override toString(). Most of the standard
Java library classes do, such as Date and others.
For example:
You can also convert any number type to String with short notation like below.
int i = 10;
String str = i + "";
To encode a string into a byte array, you can simply use the String#getBytes() method, with one of
the standard character sets available on any Java runtime:
and to decode:
https://riptutorial.com/ 253
String testString = new String(bytes, StandardCharsets.UTF_8);
For less common character sets you can indicate the character set with a string:
this does however mean that you have to handle the checked UnsupportedCharsetException.
The following call will use the default character set. The default character set is platform specific
and generally differs between Windows, Mac and Linux platforms.
Note that invalid characters and bytes may be replaced or skipped by these methods. For more
control - for instance for validating input - you're encouraged to use the CharsetEncoder and
CharsetDecoder classes.
Occasionally you will find the need to encode binary data as a base64-encoded string.
For this we can use the DatatypeConverter class from the javax.xml.bind package:
import javax.xml.bind.DatatypeConverter;
import java.util.Arrays;
https://riptutorial.com/ 254
byte[] decodedData = DatatypeConverter.parseBase64Binary(encodedData);
// assert that the original data and the decoded data are equal
assert Arrays.equals(binaryData, decodedData);
Apache commons-codec
import org.apache.commons.codec.binary.Base64;
If you inspect this program wile running, you will see that someBinaryData encodes to
c29tZUJpbmFyeURhdGE=, a very managable UTF-8 String object.
Java SE 8
// decode a String
byte [] barr = Base64.getDecoder().decode(encoded);
Reference
Each numeric wrapper class provides a parseXxx method that converts a String to the
corresponding primitive type. The following code converts a String to an int using the
Integer.parseInt method:
https://riptutorial.com/ 255
To convert to a String to an instance of a numeric wrapper class you can either use an overload of
the wrapper classes valueOf method:
The above pattern works for byte, short, int, long, float and double and the corresponding wrapper
classes (Byte, Short, Integer, Long, Float and Double).
Exceptions
A String can be read from an InputStream using the byte array constructor.
import java.io.*;
This uses the system default charset, although an alternate charset may be specified:
You can convert a numeric string to various Java numeric types as follows:
String to int:
https://riptutorial.com/ 256
String number = "12";
int num = Integer.parseInt(number);
String to float:
String to double:
String to boolean:
String to long:
String to BigInteger:
String to BigDecimal:
Conversion Exceptions:
The numeric conversions above will all throw an (unchecked) NumberFormatException if you attempt
to parse a string that is not a suitably formatted number, or is out of range for the target type. The
Exceptions topic discusses how to deal with such exceptions.
If you wanted to test that you can parse a string, you could implement a tryParse... method like
this:
https://riptutorial.com/ 257
return false;
}
}
However, calling this tryParse... method immediately before parsing is (arguably) poor practice. It
would be better to just call the parse... method and deal with the exception.
https://riptutorial.com/ 258
Chapter 39: Creating Images
Programmatically
Remarks
BufferedImage.getGraphics() always returns Graphics2D.
Using a VolatileImage may significantly improve the speed of drawing operations, but also has its
drawbacks: its contents may be lost at any moment and they may have to be redrawn from
scratch.
Examples
Creating a simple image programmatically and displaying it
class ImageCreationExample {
return img;
}
https://riptutorial.com/ 259
ImageIcon icon = new ImageIcon(img);
frame.add(new JLabel(icon));
frame.pack();
frame.setVisible(true);
}
}
https://riptutorial.com/ 260
}
https://riptutorial.com/ 261
Creating an image with BufferedImage class
Graphics g = image.createGraphics();
g.setColor(Color.BLUE);
g.drawOval(120, 120, 80, 40);
//now image has programmatically generated content, you can use it in graphics.drawImage() to
draw it somewhere else
//or just simply save it to a file
ImageIO.write(image, "png", new File("myimage.png"));
Output:
https://riptutorial.com/ 262
Editing and re-using image with BufferedImage
//modify it
Graphics g = cat.createGraphics();
g.setColor(Color.RED);
g.drawString("Cat", 10, 10);
g.dispose();
g.setColor(Color.BLUE);
g.drawRect(0, 0, 255, 255); //add some nice border
g.dispose(); //and done
Produced file:
https://riptutorial.com/ 263
Setting individual pixel's color in BufferedImage
//you don't have to use the Graphics object, you can read and set pixel color individually
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 256; j++) {
int alpha = 255; //don't forget this, or use BufferedImage.TYPE_INT_RGB instead
int red = i; //or any formula you like
int green = j; //or any formula you like
int blue = 50; //or any formula you like
int color = (alpha << 24) | (red << 16) | (green << 8) | blue;
image.setRGB(i, j, color);
}
}
Output:
/**
* Resizes an image using a Graphics2D object backed by a BufferedImage.
https://riptutorial.com/ 264
* @param srcImg - source image to scale
* @param w - desired width
* @param h - desired height
* @return - the new resized image
*/
private BufferedImage getScaledImage(Image srcImg, int w, int h){
//Create a new image with good size that contains or might contain arbitrary alpha values
between and including 0.0 and 1.0.
BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TRANSLUCENT);
//Finally draw the source image in the Graphics2D with the desired size.
g2.drawImage(srcImg, 0, 0, w, h, null);
//Disposes of this graphics context and releases any system resources that it is using
g2.dispose();
https://riptutorial.com/ 265
Chapter 40: Currency and Money
Examples
Add custom currency
https://riptutorial.com/ 266
Chapter 41: Date Class
Syntax
• Date object = new Date();
• Date object = new Date(long date);
Parameters
Parameter Explanation
No Creates a new Date object using the allocation time (to the nearest
parameter millisecond)
Creates a new Date object with the time set to the number of milliseconds
long date
since "the epoch" (January 1, 1970, 00:00:00 GMT)
Remarks
Representation
Internally, a Java Date object is represented as a long; it is the number of milliseconds since a
specific time (referred to as the epoch). The original Java Date class had methods for dealing with
time zones, etc., but these were deprecated in favor of the then-new Calendar class.
So if all you want to do in your code is represent a specific time, you can create a Date class and
store it, etc. If you want to print out a human-readable version of that date, however, you create a
Calendar class and use its formatting to produce hours, minutes, seconds, days, time zones, etc.
Keep in mind that a specific millisecond is displayed as different hours in different time zones;
normally you want to display one in the "local" time zone, but the formatting methods have to take
into account that you may want to display it for some other one.
Also be aware that the clocks used by JVMs do not usually have millisecond accuracy; the clock
might only "tick" every 10 milliseconds, and therefore, if timing things, you cannot rely on
measuring things accurately at that level.
Import Statement
import java.util.Date;
Caution
Date instances are mutable, so using them can make it difficult to write thread-safe code or can
https://riptutorial.com/ 267
accidentally provide write access to internal state. For example, in the below class, the getDate()
method allows the caller to modify the transaction date:
The solution is to either return a copy of the date field or use the new APIs in java.time introduced
in Java 8.
Most of the constructor methods in the Date class have been deprecated and should not be used.
In almost all cases, it is advisable to use Calendar class for date operations.
Java 8
Java 8 introduces new time and date API in the package java.time, including LocalDate and
LocalTime. The classes in the java.time package provide an overhauled API that is easier to use.
If you are writing to Java 8 it is strongly encouraged that you use this new API. See Dates and
Time (java.time.*) .
Examples
Creating Date objects
Here this Date object contains the current date and time when this object was created.
Date objects are best created through a Calendar instance since the use of the data constructors is
deprecated and discouraged. To do se we need to get an instance of the Calendar class from the
factory method. Then we can set year, month and day of month by using numbers or in case of
months constants provided py the Calendar class to improve readability and reduce errors.
Along with date, we can also pass time in the order of hour, minutes and seconds.
https://riptutorial.com/ 268
Comparing Date objects
//Before example
System.out.printf("Is %1$tF before %2$tF? %3$b%n", today, birthdate,
Boolean.valueOf(today.before(birthdate)));
System.out.printf("Is %1$tF before %1$tF? %3$b%n", today, today,
Boolean.valueOf(today.before(today)));
System.out.printf("Is %2$tF before %1$tF? %3$b%n", today, birthdate,
Boolean.valueOf(birthdate.before(today)));
//After example
System.out.printf("Is %1$tF after %2$tF? %3$b%n", today, birthdate,
Boolean.valueOf(today.after(birthdate)));
System.out.printf("Is %1$tF after %1$tF? %3$b%n", today, birthdate,
Boolean.valueOf(today.after(today)));
System.out.printf("Is %2$tF after %1$tF? %3$b%n", today, birthdate,
Boolean.valueOf(birthdate.after(today)));
//Compare example
System.out.printf("Compare %1$tF to %2$tF: %3$d%n", today, birthdate,
Integer.valueOf(today.compareTo(birthdate)));
System.out.printf("Compare %1$tF to %1$tF: %3$d%n", today, birthdate,
Integer.valueOf(today.compareTo(today)));
System.out.printf("Compare %2$tF to %1$tF: %3$d%n", today, birthdate,
Integer.valueOf(birthdate.compareTo(today)));
//Equal example
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", today, birthdate,
Boolean.valueOf(today.equals(birthdate)));
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", birthdate, samebirthdate,
Boolean.valueOf(birthdate.equals(samebirthdate)));
System.out.printf(
"Because birthdate.getTime() -> %1$d is different from samebirthdate.getTime() ->
%2$d, there are millisecondes!%n",
Long.valueOf(birthdate.getTime()), Long.valueOf(samebirthdate.getTime()));
https://riptutorial.com/ 269
birthdate = calendar.getTime();
samebirthdate = calendar2.getTime();
Java SE 8
//Hours, minutes, second and nanoOfsecond can also be configured with an other class
LocalDateTime
//LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
//isBefore example
System.out.printf("Is %1$tF before %2$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.isBefore(birthdate2)));
System.out.printf("Is %1$tF before %1$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.isBefore(now)));
System.out.printf("Is %2$tF before %1$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(birthdate2.isBefore(now)));
//isAfter example
System.out.printf("Is %1$tF after %2$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.isAfter(birthdate2)));
System.out.printf("Is %1$tF after %1$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.isAfter(now)));
System.out.printf("Is %2$tF after %1$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(birthdate2.isAfter(now)));
//compareTo example
System.out.printf("Compare %1$tF to %2$tF %3$d%n", now, birthdate2,
Integer.valueOf(now.compareTo(birthdate2)));
System.out.printf("Compare %1$tF to %1$tF %3$d%n", now, birthdate2,
Integer.valueOf(now.compareTo(now)));
System.out.printf("Compare %2$tF to %1$tF %3$d%n", now, birthdate2,
Integer.valueOf(birthdate2.compareTo(now)));
//equals example
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.equals(birthdate2)));
System.out.printf("Is %1$tF to %2$tF? %3$b%n", birthdate2, birthdate3,
Boolean.valueOf(birthdate2.equals(birthdate3)));
//isEqual example
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", now, birthdate2,
Boolean.valueOf(now.isEqual(birthdate2)));
System.out.printf("Is %1$tF to %2$tF? %3$b%n", birthdate2, birthdate3,
Boolean.valueOf(birthdate2.isEqual(birthdate3)));
https://riptutorial.com/ 270
Date comparison before Java 8
Before Java 8, dates could be compared using java.util.Calendar and java.util.Date classes. Date
class offers 4 methods to compare dates :
• after(Date when)
• before(Date when)
• compareTo(Date anotherDate)
• equals(Object obj)
after, before, compareTo and equals methods compare the values returned by getTime() method for
each date.
• Value greater than 0 : when the Date is after the Date argument
• Value greater than 0 : when the Date is before the Date argument
• Value equals to 0 : when the Date is equal to the Date argument
equals results can be surprising as shown in the example because values, like milliseconds, are
not initialize with the same value if not explicitly given.
Since Java 8
With Java 8 a new Object to work with Date is available java.time.LocalDate. LocalDate implements
ChronoLocalDate, the abstract representation of a date where the Chronology, or calendar
system, is pluggable.
To have the date time precision the Object java.time.LocalDateTime has to be used. LocalDate and
LocalDateTime use the same methods name for comparing.
Comparing dates using a LocalDate is different from using ChronoLocalDate because the chronology,
or calendar system are not taken in account the first one.
Because most application should use LocalDate, ChronoLocalDate is not included in examples.
Further reading here.
Most applications should declare method signatures, fields and variables as LocalDate,
not this[ChronoLocalDate] interface.
• isAfter(ChronoLocalDate other)
• isBefore(ChronoLocalDate other)
• isEqual(ChronoLocalDate other)
• compareTo(ChronoLocalDate other)
• equals(Object obj)
https://riptutorial.com/ 271
In case of LocalDate parameter, isAfter, isBefore, isEqual, equals and compareTo now use this
method:
equals method check if the parameter reference equals the date first whereas isEqual directly calls
compareTo0.
In case of an other class instance of ChronoLocalDate the dates are compared using the Epoch Day.
The Epoch Day count is a simple incrementing count of days where day 0 is 1970-01-01 (ISO).
format() from SimpleDateFormat class helps to convert a Date object into certain format String object
by using the supplied pattern string.
dateFormat.applyPattern("dd-MM-yyyy");
System.out.println(dateFormat.format(today)); //25-02-2016
Note: Here mm (small letter m) denotes minutes and MM (capital M) denotes month. Pay careful
attention when formatting years: capital "Y" (Y) indicates the "week in the year" while lower-case
"y" (y) indicates the year.
parse() from SimpleDateFormat class helps to convert a String pattern into a Date object.
https://riptutorial.com/ 272
There are 4 different styles for the text format, SHORT, MEDIUM (this is the default), LONG and FULL, all of
which depend on the locale. If no locale is specified, the system default locale is used.
Using the following code with the format string yyyy/MM/dd hh:mm.ss, we will receive the following
output
2016/04/19 11:45.36
// print it
System.out.println(formattedDate);
This method can be used to convert a formatted string representation of a date into a Date object.
/**
* Parses the date using the given format.
*
* @param formattedDate the formatted date string
* @param dateFormat the date format which was used to create the string.
* @return the date
*/
public static Date parseDate(String formattedDate, String dateFormat) {
Date date = null;
https://riptutorial.com/ 273
SimpleDateFormat objDf = new SimpleDateFormat(dateFormat);
try {
date = objDf.parse(formattedDate);
} catch (ParseException e) {
// Do what ever needs to be done with exception.
}
return date;
}
While the Java Date class has several constructors, you'll notice that most are deprecated. The
only acceptable way of creating a Date instance directly is either by using the empty constructor or
passing in a long (number of milliseconds since standard base time). Neither are handy unless
you're looking for the current date or have another Date instance already in hand.
To create a new date, you will need a Calendar instance. From there you can set the Calendar
instance to the date that you need.
Calendar c = Calendar.getInstance();
This returns a new Calendar instance set to the current time. Calendar has many methods for
mutating it's date and time or setting it outright. In this case, we'll set it to a specific date.
c.set(1974, 6, 2, 8, 0, 0);
Date d = c.getTime();
The getTime method returns the Date instance that we need. Keep in mind that the Calendar set
methods only set one or more fields, they do not set them all. That is, if you set the year, the other
fields remain unchanged.
PITFALL
In many cases, this code snippet fulfills its purpose, but keep in mind that two important parts of
the date/time are not defined.
• the (1974, 6, 2, 8, 0, 0) parameters are interpreted within the default timezone, defined
somewhere else,
• the milliseconds are not set to zero, but filled from the system clock at the time the Calendar
instance is created.
Date and LocalDate objects cannot be exactly converted between each other since a Date object
represents both a specific day and time, while a LocalDate object does not contain time or
timezone information. However, it can be useful to convert between the two if you only care about
the actual date information and not the time information.
Creates a LocalDate
https://riptutorial.com/ 274
// Create a default date
LocalDate lDate = LocalDate.now();
Creates a LocalDateTime
// Date to LocalDate
LocalDate localDate = date.toInstant().atZone(defaultZoneId).toLocalDate();
// LocalDate to Date
Date.from(localDate.atStartOfDay(defaultZoneId).toInstant());
// Date to LocalDateTime
LocalDateTime localDateTime = date.toInstant().atZone(defaultZoneId).toLocalDateTime();
// LocalDateTime to Date
Date out = Date.from(localDateTime.atZone(defaultZoneId).toInstant());
https://riptutorial.com/ 275
current time in the system default timezone
However, it is possible to display the date represented by the point in time described by the Date
object in a different time zone using e.g. java.text.SimpleDateFormat:
Output:
java.sql.Date is a wrapper around millisecond value and is used by JDBC to identify an SQL DATE
type
In the below example, we use the java.util.Date() constructor, that creates a Date object and
initializes it to represent time to the nearest millisecond. This date is used in the
convert(java.util.Date utilDate) method to return a java.sql.Date object
Example
https://riptutorial.com/ 276
Output
java.util.Date has both date and time information, whereas java.sql.Date only has date
information
LocalTime
To use just the time part of a Date use LocalTime. You can instantiate a LocalTime object in a
couple ways
LocalTime also has a built in toString method that displays the format very nicely.
System.out.println(time);
you can also get, add and subtract hours, minutes, seconds, and nanoseconds from the
LocalTime object i.e.
time.plusMinutes(1);
time.getMinutes();
time.minusMinutes(1);
You can turn it into a Date object with the following code:
this class works very nicely within a timer class to simulate an alarm clock.
https://riptutorial.com/ 277
Chapter 42: Dates and Time (java.time.*)
Examples
Simple Date Manipulations
LocalDate.now()
LocalDate y = LocalDate.now().minusDays(1);
LocalDate t = LocalDate.now().plusDays(1);
In addition to the plus and minus methods, there are a set of "with" methods that can be used to set
a particular field on a LocalDate instance.
LocalDate.now().withMonth(6);
The example above returns a new instance with the month set to June (this differs from
java.util.Date where setMonth was indexed a 0 making June 5).
Because LocalDate manipulations return immutable LocalDate instances, these methods may also
be chained together.
LocalDate ld = LocalDate.now().plusDays(1).plusYears(1);
https://riptutorial.com/ 278
Date and time with time zone information
Date and time with offset information (i.e. no DST changes taken into account)
Instant
Following example also have explanation required for understanding example within it.
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.TimeZone;
public class SomeMethodsExamples {
/**
* Has the methods of the class {@link LocalDateTime}
*/
public static void checkLocalDateTime() {
https://riptutorial.com/ 279
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("Local Date time using static now() method ::: >>> "
+ localDateTime);
System.out
.println("Following is a static map in ZoneId class which has mapping of short
timezone names to their Actual timezone names");
System.out.println(ZoneId.SHORT_IDS);
/**
* This has the methods of the class {@link LocalDate}
*/
public static void checkLocalDate() {
LocalDate localDate = LocalDate.now();
System.out.println("Gives date without Time using now() method. >> "
+ localDate);
LocalDate localDate2 = LocalDate.now(ZoneId.of(ZoneId.SHORT_IDS
.get("ECT")));
System.out
.println("now() is overridden to take ZoneID as parametere using this we can get
the same date under different timezones. >> "
+ localDate2);
}
/**
* This has the methods of abstract class {@link Clock}. Clock can be used
* for time which has time with {@link TimeZone}.
*/
public static void checkClock() {
Clock clock = Clock.systemUTC();
// Represents time according to ISO 8601
System.out.println("Time using Clock class : " + clock.instant());
}
/**
* This has the {@link Instant} class methods.
*/
public static void checkInstant() {
Instant instant = Instant.now();
https://riptutorial.com/ 280
/**
* This class checks the methods of the {@link Duration} class.
*/
public static void checkDuration() {
// toString() converts the duration to PTnHnMnS format according to ISO
// 8601 standard. If a field is zero its ignored.
System.out.println(Duration.ofDays(2));
}
/**
* Shows Local time without date. It doesn't store or represenet a date and
* time. Instead its a representation of Time like clock on the wall.
*/
public static void checkLocalTime() {
LocalTime localTime = LocalTime.now();
System.out.println("LocalTime :: " + localTime);
}
/**
* A date time with Time zone details in ISO-8601 standards.
*/
public static void checkZonedDateTime() {
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId
.of(ZoneId.SHORT_IDS.get("CST")));
System.out.println(zonedDateTime);
}
}
Before Java 8, there was DateFormat and SimpleDateFormat classes in the package java.text and
this legacy code will be continued to be used for sometime.
In formatting and parsing first you pass a String object to DateTimeFormatter, and in turn use it for
https://riptutorial.com/ 281
formatting or parsing.
import java.time.*;
import java.time.format.*;
class DateTimeFormat
{
public static void main(String[] args) {
//Parsing
String pattern = "d-MM-yyyy HH:mm";
DateTimeFormatter dtF1 = DateTimeFormatter.ofPattern(pattern);
//Formatting
DateTimeFormatter dtF2 = DateTimeFormatter.ofPattern("EEE d, MMMM, yyyy HH:mm");
System.out.println(ldtf1.format(dtF2) +"\n"+ldtf1.format(dtF3));
}
}
An important notice, instead of using Custom patterns, it is good practice to use predefined
formatters. Your code look more clear and usage of ISO8061 will definitely help you in the long
run.
now, since the method between of the ChronoUnit enumerator takes 2 Temporals as parameters so
you can pass without a problem the LocalDate instances
https://riptutorial.com/ 282
Chapter 43: Default Methods
Introduction
Default Method introduced in Java 8, allows developers to add new methods to an interface
without breaking the existing implementations of this interface. It provides flexibility to allow the
interface to define an implementation which will be used as default when a class which
implements that interface fails to provide an implementation of that method.
Syntax
• public default void methodName() {/* method body */}
Remarks
Default methods
• Can be used within an interface, to introduce a behaviour without forcing existing subclasses
to implement it.
• Can be overridden by subclasses or by a sub-interface.
• Are not allowed to override methods in java.lang.Object class.
• If a class implementing more than one interface, inherits default methods with identical
method signatures from each of the intefaces, then it must override and provide its own
interface as if they were not default methods (as part of resolving multiple inheritance).
• Although are intended to introduce a behaviour without breaking existing implementations,
existing subclasses with a static method with same method signature as the newly
introduced default method will still be broken. However this is true even in case of
introducing an instance method in a superclass.
Static methods
• Can be used within an interface, primarily intended to be used as a utility method for default
methods.
• Cannot be overridden by subclasses or by a sub-interface (is hidden to them). However as is
the case with static methods even now, each class or interface can have its own.
• Are not allowed to override instance methods in java.lang.Object class (as is presently the
case for subclasses as well).
https://riptutorial.com/ 283
Below is a table summarizing the interaction between sub-class and super-class.
SUPER_CLASS-INSTANCE- SUPER_CLASS-STATIC-
-
METHOD METHOD
SUB_CLASS-INSTANCE-
overrides generates-compiletime-error
METHOD
SUB_CLASS-STATIC-
generates-compiletime-error hides
METHOD
INTERFACE-DEFAULT- INTERFACE-STATIC-
-
METHOD METHOD
IMPL_CLASS-INSTANCE-
overrides hides
METHOD
IMPL_CLASS-STATIC-
generates-compiletime-error hides
METHOD
References :
• http://www.journaldev.com/2752/java-8-interface-changes-static-method-default-method
• https://docs.oracle.com/javase/tutorial/java/IandI/override.html
Examples
Basic usage of default methods
/**
* Interface with default method
*/
public interface Printable {
default void printString() {
System.out.println( "default implementation" );
}
}
/**
* Class which falls back to default implementation of {@link #printString()}
*/
public class WithDefault
implements Printable
{
https://riptutorial.com/ 284
}
/**
* Custom implementation of {@link #printString()}
*/
public class OverrideDefault
implements Printable {
@Override
public void printString() {
System.out.println( "overridden implementation" );
}
}
new WithDefault().printString();
new OverrideDefault().printString();
default implementation
overridden implementation
You can as well access other interface methods from within your default method.
int getB();
@Override
public int getB() {
return 2;
}
}
System.out.println(new Sum().calculateSum());
Default methods could be used along with interface static methods as well:
https://riptutorial.com/ 285
public interface Summable {
static int getA() {
return 1;
}
System.out.println(new Sum().calculateSum());
In classes, super.foo() will look in superclasses only. If you want to call a default implementation
from a superinterface, you need to qualify super with the interface name: Fooable.super.foo().
The simple answer is that it allows you to evolve an existing interface without breaking existing
implementations.
For example, you have Swim interface that you published 20 years ago.
We did a great job, our interface is very popular, there are many implementation on that around
the world and you don't have control over their source code.
https://riptutorial.com/ 286
System.out.println("Do backstroke");
}
}
After 20 years, you've decided to add new functionality to the interface, but it looks like our
interface is frozen because it will break existing implementations.
Now all existing implementations of our interface can still work. But most importantly they can
implement the newly added method in their own time.
One of the biggest reasons for this change, and one of its biggest uses, is in the Java Collections
framework. Oracle could not add a foreach method to the existing Iterable interface without
breaking all existing code which implemented Iterable. By adding default methods, existing
Iterable implementation will inherit the default implementation.
Implementations in classes, including abstract declarations, take precedence over all interface
defaults.
new FooSwimmer().backStroke();
https://riptutorial.com/ 287
Will produce
AbstractSwimmer.backStroke
new FooSwimmer().backStroke();
Will produce
FooSwimmer.backStroke
public interface A {
default void foo() { System.out.println("A.foo"); }
}
public interface B {
default void foo() { System.out.println("B.foo"); }
}
Here are two interfaces declaring default method foo with the same signature.
If you will try to extend these both interfaces in the new interface you have to make choice of two,
because Java forces you to resolve this collision explicitly.
First, you can declare method foo with the same signature as abstract, which will override A and B
behaviour.
https://riptutorial.com/ 288
void foo();
}
And when you will implement ABExtendsAbstract in the class you will have to provide foo
implementation:
Or second, you can provide a completely new default implementation. You also may reuse code
of A and B foo methods by Accessing overridden default methods from implementing class.
And when you will implement ABExtends in the class you will not have to provide foo implementation:
https://riptutorial.com/ 289
Chapter 44: Dequeue Interface
Introduction
A Deque is linear collection that supports element insertion and removal at both ends.
The name deque is short for "double ended queue" and is usually pronounced "deck".
Most Deque implementations place no fixed limits on the number of elements they may contain,
but this interface supports capacity-restricted deques as well as those with no fixed size limit.
The Deque interface is a richer abstract data type than both Stack and Queue because it
implements both stacks and queues at same time
Remarks
Generics can be used with Deque.
Examples
Adding Elements to Deque
//Retrieves and removes the head of the queue represented by this deque
Object headItem = deque.remove();
https://riptutorial.com/ 290
Object firstItem = deque.removeFirst();
//Retrieves, but does not remove, the head of the queue represented by this deque
Object headItem = deque.element();
//Retrieves, but does not remove, the first element of this deque.
Object firstItem = deque.getFirst();
//Retrieves, but does not remove, the last element of this deque.
Object lastItem = deque.getLast();
//Using Iterator
Iterator iterator = deque.iterator();
while(iterator.hasNext(){
String Item = (String) iterator.next();
}
https://riptutorial.com/ 291
Chapter 45: Disassembling and Decompiling
Syntax
• javap [options] <classes>
Parameters
Name Description
-sysinfo Show system info (path, size, date, MD5 hash) of class being processed
-classpath
<path> Specify where to find user class files
-bootclasspath
<path> Override location of bootstrap class files
Examples
https://riptutorial.com/ 292
Viewing bytecode with javap
If you want to see the generated bytecode for a Java program, you can use the provided javap
command to view it.
package com.stackoverflow.documentation;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@Service
public class HelloWorldService {
void stuff() {
System.out.println("stuff");
}
}
After compiling the source file, the most simple usage is:
https://riptutorial.com/ 293
This lists all non-private methods in the class, but that is not particularly useful for most purposes.
The following command is a lot more useful:
Classfile /Users/pivotal/IdeaProjects/stackoverflow-spring-
docs/target/classes/com/stackoverflow/documentation/HelloWorldService.class
Last modified Jul 22, 2016; size 2167 bytes
MD5 checksum 6e33b5c292ead21701906353b7f06330
Compiled from "HelloWorldService.java"
public class com.stackoverflow.documentation.HelloWorldService
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #5.#60 // java/lang/Object."<init>":()V
#2 = Fieldref #61.#62 // java/lang/System.out:Ljava/io/PrintStream;
#3 = String #63 // Hello, World!
#4 = Methodref #64.#65 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = Class #66 // java/lang/Object
#6 = Methodref #5.#67 // java/lang/Object.getClass:()Ljava/lang/Class;
#7 = Methodref #68.#69 //
java/lang/Class.getResourceAsStream:(Ljava/lang/String;)Ljava/io/InputStream;
#8 = Methodref #70.#71 // java/io/InputStream.read:([B)I
#9 = Class #72 // java/lang/String
#10 = Methodref #9.#73 // java/lang/String."<init>":([BII)V
#11 = Methodref #70.#74 // java/io/InputStream.close:()V
#12 = Class #75 // java/lang/Throwable
#13 = Methodref #12.#76 //
java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
#14 = Class #77 // java/io/IOException
#15 = Class #78 // java/lang/RuntimeException
#16 = Methodref #79.#80 // java/lang/Exception.printStackTrace:()V
#17 = String #55 // stuff
#18 = Class #81 // com/stackoverflow/documentation/HelloWorldService
#19 = Utf8 <init>
#20 = Utf8 ()V
#21 = Utf8 Code
#22 = Utf8 LineNumberTable
#23 = Utf8 LocalVariableTable
#24 = Utf8 this
#25 = Utf8 Lcom/stackoverflow/documentation/HelloWorldService;
#26 = Utf8 sayHello
#27 = Utf8 pvtMethod
#28 = Utf8 (Ljava/util/List;)[Ljava/lang/Object;
#29 = Utf8 strings
#30 = Utf8 Ljava/util/List;
#31 = Utf8 LocalVariableTypeTable
#32 = Utf8 Ljava/util/List<Ljava/lang/String;>;
#33 = Utf8 Signature
#34 = Utf8 (Ljava/util/List<Ljava/lang/String;>;)[Ljava/lang/Object;
#35 = Utf8 tryCatchResources
#36 = Utf8 (Ljava/lang/String;)Ljava/lang/String;
#37 = Utf8 bytes
#38 = Utf8 [B
#39 = Utf8 read
#40 = Utf8 I
https://riptutorial.com/ 294
#41 = Utf8 inputStream
#42 = Utf8 Ljava/io/InputStream;
#43 = Utf8 e
#44 = Utf8 Ljava/lang/Exception;
#45 = Utf8 filename
#46 = Utf8 Ljava/lang/String;
#47 = Utf8 StackMapTable
#48 = Class #81 // com/stackoverflow/documentation/HelloWorldService
#49 = Class #72 // java/lang/String
#50 = Class #82 // java/io/InputStream
#51 = Class #75 // java/lang/Throwable
#52 = Class #38 // "[B"
#53 = Class #83 // java/lang/Exception
#54 = Utf8 Exceptions
#55 = Utf8 stuff
#56 = Utf8 SourceFile
#57 = Utf8 HelloWorldService.java
#58 = Utf8 RuntimeVisibleAnnotations
#59 = Utf8 Lorg/springframework/stereotype/Service;
#60 = NameAndType #19:#20 // "<init>":()V
#61 = Class #84 // java/lang/System
#62 = NameAndType #85:#86 // out:Ljava/io/PrintStream;
#63 = Utf8 Hello, World!
#64 = Class #87 // java/io/PrintStream
#65 = NameAndType #88:#89 // println:(Ljava/lang/String;)V
#66 = Utf8 java/lang/Object
#67 = NameAndType #90:#91 // getClass:()Ljava/lang/Class;
#68 = Class #92 // java/lang/Class
#69 = NameAndType #93:#94 //
getResourceAsStream:(Ljava/lang/String;)Ljava/io/InputStream;
#70 = Class #82 // java/io/InputStream
#71 = NameAndType #39:#95 // read:([B)I
#72 = Utf8 java/lang/String
#73 = NameAndType #19:#96 // "<init>":([BII)V
#74 = NameAndType #97:#20 // close:()V
#75 = Utf8 java/lang/Throwable
#76 = NameAndType #98:#99 // addSuppressed:(Ljava/lang/Throwable;)V
#77 = Utf8 java/io/IOException
#78 = Utf8 java/lang/RuntimeException
#79 = Class #83 // java/lang/Exception
#80 = NameAndType #100:#20 // printStackTrace:()V
#81 = Utf8 com/stackoverflow/documentation/HelloWorldService
#82 = Utf8 java/io/InputStream
#83 = Utf8 java/lang/Exception
#84 = Utf8 java/lang/System
#85 = Utf8 out
#86 = Utf8 Ljava/io/PrintStream;
#87 = Utf8 java/io/PrintStream
#88 = Utf8 println
#89 = Utf8 (Ljava/lang/String;)V
#90 = Utf8 getClass
#91 = Utf8 ()Ljava/lang/Class;
#92 = Utf8 java/lang/Class
#93 = Utf8 getResourceAsStream
#94 = Utf8 (Ljava/lang/String;)Ljava/io/InputStream;
#95 = Utf8 ([B)I
#96 = Utf8 ([BII)V
#97 = Utf8 close
#98 = Utf8 addSuppressed
#99 = Utf8 (Ljava/lang/Throwable;)V
#100 = Utf8 printStackTrace
https://riptutorial.com/ 295
{
public com.stackoverflow.documentation.HelloWorldService();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 10: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/stackoverflow/documentation/HelloWorldService;
https://riptutorial.com/ 296
stack=5, locals=10, args_size=2
0: aload_0
1: invokevirtual #6 // Method
java/lang/Object.getClass:()Ljava/lang/Class;
4: aload_1
5: invokevirtual #7 // Method
java/lang/Class.getResourceAsStream:(Ljava/lang/String;)Ljava/io/InputStream;
8: astore_2
9: aconst_null
10: astore_3
11: sipush 8192
14: newarray byte
16: astore 4
18: aload_2
19: aload 4
21: invokevirtual #8 // Method java/io/InputStream.read:([B)I
24: istore 5
26: new #9 // class java/lang/String
29: dup
30: aload 4
32: iconst_0
33: iload 5
35: invokespecial #10 // Method java/lang/String."<init>":([BII)V
38: astore 6
40: aload_2
41: ifnull 70
44: aload_3
45: ifnull 66
48: aload_2
49: invokevirtual #11 // Method java/io/InputStream.close:()V
52: goto 70
55: astore 7
57: aload_3
58: aload 7
60: invokevirtual #13 // Method
java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
63: goto 70
66: aload_2
67: invokevirtual #11 // Method java/io/InputStream.close:()V
70: aload 6
72: areturn
73: astore 4
75: aload 4
77: astore_3
78: aload 4
80: athrow
81: astore 8
83: aload_2
84: ifnull 113
87: aload_3
88: ifnull 109
91: aload_2
92: invokevirtual #11 // Method java/io/InputStream.close:()V
95: goto 113
98: astore 9
100: aload_3
101: aload 9
103: invokevirtual #13 // Method
java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
106: goto 113
109: aload_2
https://riptutorial.com/ 297
110: invokevirtual #11 // Method java/io/InputStream.close:()V
113: aload 8
115: athrow
116: astore_2
117: aload_2
118: invokevirtual #16 // Method
java/lang/Exception.printStackTrace:()V
121: aload_2
122: athrow
Exception table:
from to target type
48 52 55 Class java/lang/Throwable
11 40 73 Class java/lang/Throwable
11 40 81 any
91 95 98 Class java/lang/Throwable
73 83 81 any
0 70 116 Class java/io/IOException
0 70 116 Class java/lang/RuntimeException
73 116 116 Class java/io/IOException
73 116 116 Class java/lang/RuntimeException
LineNumberTable:
line 21: 0
line 22: 11
line 23: 18
line 24: 26
line 25: 40
line 21: 73
line 25: 81
line 26: 117
line 27: 121
LocalVariableTable:
Start Length Slot Name Signature
18 55 4 bytes [B
26 47 5 read I
9 107 2 inputStream Ljava/io/InputStream;
117 6 2 e Ljava/lang/Exception;
0 123 0 this Lcom/stackoverflow/documentation/HelloWorldService;
0 123 1 filename Ljava/lang/String;
StackMapTable: number_of_entries = 9
frame_type = 255 /* full_frame */
offset_delta = 55
locals = [ class com/stackoverflow/documentation/HelloWorldService, class
java/lang/String, class java/io/InputStream, class java/lang/Throwable, class "[B", int, class
java/lang/String ]
stack = [ class java/lang/Throwable ]
frame_type = 10 /* same */
frame_type = 3 /* same */
frame_type = 255 /* full_frame */
offset_delta = 2
locals = [ class com/stackoverflow/documentation/HelloWorldService, class
java/lang/String, class java/io/InputStream, class java/lang/Throwable ]
stack = [ class java/lang/Throwable ]
frame_type = 71 /* same_locals_1_stack_item */
stack = [ class java/lang/Throwable ]
frame_type = 255 /* full_frame */
offset_delta = 16
locals = [ class com/stackoverflow/documentation/HelloWorldService, class
java/lang/String, class java/io/InputStream, class java/lang/Throwable, top, top, top, top,
class java/lang/Throwable ]
stack = [ class java/lang/Throwable ]
frame_type = 10 /* same */
https://riptutorial.com/ 298
frame_type = 3 /* same */
frame_type = 255 /* full_frame */
offset_delta = 2
locals = [ class com/stackoverflow/documentation/HelloWorldService, class
java/lang/String ]
stack = [ class java/lang/Exception ]
Exceptions:
throws java.io.IOException
void stuff();
descriptor: ()V
flags:
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field
java/lang/System.out:Ljava/io/PrintStream;
3: ldc #17 // String stuff
5: invokevirtual #4 // Method
java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 32: 0
line 33: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Lcom/stackoverflow/documentation/HelloWorldService;
}
SourceFile: "HelloWorldService.java"
RuntimeVisibleAnnotations:
0: #59()
https://riptutorial.com/ 299
Chapter 46: Documenting Java Code
Introduction
Documentation for java code is often generated using javadoc. Javadoc was created by Sun
Microsystems for the purpose of generating API documentation in HTML format from java source
code. Using the HTML format gives the convenience of being able to hyperlink related documents
together.
Syntax
• /** -- start of JavaDoc on a class, field, method, or package
• @author // To name the author of the class, interface or enum. It is required.
• @version // The version of that class, interface or enum. It is required. You could use macros
like %I% or %G% for you source control software to fill in on checkout.
• @param // To show the arguments (parameters) of a method or a constructor. Specify one
@param tag for each parameter.
• @return // To show the return types for non-void methods.
• @exception // Shows what exceptions could be thrown from the method or constructor.
Exceptions that MUST be caught should be listed here. If you want, you can also include
those that do not need to be caught, like ArrayIndexOutOfBoundsException. Specify one
@exception for each exception that can be thrown.
• @throws // Same as @exception.
• @see // Links to a method, field, class or package. Use in the form of
package.Class#something.
• @since // When this method, field or class was added. For example, JDK-8 for a class like
java.util.Optional<T>.
• @serial, @serialField, @serialData // Used to show the serialVersionUID.
• @deprecated // To mark a class, method or field as deprecated. For example, one would be
java.io.StringBufferInputStream. See a full list of existing deprecated classes here.
• {@link} // Similar to @see, but can be used with custom text: {@link
#setDefaultCloseOperation(int closeOperation) see JFrame#setDefaultCloseOperation for
more info}.
• {@linkplain} // Similar to {@link}, but without the code font.
• {@code} // For literal code, such as HTML tags. For example: {@code <html></html>}.
However, this will use a monospaced font. To get the same result without the monospace
font, use {@literal}.
• {@literal} // Same as {@code}, but without the monospaced font.
• {@value} // Shows the value of a static field: The value of JFrame#EXIT_ON_CLOSE is
{@value}. Or, you could link to a certain field: Uses the app name {@value
AppConstants#APP_NAME}.
• {@docRoot} // The root folder of the JavaDoc HTML relative to the current file. Example: <a
href="{@docRoot}/credits.html">Credits</a>.
• HTML is allowed: <code>"Hi cookies".substring(3)</code>.
https://riptutorial.com/ 300
• */ -- end of JavaDoc declaration
Remarks
Javadoc is a tool included with the JDK that allows in-code comments to be converted to an HTML
documentation. The Java API Specification was generated using Javadoc. The same is true for
much of the documentation of 3rd-party libraries.
Examples
Class Documentation
All Javadoc comments begin with a block comment followed by an asterisk (/**) and end when the
block comment does (*/). Optionally, each line can begin with arbitrary whitespace and a single
asterisk; these are ignored when the documentation files are generated.
/**
* Brief summary of this class, ending with a period.
*
* It is common to leave a blank line between the summary and further details.
* The summary (everything before the first period) is used in the class or package
* overview section.
*
* The following inline tags can be used (not an exhaustive list):
* {@link some.other.class.Documentation} for linking to other docs or symbols
* {@link some.other.class.Documentation Some Display Name} the link's appearance can be
* customized by adding a display name after the doc or symbol locator
* {@code code goes here} for formatting as code
* {@literal <>[]()foo} for interpreting literal text without converting to HTML markup
* or other tags.
*
* Optionally, the following tags may be used at the end of class documentation
* (not an exhaustive list):
*
* @author John Doe
* @version 1.0
* @since 5/10/15
* @see some.other.class.Documentation
* @deprecated This class has been replaced by some.other.package.BetterFileReader
*
* You can also have custom tags for displaying additional information.
* Using the @custom.<NAME> tag and the -tag custom.<NAME>:htmltag:"context"
* command line option, you can create a custom tag.
*
* Example custom tag and generation:
* @custom.updated 2.0
* Javadoc flag: -tag custom.updated:a:"Updated in version:"
* The above flag will display the value of @custom.updated under "Updated in version:"
*
*/
public class FileReader {
}
The same tags and format used for Classes can be used for Enums and Interfaces as well.
https://riptutorial.com/ 301
Method Documentation
All Javadoc comments begin with a block comment followed by an asterisk (/**) and end when the
block comment does (*/). Optionally, each line can begin with arbitrary whitespace and a single
asterisk; these are ignored when the documentation files are generated.
/**
* Brief summary of method, ending with a period.
*
* Further description of method and what it does, including as much detail as is
* appropriate. Inline tags such as
* {@code code here}, {@link some.other.Docs}, and {@literal text here} can be used.
*
* If a method overrides a superclass method, {@inheritDoc} can be used to copy the
* documentation
* from the superclass method
*
* @param stream Describe this parameter. Include as much detail as is appropriate
* Parameter docs are commonly aligned as here, but this is optional.
* As with other docs, the documentation before the first period is
* used as a summary.
*
* @return Describe the return values. Include as much detail as is appropriate
* Return type docs are commonly aligned as here, but this is optional.
* As with other docs, the documentation before the first period is used as a
* summary.
*
* @throws IOException Describe when and why this exception can be thrown.
* Exception docs are commonly aligned as here, but this is
* optional.
* As with other docs, the documentation before the first period
* is used as a summary.
* Instead of @throws, @exception can also be used.
*
* @since 2.1.0
* @see some.other.class.Documentation
* @deprecated Describe why this method is outdated. A replacement can also be specified.
*/
public String[] read(InputStream stream) throws IOException {
return null;
}
Field Documentation
All Javadoc comments begin with a block comment followed by an asterisk (/**) and end when the
block comment does (*/). Optionally, each line can begin with arbitrary whitespace and a single
asterisk; these are ignored when the documentation files are generated.
/**
* Fields can be documented as well.
*
* As with other javadocs, the documentation before the first period is used as a
* summary, and is usually separated from the rest of the documentation by a blank
* line.
*
* Documentation for fields can use inline tags, such as:
https://riptutorial.com/ 302
* {@code code here}
* {@literal text here}
* {@link other.docs.Here}
*
* Field documentation can also make use of the following tags:
*
* @since 2.1.0
* @see some.other.class.Documentation
* @deprecated Describe why this field is outdated
*/
public static final String CONSTANT_STRING = "foo";
Package Documentation
Java SE 5
/**
* Package documentation goes here; any documentation before the first period will
* be used as a summary.
*
* It is common practice to leave a blank line between the summary and the rest
* of the documentation; use this space to describe the package in as much detail
* as is appropriate.
*
* Inline tags such as {@code code here}, {@link reference.to.other.Documentation},
* and {@literal text here} can be used in this documentation.
*/
package com.example.foo;
In the above case, you must put this file package-info.java inside the folder of the Java package
com.example.foo.
Links
/**
* You can link to the javadoc of an already imported class using {@link ClassName}.
*
* You can also use the fully-qualified name, if the class is not already imported:
* {@link some.other.ClassName}
*
* You can link to members (fields or methods) of a class like so:
* {@link ClassName#someMethod()}
* {@link ClassName#someMethodWithParameters(int, String)}
* {@link ClassName#someField}
* {@link #someMethodInThisClass()} - used to link to members in the current class
*
* You can add a label to a linked javadoc like so:
https://riptutorial.com/ 303
* {@link ClassName#someMethod() link text}
*/
With the @see tag you can add elements to the See also section. Like @param or @return the place
where they appear is not relevant. The spec says you should write it after @return.
/**
* This method has a nice explanation but you might found further
* information at the bottom.
*
* @see ClassName#someMethod()
*/
If you want to add links to external resources you can just use the HTML <a> tag. You can use it
inline anywhere or inside both @link and @see tags.
/**
* Wondering how this works? You might want
* to check this <a href="http://stackoverflow.com/">great service</a>.
*
* @see <a href="http://stackoverflow.com/">Stack Overflow</a>
*/
Many IDEs provide support for generating HTML from Javadocs automatically; some build tools (
Maven and Gradle, for example) also have plugins that can handle the HTML creation.
However, these tools are not required to generate the Javadoc HTML; this can be done using the
command line javadoc tool.
https://riptutorial.com/ 304
The most basic usage of the tool is:
javadoc JavaFile.java
A more practical use of the command line tool, which will recursively read all java files in [source-
directory], create documentation for [package.name] and all sub-packages, and place the
generated HTML in the [docs-directory] is:
Single Line comments are started by // and may be positioned after a statement on the same line,
but not before.
Multi-Line comments are defined between /* and */. They can span multiple lines and may even
been positioned between statements.
/*
multi
line
comment
*/
object/*inner-line-comment*/.method();
}
As too many inline comments may decrease readability of code, they should be used sparsely in
case the code isn't self-explanatory enough or the design decision isn't obvious.
An additional use case for single-line comments is the use of TAGs, which are short, convention
driven keywords. Some development environments recognize certain conventions for such single-
comments. Common examples are
• //TODO
• //FIXME
https://riptutorial.com/ 305
Or issue references, i.e. for Jira
• //PRJ-1234
The canonical way of writing code inside documentation is with the {@code } construct. If you have
multiline code wrap inside <pre></pre>.
/**
* The Class TestUtils.
* <p>
* This is an {@code inline("code example")}.
* <p>
* You should wrap it in pre tags when writing multiline code.
* <pre>{@code
* Example example1 = new FirstLineExample();
* example1.butYouCanHaveMoreThanOneLine();
* }</pre>
* <p>
* Thanks for reading.
*/
class TestUtils {
Sometimes you may need to put some complex code inside the javadoc comment. The @ sign is
specially problematic. The use of the old <code> tag alongside the {@literal } construct solves the
problem.
/**
* Usage:
* <pre><code>
* class SomethingTest {
* {@literal @}Rule
* public SingleTestRule singleTestRule = new SingleTestRule("test1");
*
* {@literal @}Test
* public void test1() {
* // only this test will be executed
* }
*
* ...
* }
* </code></pre>
*/
class SingleTestRule implements TestRule { }
https://riptutorial.com/ 306
Chapter 47: Dynamic Method Dispatch
Introduction
What is Dynamic Method Dispatch?
Dynamic Method Dispatch is a process in which the call to an overridden method is resolved at
runtime rather than at compile-time. When an overridden method is called by a reference, Java
determines which version of that method to execute based on the type of object it refer to. This is
also know as runtime polymorphism.
Remarks
• Dynamic Binding = Late binding
• Abstract classes cannot be instantiated, but they can be sub-classed (Base for a child class)
• An abstract method is a method that is declared without an implementation
• Abstract class may contain a mix of methods declared with or without an implementation
• When an abstract class is sub-classed, the subclass usually provides implementations for all
of the abstract methods in its parent class. However, if it does not, then the subclass must
also be declared abstract
• Dynamic method dispatch is a mechanism by which a call to an overridden method is
resolved at runtime. This is how java implements runtime polymorphism.
• Upcasting : Casting a subtype to a supertype, upward to the inheritance tree.
• Runtime Polymorphism = Dynamic Polymorphism
Examples
Dynamic Method Dispatch - Example Code
Abstract Class :
package base;
/*
Abstract classes cannot be instantiated, but they can be subclassed
*/
public abstract class ClsVirusScanner {
https://riptutorial.com/ 307
System.out.println("Perform BootTime Scan");
}
protected void fnInternetSecutiry(){
System.out.println("Scan for Internet Security");
}
import base.ClsVirusScanner;
//Child Class 3
class ClsFreeVersion extends ClsVirusScanner{
@Override
public void fnStartScan() {
super.fnVirusMalwareScan();
}
}; //ClsTrialVersion IS-A ClsVirusScanner
//Calling Class
public class ClsRunTheApplication {
https://riptutorial.com/ 308
ClsVirusScanner objVS=null;
}
}
Result :
Upcasting :
https://riptutorial.com/ 309
Chapter 48: Encapsulation
Introduction
Imagine you had a class with some pretty important variables and they were set (by other
programmers from their code) to unacceptable values.Their code brought errors in your code. As a
solution, In OOP, you allow the state of an object (stored in its variables) to be modified only
through methods. Hiding the state of an object and providing all interaction through an objects
methods is known as Data Encapsulation.
Remarks
It is much easier to start with marking a variable private and expose it if necessary than to hide an
already public variable.
There is one exception where encapsulation may not be beneficial: "dumb" data structures
(classes whose sole purpose is to hold variables).
In this case, the interface of the class is the data that it holds.
Note that variables marked final can be marked public without violating encapsulation because
they can't be changed after being set.
Examples
Encapsulation to maintain invariants
There are two parts of a class: the interface and the implementation.
The interface is the exposed functionality of the class. Its public methods and variables are part of
the interface.
The implementation is the internal workings of a class. Other classes shouldn't need to know
about the implementation of a class.
Encapsulation refers to the practice of hiding the implementation of a class from any users of that
class. This allows the class to make assumptions about its internal state.
https://riptutorial.com/ 310
public class Angle {
This class relies on a basic assumption (or invariant): angleInDegrees and angleInRadians are
always in sync. If the class members were public, there would be no guarantees that the two
representations of angles are correlated.
Encapsulation allows you to make internal changes to a class without affecting any code that calls
the class. This reduces coupling, or how much any given class relies on the implementation of
another class.
For example, let's change the implementation of the Angle class from the previous example:
https://riptutorial.com/ 311
a.angleInDegrees = degrees;
return a;
}
private Angle(){}
}
The implementation of this class has changed so that it only stores one representation of the angle
and calculates the other angle when needed.
However, the implementation changed, but the interface didn't. If a calling class relied on
accessing the angleInRadians method, it would need to be changed to use the new version of
Angle. Calling classes shouldn't care about the internal representation of a class.
https://riptutorial.com/ 312
Chapter 49: Enum Map
Introduction
Java EnumMap class is the specialized Map implementation for enum keys. It inherits Enum and
AbstractMap classes.
K: It is the type of keys maintained by this map. V: It is the type of mapped values.
Examples
Enum Map Book Example
import java.util.*;
class Book {
int id;
String name,author,publisher;
int quantity;
public Book(int id, String name, String author, String publisher, int quantity) {
this.id = id;
this.name = name;
this.author = author;
this.publisher = publisher;
this.quantity = quantity;
}
}
public class EnumMapExample {
// Creating enum
public enum Key{
One, Two, Three
};
public static void main(String[] args) {
EnumMap<Key, Book> map = new EnumMap<Key, Book>(Key.class);
// Creating Books
Book b1=new Book(101,"Let us C","Yashwant Kanetkar","BPB",8);
Book b2=new Book(102,"Data Communications & Networking","Forouzan","Mc Graw Hill",4);
Book b3=new Book(103,"Operating System","Galvin","Wiley",6);
// Adding Books to Map
map.put(Key.One, b1);
map.put(Key.Two, b2);
map.put(Key.Three, b3);
// Traversing EnumMap
for(Map.Entry<Key, Book> entry:map.entrySet()){
Book b=entry.getValue();
System.out.println(b.id+" "+b.name+" "+b.author+" "+b.publisher+" "+b.quantity);
}
}
}
https://riptutorial.com/ 313
Chapter 50: Enum starting with number
Introduction
Java does not allow the name of enum to start with number like 100A, 25K. In that case, we can
append the code with _ (underscore) or any allowed pattern and make check of it.
Examples
Enum with name at begining
https://riptutorial.com/ 314
Chapter 51: Enums
Introduction
Java enums (declared using the enum keyword) are shorthand syntax for sizable quantities of
constants of a single class.
Syntax
• [public/protected/private] enum Enum_name { // Declare a new enum.
• ENUM_CONSTANT_1[, ENUM_CONSTANT_2...]; // Declare the enum constants. This must
be the first line inside of the enum, and should be separated by commas, with a semicolon at
the end.
• ENUM_CONSTANT_1(param)[, ENUM_CONSTANT_2(param)...]; // Declare enum
constants with parameters. The parameter types must match the constructor.
• ENUM_CONSTANT_1 {...}[, ENUM_CONSTANT_2 {...}...]; // Declare enum constants with
overridden methods. This must be done if the enum contains abstract methods; all such
methods must be implemented.
• ENUM_CONSTANT.name() // Returns a String with the name of the enum constant.
• ENUM_CONSTANT.ordinal() // Returns the ordinal of this enumeration constant, its position
in its enum declaration, where the initial constant is assigned an ordinal of zero.
• Enum_name.values() // Returns a new array (of type Enum_name[]) containing every
constant of that enum everytime it is called.
• Enum_name.valueOf("ENUM_CONSTANT") // The inverse of ENUM_CONSTANT.name() --
returns the enum constant with the given name.
• Enum.valueOf(Enum_name.class, "ENUM_CONSTANT") // A synonym of the previous one:
The inverse of ENUM_CONSTANT.name() -- returns the enum constant with the given
name.
Remarks
Restrictions
Enums always extend java.lang.Enum, so it is impossible for an enum to extend a class. However,
they can implement many interfaces.
https://riptutorial.com/ 315
Examples
Declaring and using a basic enum
Enum can be considered to be syntax sugar for a sealed class that is instantiated only a number
of times known at compile-time to define a set of constants.
While the enum constants don't necessarily need to be in all-caps, it is Java convention that
names of constants are entirely uppercase, with words separated by underscores.
/**
* This enum is declared in the Season.java file.
*/
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
/**
* This enum is declared inside the Day.java file and
* cannot be accessed outside because it's declared as private.
*/
private enum Season {
WINTER,
SPRING,
SUMMER,
https://riptutorial.com/ 316
FALL
}
/**
* Constructor
*/
public Day() {
// Illegal. Compilation error
enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
}
Every constant of enum is public, static and final by default. As every constant is static, they
can be accessed directly using the enum name.
https://riptutorial.com/ 317
System.out.println(s.name()); // name() is a built-in method that gets the exact name of
the enum constant
}
You can get an array of the enum constants using the values() method. The values are
guaranteed to be in declaration order in the returned array:
Note: this method allocates a new array of values each time it is called.
Another way to compare enum constants is by using equals() as below, which is considered bad
practice as you can easily fall into pitfalls as follows:
Season.FALL.equals(Season.FALL); // true
Season.FALL.equals(Season.WINTER); // false
Season.FALL.equals("FALL"); // false and no compiler error
https://riptutorial.com/ 318
Furthermore, although the set of instances in the enum cannot be changed at run-time, the
instances themselves are not inherently immutable because like any other class, an enum can
contain mutable fields as is demonstrated below.
// Usage:
MutableExample.A.print(); // Outputs 0
MutableExample.A.increment();
MutableExample.A.print(); // Outputs 1 -- we've changed a field
MutableExample.B.print(); // Outputs 0 -- another instance remains unchanged
However, a good practice is to make enum instances immutable, i.e. when they either don't have
any additional fields or all such fields are marked as final and are immutable themselves. This will
ensure that for a lifetime of the application an enum won't leak any memory and that it is safe to use
its instances across all threads.
Enums implicitly implement Serializable and Comparable because the Enum class does:
An enum cannot have a public constructor; however, private constructors are acceptable
(constructors for enums are package-private by default):
Coin(int value) {
this.value = value;
}
https://riptutorial.com/ 319
int p = Coin.NICKEL.getValue(); // the int value will be 5
It is recommended that you keep all fields private and provide getter methods, as there are a finite
number of instances for an enum.
If you were to implement an Enum as a class instead, it would look like this:
Enum constants are technically mutable, so a setter could be added to change the internal
structure of an enum constant. However, this is considered very bad practice and should be
avoided.
Coin(int value){
this.value = value;
}
...
You may define multiple constructors in the same enum. When you do, the arguments you pass in
your enum declaration decide which constructor is called:
https://riptutorial.com/ 320
private final int value;
private final boolean isCopperColored;
Coin(int value){
this(value, false);
}
...
Note: All non-primitive enum fields should implement Serializable because the Enum class does.
An enum can contain a method, just like any class. To see how this works, we'll declare an enum
like this:
Let's have a method that returns the enum in the opposite direction:
This can be improved further through the use of fields and static initializer blocks:
https://riptutorial.com/ 321
public Direction getOpposite(){
return opposite;
}
static {
NORTH.opposite = SOUTH;
SOUTH.opposite = NORTH;
WEST.opposite = EAST;
EAST.opposite = WEST;
}
}
In this example, the opposite direction is stored in a private instance field opposite, which is
statically initialized the first time a Direction is used. In this particular case (because NORTH
references SOUTH and conversely), we cannot use Enums with constructors here (Constructors
NORTH(SOUTH), SOUTH(NORTH), EAST(WEST), WEST(EAST) would be more elegant and would allow
opposite to be declared final, but would be self-referential and therefore are not allowed).
Implements Interface
This is an enum that is also a callable function that tests String inputs against precompiled regular
expression patterns.
import java.util.function.Predicate;
import java.util.regex.Pattern;
@Override
public boolean test(final String input) {
return this.pattern.matcher(input).matches();
}
}
import java.util.function.Predicate;
https://riptutorial.com/ 322
public boolean test(String s) { return s == null; }
},
EMPTY {
@Override
public boolean test(String s) { return s.equals(""); }
},
NULL_OR_EMPTY {
@Override
public boolean test(String s) { return NULL.test(s) || EMPTY.test(s); }
};
}
When a method need to accept an "extensible" set of enum values, the programmer can apply
polymorphism like on a normal class by creating an interface which will be used anywere where
the enums shall be used:
This way, any enum tagged by (implementing) the interface can be used as a parameter, allowing
the programmer to create a variable amount of enums that will be accepted by the method. This can
be useful, for example, in APIs where there is a default (unmodifiable) enum and the user of these
APIs want to "extend" the enum with more values.
Sample which shows how to use the enums - note how printEnum() accepts values from both enum
types:
https://riptutorial.com/ 323
printEnum(DefaultValues.VALUE_ONE); // VALUE_ONE
printEnum(DefaultValues.VALUE_TWO); // VALUE_TWO
printEnum(ExtendedValues.VALUE_THREE); // VALUE_THREE
printEnum(ExtendedValues.VALUE_FOUR); // VALUE_FOUR
Note: This pattern does not prevent you from redefining enum values, which are already defined in
one enum, in another enum. These enum values would be different instances then. Also, it is not
possible to use switch-on-enum since all we have is the interface, not the real enum.
Enums can define abstract methods, which each enum member is required to implement.
enum Action {
DODGE {
public boolean execute(Player player) {
return player.isAttacking();
}
},
ATTACK {
public boolean execute(Player player) {
return player.hasWeapon();
}
},
JUMP {
public boolean execute(Player player) {
return player.getCoordinates().equals(new Coordinates(0, 0));
}
};
This allows for each enum member to define its own behaviour for a given operation, without
having to switch on types in a method in the top-level definition.
Note that this pattern is a short form of what is typically achieved using polymorphism and/or
implementing interfaces.
Documenting enums
Not always the enum name is clear enough to be understood. To document an enum, use standard
javadoc:
/**
* United States coins
*/
public enum Coins {
/**
* One-cent coin, commonly known as a penny,
* is a unit of currency equaling one-hundredth
* of a United States dollar
https://riptutorial.com/ 324
*/
PENNY(1),
/**
* A nickel is a five-cent coin equaling
* five-hundredth of a United States dollar
*/
NICKEL(5),
/**
* The dime is a ten-cent coin refers to
* one tenth of a United States dollar
*/
DIME(10),
/**
* The quarter is a US coin worth 25 cents,
* one-fourth of a United States dollar
*/
QUARTER(25);
Coins(int value){
this.value = value;
}
Each enum class contains an implicit static method named values(). This method returns an array
containing all values of that enum. You can use this method to iterate over the values. It is
important to note however that this method returns a new array every time it is called.
/**
* Print out all the values in this enum.
*/
public static void printAllDays() {
for(Day day : Day.values()) {
System.out.println(day.name());
}
}
}
When writing a class with generics in java, it is possible to ensure that the type parameter is an
https://riptutorial.com/ 325
enum. Since all enums extend the Enum class, the following syntax may be used.
enum DayOfWeek {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}
An enum is compiled with a built-in static valueOf() method which can be used to lookup a
constant by its name:
Both of these valueOf() methods will throw an IllegalArgumentException if the specified enum does
not have a constant with a matching name.
The Guava library provides a helper method Enums.getIfPresent() that returns a Guava Optional to
eliminate explicit exception handling:
Enum constants are instantiated when an enum is referenced for the first time. Therefore, that
allows to implement Singleton software design pattern with a single-element enum.
https://riptutorial.com/ 326
public enum Attendant {
INSTANCE;
private Attendant() {
// perform some initialization routine
}
According to "Effective Java" book by Joshua Bloch, a single-element enum is the best way to
implement a singleton. This approach has following advantages:
• thread safety
• guarantee of single instantiation
• out-of-the-box serialization
And as shown in the section implements interface this singleton might also implement one or more
interfaces.
In case we want to use enum with more information and not just as constant values, and we want to
be able to compare two enums.
Coin(int value){
this.value = value;
}
Here we defined an Enum called Coin which represent its value. With the method isGreaterThan we
can compare two enums:
https://riptutorial.com/ 327
Coin penny = Coin.PENNY;
Coin dime = Coin.DIME;
Sometimes you want to convert your enum to a String, there are two ways to do that.
Assume we have:
name() is an internal method in enum that returns the String representation of the enum, the return
String represents exactly how the enum value was defined.
For example:
System.out.println(Fruit.BANANA.name()); // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.name()); // "GRAPE_FRUIT"
However, toString() is likely overridden by developers to make it print a more user friendly String
Don't use toString() if you want to do checking in your code, name() is much more
stable for that. Only use toString() when you are going to output the value to logs or
stdout or something
By default:
System.out.println(Fruit.BANANA.toString()); // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "GRAPE_FRUIT"
https://riptutorial.com/ 328
Example of being overridden
System.out.println(Fruit.BANANA.toString()); // "Banana"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "Grape Fruit"
In an enum it is possible to define a specific behavior for a particular constant of the enum which
overrides the default behavior of the enum, this technique is known as constant specific body.
Suppose three piano students - John, Ben and Luke - are defined in an enum named PianoClass, as
follows:
enum PianoClass {
JOHN, BEN, LUKE;
public String getSex() {
return "Male";
}
public String getLevel() {
return "Beginner";
}
}
And one day two other students arrive - Rita and Tom - with a sex (Female) and level
(Intermediate) that do not match the previous ones:
enum PianoClass2 {
JOHN, BEN, LUKE, RITA, TOM;
public String getSex() {
return "Male"; // issue, Rita is a female
}
public String getLevel() {
return "Beginner"; // issue, Tom is an intermediate student
}
}
so that simply adding the new students to the constant declaration, as follows, is not correct:
It's possible to define a specific behavior for each of the constant, Rita and Tom, which overrides
the PianoClass2 default behavior as follows:
enum PianoClass3 {
JOHN, BEN, LUKE,
RITA {
@Override
public String getSex() {
return "Female";
https://riptutorial.com/ 329
}
},
TOM {
@Override
public String getLevel() {
return "Intermediate";
}
};
public String getSex() {
return "Male";
}
public String getLevel() {
return "Beginner";
}
}
and now Tom's level and Rita's sex are as they should be:
Another way to define content specific body is by using constructor, for instance:
enum Friend {
MAT("Male"),
JOHN("Male"),
JANE("Female");
Friend(String gender) {
this.gender = gender;
}
and usage:
enum Util {
/* No instances */;
https://riptutorial.com/ 330
public static int clamp(int min, int max, int i) {
return Math.min(Math.max(i, min), max);
}
Just as enum can be used for singletons (1 instance classes), it can be used for utility classes (0
instance classes). Just make sure to terminate the (empty) list of enum constants with a ;.
See the question Zero instance enum vs private constructors for preventing instantiation for a
discussion on pro's and con's compared to private constructors.
If your enum class is required to have static fields, keep in mind they are created after the enum
values themselves. That means, the following code will result in a NullPointerException:
enum Example {
ONE(1), TWO(2);
enum Example {
ONE(1), TWO(2);
enum Example {
ONE(1), TWO(2);
https://riptutorial.com/ 331
putValue(this.name(), value);
}
initialisisation:
Enums contains only constants and can be compared directly with ==. So, only reference check is
needed, no need to use .equals method. Moreover, if .equals used incorrectly, may raise the
NullPointerException while that's not the case with == check.
enum Day {
GOOD, AVERAGE, WORST;
}
if (day.equals(Day.GOOD)) {//NullPointerException!
System.out.println("Good Day!");
}
}
}
To group, complement, range the enum values we have EnumSet class which contains different
methods.
• EnumSet#of : Set of specific enums without any range. Multiple overloaded of methods are
there.
https://riptutorial.com/ 332
• EnumSet#complementOf : Set of enum which is complement of enum values provided in method
parameter
enum Page {
A1, A2, A3, A4, A5, A6, A7, A8, A9, A10
}
if (range.contains(Page.A4)) {
System.out.println("Range contains A4");
}
if (of.contains(Page.A1)) {
System.out.println("Of contains A1");
}
}
}
https://riptutorial.com/ 333
Chapter 52: EnumSet class
Introduction
Java EnumSet class is the specialized Set implementation for use with enum types. It inherits
AbstractSet class and implements the Set interface.
Examples
Enum Set Example
import java.util.*;
enum days {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}
public class EnumSetExample {
public static void main(String[] args) {
Set<days> set = EnumSet.of(days.TUESDAY, days.WEDNESDAY);
// Traversing elements
Iterator<days> iter = set.iterator();
while (iter.hasNext())
System.out.println(iter.next());
}
}
https://riptutorial.com/ 334
Chapter 53: Exceptions and exception
handling
Introduction
Objects of type Throwable and its subtypes can be sent up the stack with the throw keyword and
caught with try…catch statements.
Syntax
• void someMethod() throws SomeException { } //method declaration, forces method callers to
catch if SomeException is a checked exception type
• try {
• catch (SomeException e) {
• finally {
//code that will always run, whether try block finishes or not
Examples
Catching an exception with try-catch
An exception can be caught and handled using the try...catch statement. (In fact try statements
take other forms, as described in other examples about try...catch...finally and try-with-
resources.)
https://riptutorial.com/ 335
try {
doSomething();
} catch (SomeException e) {
handle(e);
}
// next statement
try {
doSomething();
} catch (SomeException e) {
handleOneWay(e)
} catch (SomeOtherException e) {
handleAnotherWay(e);
}
// next statement
If there are multiple catch blocks, they are tried one at a time starting with the first one, until a
match is found for the exception. The corresponding handler is executed (as above), and then
control is passed to the next statement after the try...catch statement. The catch blocks after the
one that matches are always skipped, even if the handler code throws an exception.
The "top down" matching strategy has consequences for cases where the exceptions in the catch
blocks are not disjoint. For example:
try {
throw new RuntimeException("test");
} catch (Exception e) {
System.out.println("Exception");
} catch (RuntimeException e) {
System.out.println("RuntimeException");
}
https://riptutorial.com/ 336
This code snippet will output "Exception" rather than "RuntimeException". Since RuntimeException
is a subtype of Exception, the first (more general) catch will be matched. The second (more
specific) catch will never be executed.
The lesson to learn from this is that the most specific catch blocks (in terms of the exception types)
should appear first, and the most general ones should be last. (Some Java compilers will warn you
if a catch can never be executed, but this is not a compilation error.)
Starting with Java SE 7, a single catch block can handle a list of unrelated exceptions. The
exception type are listed, separated with a vertical bar (|) symbol. For example:
try {
doSomething();
} catch (SomeException | SomeOtherException e) {
handleSomeException(e);
}
The behavior of a multi-exception catch is a simple extension for the single-exception case. The
catch matches if the thrown exception matches (at least) one of the listed exceptions.
There is some additional subtlety in the specification. The type of e is a synthetic union of the
exception types in the list. When the value of e is used, its static type is the least common
supertype of the type union. However, if e is rethrown within the catch block, the exception types
that are thrown are the types in the union. For example:
In the above, IOException and SQLException are checked exceptions whose least common
supertype is Exception. This means that the report method must match report(Exception).
However, the compiler knows that the throw can throw only an IOException or an SQLException.
Thus, method can be declared as throws IOException, SQLException rather than throws Exception.
(Which is a good thing: see Pitfall - Throwing Throwable, Exception, Error or RuntimeException.)
Throwing an exception
https://riptutorial.com/ 337
}
}
The exception is thrown on the 3rd line. This statement can be broken down into two parts:
When the exception is thrown, it causes the enclosing statements to terminate abnormally until the
exception is handled. This is described in other examples.
It is good practice to both create and throw the exception object in a single statement, as shown
above. It is also good practice to include a meaningful error message in the exception to help the
programmer to understand the cause of the problem. However, this is not necessarily the
message that you should be showing to the end user. (For a start, Java has no direct support for
internationalizing exception messages.)
• We have declared the checkNumber as throws IllegalArgumentException. This was not strictly
necessary, since IllegalArgumentException is a checked exception; see The Java Exception
Hierarchy - Unchecked and Checked Exceptions. However, it is good practice to do this, and
also to include the exceptions thrown a method's javadoc comments.
the compiler would report a compilation error for the return statement.
Exception chaining
Many standard exceptions have a constructor with a second cause argument in addition to the
conventional message argument. The cause allows you to chain exceptions. Here is an example.
First we define an unchecked exception that our application is going throw when it encounters a
non-recoverable error. Note that we have included a constructor that accepts a cause argument.
https://riptutorial.com/ 338
public AppErrorException(String message, Throwable cause) {
super(message, cause);
}
}
The throw within the try block detects a problem and reports it via an exception with a simple
message. By contrast, the throw within the catch block is handling the IOException by wrapping it in
a new (checked) exception. However, it is not throwing away the original exception. By passing
the IOException as the cause, we record it so that it can be printed in the stacktrace, as explained in
Creating and reading stacktraces.
Custom Exceptions
Under most circumstances, it is simpler from a code-design standpoint to use existing generic
Exception classes when throwing exceptions. This is especially true if you only need the exception
to carry a simple error message. In that case, RuntimeException is usually preferred, since it is not
a checked Exception. Other exception classes exist for common classes of errors:
Cases where you do want to use a custom exception class include the following:
• You are writing an API or library for use by others, and you want to allow users of your API to
be able to specifically catch and handle exceptions from your API, and be able to
differentiate those exceptions from other, more generic exceptions.
• You are throwing exceptions for a specific kind of error in one part of your program, which
you want to catch and handle in another part of your program, and you want to be able to
differentiate these errors from other, more generic errors.
You can create your own custom exceptions by extending RuntimeException for an unchecked
exception, or checked exception by extending any Exception which is not also subclass of
RuntimeException, because:
https://riptutorial.com/ 339
Subclasses of Exception that are not also subclasses of RuntimeException are
checked exceptions
And the fields can be used where the exception is caught and handled:
More:
Java SE 7
As the try-catch-final statement example illustrates, resource cleanup using a finally clause
requires a significant amount of "boiler-plate" code to implement the edge-cases correctly. Java 7
provides a much simpler way to deal with this problem in the form of the try-with-resources
https://riptutorial.com/ 340
statement.
What is a resource?
Java 7 introduced the java.lang.AutoCloseable interface to allow classes to be managed using the
try-with-resources statement. Instances of classes that implement AutoCloseable are referred to as
resources. These typically need to be disposed of in a timely fashion rather than relying on the
garbage collector to dispose of them.
A close() method should dispose of the resource in an appropriate fashion. The specification
states that it should be safe to call the method on a resource that has already been disposed of. In
addition, classes that implement Autocloseable are strongly encouraged to declare the close()
method to throw a more specific exception than Exception, or no exception at all.
A wide range of standard Java classes and interfaces implement AutoCloseable. These include:
The resources to be manage are declared as variables in the (...) section after the try clause. In
the example above, we declare a resource variable stream and initialize it to a newly created
PrintStream.
Once the resource variables have been initialized, the try block is executed. When that
completes, stream.close() will be called automatically to ensure that the resource does not leak.
Note that the close() call happens no matter how the block completes.
https://riptutorial.com/ 341
The try-with-resources statement can be enhanced with catch and finally blocks, as with the pre-
Java 7 try-catch-finally syntax. The following code snippet adds a catch block to our previous one
to deal with the FileNotFoundException that the PrintStream constructor can throw:
If either the resource initialization or the try block throws the exception, then the catch block will be
executed. The finally block will always be executed, as with a conventional try-catch-finally
statement.
• The resource variable is out of scope in the catch and finally blocks.
• The resource cleanup will happen before the statement tries to match the catch block.
• If the automatic resource cleanup threw an exception, then that could be caught in one of the
catch blocks.
This behaves as you would expect. Both is and os are closed automatically at the end of the try
block. There are a couple of points to note:
• The initializations occur in the code order, and later resource variable initializers can use of
the values of the earlier ones.
• All resource variables that were successfully initialized will be cleaned up.
• Resource variables are cleaned up in reverse order of their declarations.
Thus, in the above example, is is initialized before os and cleaned up after it, and is will be
cleaned up if there is an exception while initializing os.
https://riptutorial.com/ 342
classical try-catch-finally statement. (Please refer to the JLS for the full details.)
(The JLS specifies that the actual t and primaryException variables will be invisible to normal Java
code.)
The enhanced form of try-with-resources is specified as an equivalence with the basic form. For
example:
https://riptutorial.com/ 343
is equivalent to:
try {
try (PrintStream stream = new PrintStream(fileName)) {
stream.println("Hello world!");
}
} catch (NullPointerException ex) {
System.err.println("Null filename");
} finally {
System.err.println("All done");
}
When an exception object is created (i.e. when you new it), the Throwable constructor captures
information about the context in which the exception was created. Later on, this information can be
output in the form of a stacktrace, which can be used to help diagnose the problem that caused
the exception in the first place.
Printing a stacktrace
Printing a stacktrace is simply a matter of calling the printStackTrace() method. For example:
try {
int a = 0;
int b = 0;
int c = a / b;
} catch (ArithmeticException ex) {
// This prints the stacktrace to standard output
ex.printStackTrace();
}
The printStackTrace() method without arguments will print to the application's standard output; i.e.
the current System.out. There are also printStackTrace(PrintStream) and
printStackTrace(PrintWriter) overloads that print to a specified Stream or Writer.
Notes:
1. The stacktrace does not include the details of the exception itself. You can use the
toString() method to get those details; e.g.
Understanding a stacktrace
https://riptutorial.com/ 344
Consider the following simple program consisting of two classes in two files. (We have shown the
filenames and added line numbers for illustration purposes.)
File: "Main.java"
1 public class Main {
2 public static void main(String[] args) {
3 new Test().foo();
4 }
5 }
File: "Test.java"
1 class Test {
2 public void foo() {
3 bar();
4 }
5
6 public int bar() {
7 int a = 1;
8 int b = 0;
9 return a / b;
10 }
When these files are compiled and run, we will get the following output.
Let us read this one line at a time to figure out what it is telling us.
Line #1 tells us that the thread called "main" has terminated due to an uncaught exception. The full
name of the exception is java.lang.ArithmeticException, and the exception message is "/ by zero".
Indeed, the message "/ by zero" is a strong hint that the cause of the exception is that some code
has attempted to divide something by zero. But what?
The remaining 3 lines are the stack trace. Each line represents a method (or constructor) call on
the call stack, and each one tells us three things:
• the name of the class and method that was being executed,
• the source code filename,
• the source code line number of the statement that was being executed
These lines of a stacktrace are listed with the frame for the current call at the top. The top frame in
our example above is in the Test.bar method, and at line 9 of the Test.java file. That is the
following line:
https://riptutorial.com/ 345
return a / b;
If we look a couple of lines earlier in the file to where b is initialized, it is apparent that b will have
the value zero. We can say without any doubt that this is the cause of the exception.
If we needed to go further, we can see from the stacktrace that bar() was called from foo() at line
3 of Test.java, and that foo() was in turn called from Main.main().
Note: The class and method names in the stack frames are the internal names for the classes and
methods. You will need to recognize the following unusual cases:
(In some versions of Java, the stacktrace formatting code will detect and elide repeated
stackframe sequences, as can occur when an application fails due to excessive recursion.)
Exception chaining happens when a piece of code catches an exception, and then creates and
throws a new one, passing the first exception as the cause. Here is an example:
File: Test,java
1 public class Test {
2 int foo() {
3 return 0 / 0;
4 }
5
6 public Test() {
7 try {
8 foo();
9 } catch (ArithmeticException ex) {
10 throw new RuntimeException("A bad thing happened", ex);
11 }
12 }
13
14 public static void main(String[] args) {
15 new Test();
16 }
17 }
When the above class is compiled and run, we get the following stacktrace:
https://riptutorial.com/ 346
Caused by: java.lang.ArithmeticException: / by zero
at Test.foo(Test.java:3)
at Test.<init>(Test.java:8)
... 1 more
The stacktrace starts with the class name, method and call stack for the exception that (in this
case) caused the application to crash. This is followed by a "Caused by:" line that reports the cause
exception. The class name and message are reported, followed by the cause exception's stack
frames. The trace ends with an "... N more" which indicates that the last N frames are the same as
for the previous exception.
The "Caused by:" is only included in the output when the primary exception's cause is not null).
Exceptions can be chained indefinitely, and in that case the stacktrace can have multiple "Caused
by:" traces.
Note: the cause mechanism was only exposed in the Throwable API in Java 1.4.0. Prior to that,
exception chaining needed to be implemented by the application using a custom exception field to
represent the cause, and a custom printStackTrace method.
The Apache Commons and Guava libraries provide utility methods for capturing a stacktrace as a
String:
org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)
com.google.common.base.Throwables.getStackTraceAsString(Throwable)
If you cannot use third party libraries in your code base, then the following method with do the
task:
/**
* Returns the string representation of the stack trace.
*
* @param throwable the throwable
* @return the string.
*/
public static String stackTraceToString(Throwable throwable) {
StringWriter stringWriter = new StringWriter();
throwable.printStackTrace(new PrintWriter(stringWriter));
return stringWriter.toString();
}
Note that if your intention is to analyze the stacktrace, it is simpler to use getStackTrace() and
getCause() than to attempt to parse a stacktrace.
https://riptutorial.com/ 347
Handling InterruptedException
But this is exactly the wrong way to handle an "impossible" event occurring. If you know your
application will never encounter an InterruptedException you should treat such an event as a
serious violation of your program's assumptions and exit as quickly as possible.
This does two things; it first restores the interrupt status of the thread (as if the
InterruptedException had not been thrown in the first place), and then it throws an AssertionError
indicating the basic invariants of your application have been violated. If you know for certain that
you'll never interrupt the thread this code runs in this is safe since the catch block should never be
reached.
More often, however, you cannot guarantee that your thread will never be interrupted. In particular
if you're writing code that will be executed by an Executor or some other thread-management it's
critical that your code responds promptly to interrupts, otherwise your application will stall or even
deadlock.
In such cases the best thing to do is generally to allow the InterruptedException to propagate up
the call stack, adding a throws InterruptedException to each method in turn. This may seem kludgy
https://riptutorial.com/ 348
but it's actually a desirable property - your method's signatures now indicates to callers that it will
respond promptly to interrupts.
// Let the caller determine how to handle the interrupt if you're unsure
public void myLongRunningMethod() throws InterruptedException {
...
}
In limited cases (e.g. while overriding a method that doesn't throw any checked exceptions) you
can reset the interrupted status without raising an exception, expecting whatever code is executed
next to handle the interrupt. This delays handling the interruption but doesn't suppress it entirely.
// Suppresses the exception but resets the interrupted state letting later code
// detect the interrupt and handle it properly.
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return ...; // your expectations are still broken at this point - try not to do more work.
}
All Java exceptions are instances of classes in the Exception class hierarchy. This can be
represented as follows:
• java.lang.Throwable - This is the base class for all exception classes. Its methods and
constructors implement a range of functionality common to all exceptions.
○ java.lang.Exception - This is the superclass of all normal exceptions.
○ various standard and custom exception classes.
○ java.lang.RuntimeException - This the superclass of all normal exceptions that are
unchecked exceptions.
○ various standard and custom runtime exception classes.
○ java.lang.Error - This is the superclass of all "fatal error" exceptions.
Notes:
https://riptutorial.com/ 349
know which exceptions a given method or procedure might throw. Given that an unhandled
exception is liable to cause a program to crash, this can make exceptions a source of fragility.
The Java language addresses this concern with the checked exception mechanism. First, Java
classifies exceptions into two categories:
• Checked exceptions typically represent anticipated events that an application should be able
to deal with. For instance, IOException and its subtypes represent error conditions that can
occur in I/O operations. Examples include, file opens failing because a file or directory does
not exist, network reads and writes failing because a network connection has been broken
and so on.
The second part of the checked exception mechanism is that there are restrictions on methods
where a checked exception may occur:
These restrictions do not apply to unchecked exceptions. This includes all cases where an
exception is thrown implicitly, since all such cases throw unchecked exceptions.
https://riptutorial.com/ 350
The first example shows how explicitly thrown checked exceptions can be declared as "thrown" if
they should not be handled in the method.
// INCORRECT
public void methodThrowingCheckedException(boolean flag) {
int i = 1 / 0; // Compiles OK, throws ArithmeticException
if (flag) {
throw new MyException(); // Compilation error
} else {
throw new MyException2(); // Compiles OK
}
}
// CORRECTED
public void methodThrowingCheckedException(boolean flag) throws MyException {
int i = 1 / 0; // Compiles OK, throws ArithmeticException
if (flag) {
throw new MyException(); // Compilation error
} else {
throw new MyException2(); // Compiles OK
}
}
The second example shows how a propagated checked exception can be dealt with.
// INCORRECT
public void methodWithPropagatedCheckedException() {
InputStream is = new FileInputStream("someFile.txt"); // Compilation error
// FileInputStream throws IOException or a subclass if the file cannot
// be opened. IOException is a checked exception.
...
}
// CORRECTED (Version A)
public void methodWithPropagatedCheckedException() throws IOException {
InputStream is = new FileInputStream("someFile.txt");
...
}
// CORRECTED (Version B)
public void methodWithPropagatedCheckedException() {
try {
InputStream is = new FileInputStream("someFile.txt");
...
} catch (IOException ex) {
System.out.println("Cannot open file: " + ex.getMessage());
}
}
The final example shows how to deal with a checked exception in a static field initializer.
// INCORRECT
public class Test {
private static final InputStream is =
new FileInputStream("someFile.txt"); // Compilation error
}
// CORRECTED
https://riptutorial.com/ 351
public class Test {
private static final InputStream is;
static {
InputStream tmp = null;
try {
tmp = new FileInputStream("someFile.txt");
} catch (IOException ex) {
System.out.println("Cannot open file: " + ex.getMessage());
}
is = tmp;
}
}
Note that in this last case, we also have to deal with the problems that is cannot be assigned to
more than once, and yet also has to be assigned to, even in the case of an exception.
Introduction
Exceptions are errors which occur when a program is executing. Consider the Java program
below which divides two integers.
class Division {
public static void main(String[] args) {
int a, b, result;
a = input.nextInt();
b = input.nextInt();
result = a / b;
Now we compile and execute the above code, and see the output for an attempted division by
zero:
Division by zero is an invalid operation that would produce a value that cannot be represented as
an integer. Java deals with this by throwing an exception. In this case, the exception is an
instance of the ArithmeticException class.
Note: The example on creating and reading stack traces explains what the output after the two
numbers means.
The utility of an exception is the flow control that it allows. Without using exceptions, a typical
https://riptutorial.com/ 352
solution to this problem may be to first check if b == 0:
class Division {
public static void main(String[] args) {
int a, b, result;
a = input.nextInt();
b = input.nextInt();
if (b == 0) {
System.out.println("You cannot divide by zero.");
return;
}
result = a / b;
This prints the message You cannot divide by zero. to the console and quits the program in a
graceful way when the user tries to divide by zero. An equivalent way of dealing with this problem
via exception handling would be to replace the if flow control with a try-catch block:
...
a = input.nextInt();
b = input.nextInt();
try {
result = a / b;
}
catch (ArithmeticException e) {
System.out.println("An ArithmeticException occurred. Perhaps you tried to divide by
zero.");
return;
}
...
It is generally considered good practice to use exception handling as part of the normal flow
https://riptutorial.com/ 353
control of an application where behavior would otherwise be undefined or unexpected. For
instance, instead of returning null when a method fails, it is usually better practice to throw an
exception so that the application making use of the method can define its own flow control for the
situation via exception handling of the kind illustrated above. In some sense, this gets around the
problem of having to return a particular type, as any one of multiple kinds of exceptions may be
thrown to indicate the specific problem that occurred.
For more advice on how and how not to use exceptions, refer to Java Pitfalls - Exception usage
Although it's bad practice, it's possible to add multiple return statements in a exception handling
block:
This method will always return 7 since the finally block associated with the try/catch block is
executed before anything is returned. Now, as finally has return 7;, this value supersedes the
try/catch return values.
If the catch block returns a primitive value and that primitive value is subsequently changed in the
finally block, the value returned in the catch block will be returned and the changes from the finally
block will be ignored.
System.out.println(n);
}
int returnNumber = 0;
try {
if (number % 2 == 0)
throw new Exception("Exception thrown");
else
return returnNumber;
https://riptutorial.com/ 354
} catch (Exception e) {
return returnNumber;
} finally {
returnNumber = 1;
}
}
}
This example covers some advanced features and use-cases for Exceptions.
The primary use of exception stacktraces is to provide information about an application error and
its context so that the programmer can diagnose and fix the problem. Sometimes it can be used
for other things. For example, a SecurityManager class may need to examine the call stack to
decide whether the code that is making a call should be trusted.
You can use exceptions to examine the call stack programatically as follows:
2. The javadocs for getStackTrace() state that a JVM is permitted to leave out frames:
Some virtual machines may, under some circumstances, omit one or more stack
frames from the stack trace. In the extreme case, a virtual machine that has no
stack trace information concerning this throwable is permitted to return a zero-
length array from this method.
https://riptutorial.com/ 355
The stack frame information needed for stacktraces, is captured when the Throwable constructors
call the Throwable.fillInStackTrace() method. This method is public, which means that a subclass
can override it. The trick is to override the method inherited from Throwable with one that does
nothing; e.g.
@Override
public void fillInStackTrace() {
// do nothing
}
}
The problem with this approach is that an exception that overrides fillInStackTrace() can never
capture the stacktrace, and is useless in scenarios where you need one.
In some situations, the stacktrace for an exception created in the normal way contains either
incorrect information, or information that the developer does not want to reveal to the user. For
these scenarios, the Throwable.setStackTrace can be used to replace the array of StackTraceElement
objects that holds the information.
For example, the following can be used to discard an exception's stack information:
exception.setStackTrace(new StackTraceElement[0]);
Suppressed exceptions
Java SE 7
Java 7 introduced the try-with-resources construct, and the associated concept of exception
suppression. Consider the following snippet:
When the exception is thrown, the try will call close() on the w which will flush any buffered output
and then close the FileWriter. But what happens if an IOException is thrown while flushing the
output?
What happens is that any exception that is thrown while cleaning up a resource is suppressed.
The exception is caught, and added to the primary exception's suppressed exception list. Next the
try-with-resources will continue with the cleanup of the other resources. Finally, primary exception
https://riptutorial.com/ 356
will be rethrown.
A similar pattern occurs if an exception it thrown during the resource initialization, or if the try
block completes normally. The first exception thrown becomes the primary exception, and
subsequent ones arising from cleanup are suppressed.
The suppressed exceptions can be retrieved from the primary exception object by calling
getSuppressedExceptions.
The try...catch...finally statement combines exception handling with clean-up code. The
finally block contains code that will be executed in all circumstances. This makes them suitable
for resource management, and other kinds of cleanup.
Try-finally
Here is an example of the simpler (try...finally) form:
try {
doSomething();
} finally {
cleanUp();
}
The code within finally block will always be executed. (The only exceptions are if System.exit(int)
is called, or if the JVM panics.) Thus a finally block is the correct place code that always needs to
be executed; e.g. closing files and other resources or releasing locks.
try-catch-finally
Our second example shows how catch and finally can be used together. It also illustrates that
cleaning up resources is not straightforward.
https://riptutorial.com/ 357
Reader reader = null;
try {
reader = new BufferedReader(new FileReader(fileName));
result = reader.readLine();
} catch (IOException ex) {
Logger.getLogger.warn("Unexpected IO error", ex); // logging the exception
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
// ignore / discard this exception
}
}
}
The complete set of (hypothetical) behaviors of try...catch...finally in this example are too
complicated to describe here. The simple version is that the code in the finally block will always
be executed.
• We declare the "resource" (i.e. reader variable) before the try block so that it will be in scope
for the finally block.
• By putting the new FileReader(...), the catch is able to handle any IOError exception from
thrown when opening the file.
• We need a reader.close() in the finally block because there are some exception paths that
we cannot intercept either in the try block or in catch block.
• However, since an exception might have been thrown before reader was initialized, we also
need an explicit null test.
• Finally, the reader.close() call might (hypothetically) throw an exception. We don't care about
that, but if we don't catch the exception at source, we would need to deal with it further up
the call stack.
Java SE 7
Java 7 and later provide an alternative try-with-resources syntax which significantly simplifies
resource clean-up.
Java's checked exception mechanism requires the programmer to declare that certain methods
could throw specifed checked exceptions. This is done using the throws clause. For example:
https://riptutorial.com/ 358
The throws OddNumberException declares that a call to checkEven could throw an exception that is of
type OddNumberException.
A throws clause can declare a list of types, and can include unchecked exceptions as well as
checked exceptions.
1. It tells the compiler which exceptions are thrown so that the compiler can report uncaught
(checked) exceptions as errors.
2. It tells a programmer who is writing code that calls the method what exceptions to expect.
For this purpose, it often makes to senses to include unchecked exceptions in a throws list.
Note: that the throws list is also used by the javadoc tool when generating API documentation, and
by a typical IDE's "hover text" method tips.
@Override
public void checkEven(int number) throws NullPointerException // OK—NullPointerException is an
unchecked exception
...
@Override
public void checkEven(Double number) throws OddNumberException // OK—identical to the
superclass
...
@Override
public void checkEven(int number) throws PrimeNumberException, NonEvenNumberException //
https://riptutorial.com/ 359
OK—these are both subclasses
@Override
public void checkEven(Double number) throws IOExcepion // ERROR
The reason for this rule is that if an overriden method can throw a checked exception that the
overridden method could not throw, that would break type substitutability.
https://riptutorial.com/ 360
Chapter 54: Executor, ExecutorService and
Thread pools
Introduction
The Executor interface in Java provides a way of decoupling task submission from the mechanics
of how each task will be run, including details of thread use, scheduling, etc. An Executor is
normally used instead of explicitly creating threads. With Executors, developers won't have to
significantly rewrite their code to be able to easily tune their program's task-execution policy.
Remarks
Pitfalls
Examples
Fire and Forget - Runnable Tasks
Note that with this executor, you have no means to get any computed value back.
With Java 8, one can utilize lambdas to shorten the code example.
Java SE 8
https://riptutorial.com/ 361
ThreadPoolExecutor
A common Executor used is the ThreadPoolExecutor, which takes care of Thread handling. You can
configure the minimal amount of Threads the executor always has to maintain when there's not
much to do (it's called core size) and a maximal Thread size to which the Pool can grow, if there is
more work to do. Once the workload declines, the Pool slowly reduces the Thread count again
until it reaches min size.
pool.execute(new Runnable() {
@Override public void run() {
//code to run
}
});
Note If you configure the ThreadPoolExecutor with an unbounded queue, then the thread count will
not exceed corePoolSize since new threads are only created if the queue is full:
from JavaDoc
If there are more than corePoolSize but less than maximumPoolSize threads running,
a new thread will be created only if the queue is full.
Advantages:
https://riptutorial.com/ 362
4. In ThreadPoolExecutor.DiscardOldestPolicy, if the executor is not shut down, the task at
the head of the work queue is dropped, and then execution is retried (which can fail
again, causing this to be repeated.)
If your computation produces some return value which later is required, a simple Runnable task
isn't sufficient. For such cases you can use ExecutorService.submit(Callable<T>) which returns a
value after execution completes.
The Service will return a Future which you can use to retrieve the result of the task execution.
When you need to get the result of the future, call future.get()
try {
// Blocks current thread until future is completed
Integer result = future.get();
catch (InterruptedException || ExecutionException e) {
// handle appropriately
}
try {
// Blocks current thread for a maximum of 500 milliseconds.
// If the future finishes before that, result is returned,
// otherwise TimeoutException is thrown.
Integer result = future.get(500, TimeUnit.MILLISECONDS);
catch (InterruptedException || ExecutionException || TimeoutException e) {
// handle appropriately
}
If the result of a scheduled or running task is no longer required, you can call
https://riptutorial.com/ 363
Future.cancel(boolean) to cancel it.
• Calling cancel(false) will just remove the task from the queue of tasks to be run.
• Calling cancel(true) will also interrupt the task if it is currently running.
The ScheduledExecutorService class provides a methods for scheduling single or repeated tasks in
a number of ways. The following code sample assume that pool has been declared and initialized
as follows:
Task execution will continue according to the schedule until the pool is shut down, the future is
canceled, or one of the tasks encounters an exception.
It is guaranteed that the tasks scheduled by a given scheduledAtFixedRate call will not overlap in
time. If a task takes longer than the prescribed period, then the next and subsequent task
executions may start late.
https://riptutorial.com/ 364
Starting tasks with a fixed delay
The following example schedules a task to start after ten minutes, and then repeatedly with a
delay of one minute between one task ending and the next one starting.
Task execution will continue according to the schedule until the pool is shut down, the future is
canceled, or one of the tasks encounters an exception.
If
The default behavior is that you'll get a RejectedExecutionException thrown at the caller. But there
are more predefined behaviors available:
https://riptutorial.com/ 365
You can as well implement your own behavior by extending RejectedExecutionHandler interface:
Generally execute() command is used for fire and forget calls (without need of analyzing the
result) and submit() command is used for analyzing the result of Future object.
We should be aware of key difference of Exception Handling mechanisms between these two
commands.
Exceptions from submit() are swallowed by framework if you did not catch them.
Case 1: submit the Runnable with execute() command, which reports the Exception.
import java.util.concurrent.*;
import java.util.*;
public ExtendedExecutor() {
super(1, 1, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
}
// ...
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException ce) {
https://riptutorial.com/ 366
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null)
System.out.println(t);
}
}
output:
creating service
a and b=4:0
a and b=4:0
Exception in thread "pool-1-thread-1" Exception in thread "pool-1-thread-2"
java.lang.ArithmeticException: / by zero
at ExecuteSubmitDemo$1.run(ExecuteSubmitDemo.java:15)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
java.lang.ArithmeticException: / by zero
at ExecuteSubmitDemo$1.run(ExecuteSubmitDemo.java:15)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
output:
creating service
a and b=4:0
a and b=4:0
output:
creating service
a and b=4:0
java.lang.ArithmeticException: / by zero
a and b=4:0
java.lang.ArithmeticException: / by zero
I have demonstrated this example to cover two topics : Use your custom ThreadPoolExecutor and
handle Exectpion with custom ThreadPoolExecutor.
https://riptutorial.com/ 367
Other simple solution to above problem : When you are using normal ExecutorService &
submit command, get the Future object from submit() command call get() API on Future. Catch the
three exceptions, which have been quoted in afterExecute method implementation. Advantage of
custom ThreadPoolExecutor over this approach : You have to handle Exception handling
mechanism in only one place - Custom ThreadPoolExecutor.
1. ExecutorService
I prefer this one when number of Callable/Runnable tasks are small in number and piling of
tasks in unbounded queue does not increase memory & degrade the performance of the
system. If you have CPU/Memory constraints, I prefer to use ThreadPoolExecutor with capacity
constraints & RejectedExecutionHandler to handle rejection of tasks.
2. CountDownLatch
CountDownLatch will be initialized with a given count. This count is decremented by calls to the
countDown() method. Threads waiting for this count to reach zero can call one of the await()
methods. Calling await() blocks the thread until the count reaches zero. This class enables a
java thread to wait until other set of threads completes their tasks.
Use cases:
3. Deadlock detection.
https://riptutorial.com/ 368
head of the work queue is dropped, and then execution is retried (which can fail again,
causing this to be repeated.)
If you want to simulate CountDownLatch behaviour, you can use invokeAll() method.
The ForkJoinPool was added to Java in Java 7. The ForkJoinPool is similar to the Java
ExecutorService but with one difference. The ForkJoinPool makes it easy for tasks to split their
work up into smaller tasks which are then submitted to the ForkJoinPool too. Task stealing
happens in ForkJoinPool when free worker threads steal tasks from busy worker thread
queue.
Java 8 has introduced one more API in ExecutorService to create work stealing pool. You
don't have to create RecursiveTask and RecursiveAction but still can use ForkJoinPool.
Creates a work-stealing thread pool using all available processors as its target
parallelism level.
All these four mechanism are complimentary to each other. Depending on level of granularity you
want to control, you have to chose right ones.
Let's have a look at various options to wait for completion of tasks submitted to Executor
1. ExecutorService invokeAll()
Executes the given tasks, returning a list of Futures holding their status and
results when everything is completed.
Example:
import java.util.concurrent.*;
import java.util.*;
https://riptutorial.com/ 369
try{
List<Future<Long>> futures = service.invokeAll(futureList);
} catch(Exception err){
err.printStackTrace();
}
System.out.println("Completed");
service.shutdown();
}
public static void main(String args[]){
InvokeAllDemo demo = new InvokeAllDemo();
}
class MyCallable implements Callable<Long>{
Long id = 0L;
public MyCallable(Long val){
this.id = val;
}
public Long call(){
// Add your business logic
return id;
}
}
}
2. CountDownLatch
A synchronization aid that allows one or more threads to wait until a set of
operations being performed in other threads completes.
https://riptutorial.com/ 370
shutdown():Initiates an orderly shutdown in which previously submitted tasks are executed,
but no new tasks will be accepted.
shutdownNow():Attempts to stop all actively executing tasks, halts the processing of waiting
tasks, and returns a list of the tasks that were awaiting execution.
In above example, if your tasks are taking more time to complete, you can change if
condition to while condition
Replace
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
with
while(!pool.awaitTermination(60, TimeUnit.SECONDS)) {
Thread.sleep(60000);
Creates an Executor that uses a single worker thread operating off an unbounded
queue
Which means that a newFixedThreadPool can be reconfigured later in the program by:
((ThreadPoolExecutor) fixedThreadPool).setMaximumPoolSize(10) This is not possible for
newSingleThreadExecutor
Use cases:
Cons:
Creates a thread pool that reuses a fixed number of threads operating off a
https://riptutorial.com/ 371
shared unbounded queue. At any point, at most nThreads threads will be active
processing tasks. If additional tasks are submitted when all threads are active,
they will wait in the queue until a thread is available
Use cases:
Cons:
Creates a thread pool that creates new threads as needed, but will reuse
previously constructed threads when they are available
Use cases:
Cons:
Creates a thread pool that can schedule commands to run after a given delay, or
to execute periodically.
Use cases:
1. Handling recurring events with delays, which will happen in future at certain interval of
times
Cons:
Creates a work-stealing thread pool using all available processors as its target
parallelism level
Use cases:
https://riptutorial.com/ 372
2. Effective use of idle threads. Idle threads steals tasks from busy threads.
Cons:
You can see one common drawbacks in all these ExecutorService : unbounded queue. This will
be addressed with ThreadPoolExecutor
Method Description
Executes a the submitted work and return a future which can be used to get the
submit
result
execute Execute the task sometime in the future without getting any return value
Executes all the but return only the result of one that has been successful (without
invokeAny
exceptions)
Once you are done with the Thread Pool you can call shutdown() to terminate the Thread Pool.
This executes all pending tasks. To wait for all tasks to execute you can can loop around
awaitTermination or isShutdown().
https://riptutorial.com/ 373
Chapter 55: Expressions
Introduction
Expressions in Java are the primary construct for doing calculations.
Remarks
For a reference on the operators that can be used in expressions, see Operators.
Examples
Operator Precedence
When an expression contains multiple operators, it can potentially be read in different ways. For
example, the mathematical expression 1 + 2 x 3 could be read in two ways:
1. Add 1 and 2 and multiply the result by 3. This gives the answer 9. If we added parentheses,
this would look like ( 1 + 2 ) x 3.
2. Add 1 to the result of multiplying 2 and 3. This gives the answer 7. If we added parentheses,
this would look like 1 + ( 2 x 3 ).
In mathematics, the convention is to read the expression the second way. The general rule is that
multiplication and division are done before addition and subtraction. When more advanced
mathematical notation is used, either the meaning is either "self-evident" (to a trained
mathematician!), or parentheses are added to disambiguate. In either case, the effectiveness of
the notation to convey meaning depends on the intelligence and shared knowledge of the
mathematicians.
Java has the same clear rules on how to read an expression, based on the precedence of the
operators that are used.
In general, each operator is ascribed a precedence value; see the table below.
For example:
1 + 2 * 3
The precedence of + is lower than the precedence of *, so the result of the expression is 7, not 9.
Qualifier name.name
Parentheses (expr) 15 Left to right
Instance creation new
https://riptutorial.com/ 374
Description Operators / constructs (primary) Precedence Associativity
Bitwise exclusive
^ 6 Left to right
OR
1 Lambda expression precedence is complex, as it can also occur after a cast, or as the third part
of the conditional ternary operator.
Constant Expressions
A constant expression is an expression that yields a primitive type or a String, and whose value
can be evaluated at compile time to a literal. The expression must evaluate without throwing an
exception, and it must be composed of only the following:
https://riptutorial.com/ 375
• Type casts to primitive types or String.
• The following binary operators: *, /, %, +, -, <<, >>, >>>, <, <=, >, >=, ==, !=, &, ^, |, && and ||.
• Simple names that refer to constant variables. (A constant variable is a variable declared as
final where the initializer expression is itself a constant expression.)
• Qualified names of the form <TypeName> . <Identifier> that refer to constant variables.
Note that the above list excludes ++ and --, the assignment operators, class and instanceof,
method calls and references to general variables or fields.
Constant expressions of type String result in an "interned" String, and floating point operations in
constant expressions are evaluated with FP-strict semantics.
Constant expressions are required for case labels in switch statements. For example:
switch (someValue) {
case 1 + 1: // OK
case Math.min(2, 3): // Error - not a constant expression
doSomething();
}
When the expression on the right hand side of an assignment is a constant expression, then the
assignment can perform a primitive narrowing conversion. This is allowed provided that the value
of the constant expression is within the range of the type on the left hand side. (See JLS 5.1.3 and
5.2) For example:
When a constant expression is used as the condition in a do, while or for, then it affects the
readability analysis. For example:
while (false) {
doSomething(); // Error - statenent not reachable
}
boolean flag = false;
https://riptutorial.com/ 376
while (flag) {
doSomething(); // OK
}
(Note that this does not apply if statements. The Java compiler allows the then or else block of an
if statement to be unreachable. This is the Java analog of conditional compilation in C and C++.)
Finally, static final fields in an class or interface with constant expression initializers are
initialized eagerly. Thus, it is guaranteed that these constants will be observed in the initialized
state, even when there is a cycle in the class initialization dependency graph.
Simple Example
In the following example:
Note that if the effects of the calls are observable, you will be able to observe that the call to
method1 occurs before the call to method2.
int i = 1;
intArray[i] = ++i + 1;
https://riptutorial.com/ 377
1. The left operand of = operator is evaluated. This gives the address of intArray[1].
2. The pre-increment is evaluated. This adds 1 to i, and evaluates to 2.
3. The right hand operand of the + is evaluated.
4. The + operation is evaluated to: 2 + 1 -> 3.
5. The = operation is evaluated, assigning 3 to intArray[1].
Note that since the left-hand operand of the = is evaluated first, it is not influenced by the side-
effect of the ++i subexpression.
Reference:
Expression Basics
Expressions in Java are the primary construct for doing calculations. Here are some examples:
The details of the different forms of expressions may be found in other Topics.
• The Operators topic covers unary, binary and ternary operator expressions.
https://riptutorial.com/ 378
• The Lambda expressions topic covers lambda expressions and method reference
expressions.
• The Classes and Objects topic covers class instance creation expressions.
• The Arrays topic covers array access expressions and array instance creation expressions.
• The Literals topic covers the different kinds of literals expressions.
However, (in Java 8 and later) the following kinds of expressions may be poly expressions:
• Parenthesized expressions
• Class instance creation expressions
• Method invocation expressions
• Method reference expressions
• Conditional expressions
• Lambda expressions
When an expression is a poly expression, its type may be influenced by the expression's target
type; i.e. what it is being used for.
Expression Statements
Unlike many other languages, Java does not generally allow expressions to be used as
statements. For example:
Since the result of evaluating an expression like cannot be use, and since it cannot affect the
execution of the program in any other way, the Java designers took the position that such usage is
either a mistake, or misguided.
However, this does not apply to all expressions. A subset of expressions are (in fact) legal as
statements. The set comprises:
https://riptutorial.com/ 379
• Method calls (void or non-void).
• Class instance creation expressions.
https://riptutorial.com/ 380
Chapter 56: File I/O
Introduction
Java I/O (Input and Output) is used to process the input and produce the output. Java uses the
concept of stream to make I/O operation fast. The java.io package contains all the classes
required for input and output operations. Handling files is also done in java by Java I/O API.
Examples
Reading all bytes to a byte[]
Java SE 7
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;
try {
byte[] data = Files.readAllBytes(path);
} catch(IOException e) {
e.printStackTrace();
}
import java.awt.Image;
import javax.imageio.ImageIO;
...
try {
Image img = ImageIO.read(new File("~/Desktop/cat.png"));
} catch (IOException e) {
e.printStackTrace();
}
Java SE 7
https://riptutorial.com/ 381
// Handle I/O Exception
ioe.printStackTrace();
}
Java SE 7
Most java.io file APIs accept both Strings and Files as arguments, so you could as well use
Streams provide the most direct access to the binary content, so any InputStream / OutputStream
implementations always operate on ints and bytes.
// Read a chunk
byte[] data = new byte[1024];
int nBytesRead = inputStream.read(data);
if (nBytesRead >= 0) { // A negative value represents end of stream
// Write the chunk to another stream
outputStream.write(data, 0, nBytesRead);
}
There are some exceptions, probably most notably the PrintStream which adds the "ability to print
representations of various data values conveniently". This allows to use System.out both as a
binary InputStream and as a textual output using methods such as System.out.println().
Also, some stream implementations work as an interface to higher-level contents such as Java
objects (see Serialization) or native types, e.g. DataOutputStream / DataInputStream.
https://riptutorial.com/ 382
With the Writer and Reader classes, Java also provides an API for explicit character streams.
Although most applications will base these implementations on streams, the character stream API
does not expose any methods for binary content.
Whenever it is necessary to encode characters into binary data (e.g. when using the
InputStreamWriter / OutputStreamWriter classes), you should specify a charset if you do not want to
depend on the platform's default charset. When in doubt, use a Unicode-compatible encoding, e.g.
UTF-8 which is supported on all Java platforms. Therefore, you should probably stay away from
classes like FileWriter and FileReader as those always use the default platform charset. A better
way to access files using character streams is this:
One of the most commonly used Readers is BufferedReader which provides a method to read whole
lines of text from another reader and is presumably the simplest way to read a character stream
line by line:
\Z is the EOF (End of File) Symbol. When set as delimiter the Scanner will read the fill until the
EOF Flag is reached.
https://riptutorial.com/ 383
Reading a file with a Scanner
word by word
and you can also change the delimeter by using scanner.useDelimeter() method
https://riptutorial.com/ 384
Migrating from java.io.File to Java 7 NIO (java.nio.file.Path)
These examples assume that you already know what Java 7's NIO is in general, and you are used
to writing code using java.io.File. Use these examples as a means to quickly find more NIO-
centric documentation for migrating.
There is much more to Java 7's NIO such as memory-mapped files or opening a ZIP or JAR file
using FileSystem. These examples will only cover a limited number of basic use cases.
As a basic rule, if you are used to perform a file system read/write operation using a java.io.File
instance method, you will find it as a static method within java.nio.file.Files.
Point to a path
// -> IO
File file = new File("io.txt");
// -> NIO
Path path = Paths.get("nio.txt");
// -> NIO
Path directory = Paths.get("C:/");
Path pathInDirectory = directory.resolve("nio.txt");
// -> NIO to IO
File fileFromPath = Paths.get("nio.txt").toFile();
https://riptutorial.com/ 385
if (file.exists()) {
boolean deleted = file.delete();
if (!deleted) {
throw new IOException("Unable to delete file");
}
}
// -> NIO
Files.deleteIfExists(path);
// -> IO
if (file.exists()) {
// Note: Not atomic
throw new IOException("File already exists");
}
try (FileOutputStream outputStream = new FileOutputStream(file)) {
for (String line : lines) {
outputStream.write((line + System.lineSeparator()).getBytes(StandardCharsets.UTF_8));
}
}
// -> NIO
try (OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW)) {
for (String line : lines) {
outputStream.write((line + System.lineSeparator()).getBytes(StandardCharsets.UTF_8));
}
}
// -> NIO
Files.walkFileTree(directory, EnumSet.noneOf(FileVisitOption.class), 1, new
https://riptutorial.com/ 386
SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path selectedPath, BasicFileAttributes attrs)
throws IOException {
System.out.println("d " + selectedPath.toAbsolutePath());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path selectedPath, BasicFileAttributes attrs) throws
IOException {
System.out.println("f " + selectedPath.toAbsolutePath());
return FileVisitResult.CONTINUE;
}
});
// -> NIO
// Note: Symbolic links are NOT followed unless explicitly passed as an argument to
Files.walkFileTree
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws
IOException {
System.out.println("d " + selectedPath.toAbsolutePath());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path selectedPath, BasicFileAttributes attrs) throws
IOException {
System.out.println("f " + selectedPath.toAbsolutePath());
return FileVisitResult.CONTINUE;
}
});
https://riptutorial.com/ 387
String filepath ="C:\\test.txt";
FileOutputStream fos = null;
try {
fos = new FileOutputStream(filepath);
byte[] buffer = "This will be written in test.txt".getBytes();
fos.write(buffer, 0, buffer.length);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fos != null)
fos.close();
}
Note, that since Java 1.7 the try-with-resources statement was introduced what made
implementation of reading\writing operation much simpler:
https://riptutorial.com/ 388
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You can read an a binary file using this piece of code in all recent versions of Java:
Java SE 1.4
If you are using Java 7 or later, there is a simpler way using the nio API:
Java SE 7
Locking
A file can be locked using the FileChannel API that can be acquired from Input Output streams and
readers
/*
* try to lock the file. true means whether the lock is shared or not i.e. multiple
processes can acquire a
* shared lock (for reading only) Using false with readable channel only will generate an
exception. You should
* use a writable channel (taken from FileOutputStream) when using false. tryLock will
always return immediately
*/
FileLock lock = channel.tryLock(0, Long.MAX_VALUE, true);
if (lock == null) {
System.out.println("Unable to acquire lock");
} else {
System.out.println("Lock acquired successfully");
}
// you can also use blocking call which will block until a lock is acquired.
channel.lock();
https://riptutorial.com/ 389
// Once you have completed desired operations of file. release the lock
if (lock != null) {
lock.release();
}
We can directly copy data from a source to a data sink using a loop. In this example, we are
reading data from an InputStream and at the same time, writing to an OutputStream. Once we are
done reading and writing, we have to close the resource.
Channel uses a Buffer to read/write data. A buffer is a fixed sized container where we can write a
block of data at once. Channel is a quite faster than stream-based I/O.
To read data from a file using Channel we need to have the following steps-
https://riptutorial.com/ 390
5. When we call the read method of the Channel, it fills up the buffer using data.
6. If we need to read the data from the ByteBuffer, we need to flip the buffer to change its mode
to write-only to read-only mode and then keep reading data from the buffer.
7. When there is no longer data to read, the read() method of channel returns 0 or -1.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
if (!inputFile.exists()) {
System.out.println("The input file doesn't exit.");
return;
}
try {
FileInputStream fis = new FileInputStream(inputFile);
FileChannel fileChannel = fis.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
We can use Channel to copy file content faster. To do so, we can use transferTo() method of
FileChannel .
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
https://riptutorial.com/ 391
File sourceFile = new File("hello.txt");
File sinkFile = new File("hello2.txt");
copy(sourceFile, sinkFile);
}
Reading file using a BufferedInputStream generally faster than FileInputStream because it maintains
an internal buffer to store bytes read from the underlying input stream.
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
}
}
To write data to a file using Channel we need to have the following steps:
https://riptutorial.com/ 392
4. Then we have to call the flip() method of the ByteBuffer and pass it as an argument of the
write() method of the FileChannel
5. Once we are done writing, we have to close the resource
import java.io.*;
import java.nio.*;
public class FileChannelWrite {
try {
FileOutputStream fos = new FileOutputStream(outputFile);
FileChannel fileChannel = fos.getChannel();
byte[] bytes = text.getBytes();
ByteBuffer buffer = ByteBuffer.wrap(bytes);
fileChannel.write(buffer);
fileChannel.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
}
We can use PrintStream class to write a file. It has several methods that let you print any data type
values. println() method appends a new line. Once we are done printing, we have to flush the
PrintStream.
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.time.LocalDate;
ps.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
https://riptutorial.com/ 393
public void iterate(final String dirPath) throws IOException {
final DirectoryStream<Path> paths = Files.newDirectoryStream(Paths.get(dirPath));
for (final Path path : paths) {
if (Files.isDirectory(path)) {
System.out.println(path.getFileName());
}
}
}
Adding Directories
To make a new directory from a File instance you would need to use one of two methods:
mkdirs() or mkdir().
// assume that neither "A New Folder" or "A New Folder 2" exist
Sometimes a poorly designed 3rd-party library will write unwanted diagnostics to System.out or
System.err streams. The recommended solutions to this would be to either find a better library or
(in the case of open source) fix the problem and contribute a patch to the developers.
If the above solutions are not feasible, then you should consider redirecting the streams.
On a UNIX, Linux or MacOSX system can be done from the shell using > redirection. For example:
The first one redirects standard output and standard error to "/dev/null", which throws away
anything written to those streams. The second of redirects standard output to "out.log" and
https://riptutorial.com/ 394
standard error to "error.log".
(For more information on redirection, refer to the documentation of the command shell you are
using. Similar advice applies to Windows.)
Alternatively, you could implement the redirection in a wrapper script or batch file that launches the
Java application.
It is also possible to redired the streams within a Java application using System.setOut() and
System.setErr(). For example, the following snippet redirects standard output and standard error to
2 log files:
If you want to throw away the output entirely, you can create an output stream that "writes" to an
invalid file descriptor. This is functionally equivalent to writing to "/dev/null" on UNIX.
The FileSystem API of Java 7 allows to read and add entries from or to a Zip file using the Java
NIO file API in the same way as operating on any other filesystem.
The FileSystem is a resource that should be properly closed after use, therefore the try-with-
resources block should be used.
https://riptutorial.com/ 395
Map<String, String> env = new HashMap<>();
env.put("create", "true"); //required for creating a new zip file
env.put("encoding", "UTF-8"); //optional: default is UTF-8
URI uri = URI.create("jar:file:/path/to/file.zip");
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
Path newFile = zipFs.getPath("/newFile.txt");
//writing to file
Files.write(newFile, "Hello world".getBytes());
} catch(IOException ex) {
ex.printStackTrace();
}
https://riptutorial.com/ 396
Chapter 57: FileUpload to AWS
Introduction
Upload File to AWS s3 bucket using spring rest API.
Examples
Upload file to s3 bucket
Here we will create a rest APi which will take file object as a multipart parameter from
front end and upload it to S3 bucket using java rest API.
Requirement :- secrete key and Access key for s3 bucket where you wanna upload your file.
code:- DocumentController.java
@RestController
@RequestMapping("/api/v2")
public class DocumentController {
System.out.println("*****************************");
https://riptutorial.com/ 397
/****************** DocumentController.uploadfile(credentials);
***************************/
return url;
return null;
var settings = {
"async": true,
"crossDomain": true,
"url": "http://url/",
"method": "POST",
"headers": {
"cache-control": "no-cache"
https://riptutorial.com/ 398
},
"processData": false,
"contentType": false,
"mimeType": "multipart/form-data",
"data": form
}
$.ajax(settings).done(function (response) {
console.log(response);
});
https://riptutorial.com/ 399
Chapter 58: Fluent Interface
Remarks
Goals
When used for constructing objects, the choices available to the caller can be made clearly and
enforced via compile-time checks. For example, consider the following tree of options representing
steps along the path to construct some complex object:
A -> B
-> C -> D -> Done
-> E -> Done
-> F -> Done.
-> G -> H -> I -> Done.
A builder using a fluent interface would allow the caller to easily see what options are available at
each step. For example, A -> B is possible, but A -> C is not and would result in a compile-time
error.
Examples
Truth - Fluent Testing Framework
In fluent programming style you return this from fluent (setter) methods that would return nothing
in non-fluent programming style.
This allows you to chain the different method calls which makes your code shorter and easier to
handle for the developers.
https://riptutorial.com/ 400
private String firstName;
private String lastName;
As the setter methods don't return anything, we need 4 instructions in the mainmethod to
instantiate a Person with some data and print it. With a fluent style this code can be changed to:
https://riptutorial.com/ 401
public static void main(String[] args) {
System.out.println(new Person().withFirstName("John")
.withLastName("Doe").whoAreYou());
}
}
The idea is to always return some object to enable building of a method call chain and to use
method names which reflect natural speaking. This fluent style makes the code more readable.
https://riptutorial.com/ 402
Chapter 59: FTP (File Transfer Protocol)
Syntax
• FTPClient connect(InetAddress host, int port)
• FTPClient login(String username, String password)
• FTPClient disconnect()
• FTPReply getReplyStrings()
• boolean storeFile(String remote, InputStream local)
• OutputStream storeFileStream(String remote)
• boolean setFileType(int fileType)
• boolean completePendingCommand()
Parameters
Parameters Details
Examples
Connecting and Logging Into a FTP Server
To start using FTP with Java, you will need to create a new FTPClient and then connect and login
to the server using .connect(String server, int port) and .login(String username, String password)
.
import java.io.IOException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
//Import all the required resource for this project.
https://riptutorial.com/ 403
ftp.connect(server, port);
ftp.login(user, pass);
}
}
Now we have the basics done. But what if we have an error connecting to the server? We'll want
to know when something goes wrong and get the error message. Let's add some code to catch
errors while connecting.
try {
ftp.connect(server, port);
showServerReply(ftp);
int replyCode = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
System.out.printIn("Operation failed. Server reply code: " + replyCode)
return;
}
ftp.login(user, pass);
} catch {
showServerReply(ftp);
This grabs the reply/error code from the server and stores it as an integer.
if (!FTPReply.isPositiveCompletion(replyCode)) {
System.out.printIn("Operation failed. Server reply code: " + replyCode)
return;
}
This checks the reply code to see if there was an error. If there was an error, it will simply print
"Operation failed. Server reply code: " followed by the error code. We also added a try/catch block
which we will add to in the next step. Next, let's also create a function that checks ftp.login() for
errors.
https://riptutorial.com/ 404
boolean success = ftp.login(user, pass);
This will not just attempt to login to the FTP server, it will also store the result as a boolean.
showServerReply(ftp);
This will check if the server sent us any messages, but we will first need to create the function in
the next step.
if (!success) {
System.out.println("Failed to log into the server");
return;
} else {
System.out.println("LOGGED IN SERVER");
}
This statement will check if we logged in successfully; if so, it will print "LOGGED IN SERVER",
otherwise it will print "Failed to log into the server". This is our script so far:
import java.io.IOException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
}
}
}
Now next let's create complete the Catch block in case we run into any errors with the whole
process.
https://riptutorial.com/ 405
} catch (IOException ex) {
System.out.println("Oops! Something went wrong.");
ex.printStackTrace();
}
The completed catch block will now print "Oops! Something went wrong." and the stacktrace if
there is an error. Now our final step is to create the showServerReply() we have been using for a
while now.
This function takes an FTPClient as a variable, and calls it "ftp". After that it stores any server
replies from the server in a string array. Next it checks if any messages were stored. If there is
any, it prints each of them as "SERVER: [reply]". Now that we have that function done, this is the
completed script:
import java.io.IOException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
https://riptutorial.com/ 406
return;
} else {
System.out.println("LOGGED IN SERVER");
}
} catch (IOException ex) {
System.out.println("Oops! Something went wrong.");
ex.printStackTrace();
}
}
}
We first need to create a new FTPClient and try connecting to the server it and logging into it using
.connect(String server, int port) and .login(String username, String password). It is important to
connect and login using a try/catch block in case our code fails to connect with the server. We will
also need to create a function that checks and displays any messages we may receive from the
server as we try connecting and logging in. We will call this function "showServerReply(FTPClient
ftp)".
import java.io.IOException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
https://riptutorial.com/ 407
}
}
}
After this, you should now have your FTP server connected to you Java script.
https://riptutorial.com/ 408
Chapter 60: Functional Interfaces
Introduction
In Java 8+, a functional interface is an interface that has just one abstract method (aside from the
methods of Object). See JLS §9.8. Functional Interfaces.
Examples
List of standard Java Runtime Library functional interfaces by signature
() void Runnable
() T Supplier
() boolean BooleanSupplier
() int IntSupplier
() long LongSupplier
() double DoubleSupplier
(T) T UnaryOperator<T>
(T) R Function<T,R>
(T, T) T BinaryOperator<T>
(T, U) R BiFunction<T,U,R>
https://riptutorial.com/ 409
Parameter Types Return Type Interface
(int) R IntFunction<R>
(long) R LongFunction<R>
(double) R DoubleFunction<R>
https://riptutorial.com/ 410
Parameter Types Return Type Interface
https://riptutorial.com/ 411
Chapter 61: Generating Java Code
Examples
Generate POJO From JSON
https://riptutorial.com/ 412
Chapter 62: Generics
Introduction
Generics are a facility of generic programming that extend Java's type system to allow a type or
method to operate on objects of various types while providing compile-time type safety. In
particular, the Java collections framework supports generics to specify the type of objects stored in
a collection instance.
Syntax
• class ArrayList<E> {} // a generic class with type parameter E
• class HashMap<K, V> {} // a generic class with two type parameters K and V
• <E> void print(E element) {} // a generic method with type parameter E
• ArrayList<String> names; // declaration of a generic class
• ArrayList<?> objects; // declaration of a generic class with an unknown type parameter
• new ArrayList<String>() // instantiation of a generic class
• new ArrayList<>() // instantiation with type inference "diamond" (Java 7 or later)
Remarks
Generics are implemented in Java through Type erasure, which means that during runtime the
Type information specified in the instantiation of a generic class is not available. For example, the
statement List<String> names = new ArrayList<>(); produces a list object from which the element
type String cannot be recovered at runtime. However, if the list is stored in a field of type
List<String>, or passed to a method/constructor parameter of this same type, or returned from a
method of that return type, then the full type information can be recovered at runtime through the
Java Reflection API.
This also means that when casting to a generic type (e.g.: (List<String>) list), the cast is an
unchecked cast. Because the parameter <String> is erased, the JVM cannot check if a cast from a
List<?> to a List<String> is correct; the JVM only sees a cast for List to List at runtime.
Examples
Creating a Generic Class
Generics enable classes, interfaces, and methods to take other classes and interfaces as type
parameters.
This example uses generic class Param to take a single type parameter T, delimited by angle
brackets (<>):
https://riptutorial.com/ 413
private T value;
public T getValue() {
return value;
}
To instantiate this class, provide a type argument in place of T. For example, Integer:
The type argument can be any reference type, including arrays and other generic types:
Param<String[]> stringArrayParam;
Param<int[][]> int2dArrayParam;
Param<Param<Object>> objectNestedParam;
In Java SE 7 and later, the type argument can be replaced with an empty set of type arguments (
<>) called the diamond:
Java SE 7
Unlike other identifiers, type parameters have no naming constraints. However their names are
commonly the first letter of their purpose in upper case. (This is true even throughout the official
JavaDocs.)
Examples include T for "type", E for "element" and K/V for "key"/"value".
public T getValue() {
return value;
}
AbstractParam is an abstract class declared with a type parameter of T. When extending this class,
that type parameter can be replaced by a type argument written inside <>, or the type parameter
can remain unchanged. In the first and second examples below, String and Integer replace the
https://riptutorial.com/ 414
type parameter. In the third example, the type parameter remains unchanged. The fourth example
doesn't use generics at all, so it's similar to if the class had an Object parameter. The compiler will
warn about AbstractParam being a raw type, but it will compile the ObjectParam class. The fifth
example has 2 type parameters (see "multiple type parameters" below), choosing the second
parameter as the type parameter passed to the superclass.
Notice that in the Email class, the T getValue() method acts as if it had a signature of String
getValue(), and the void setValue(T) method acts as if it was declared void setValue(String).
It is also possible to instantiate with anonymous inner class with an empty curly braces ({}):
Note that using the diamond with anonymous inner classes is not allowed.
https://riptutorial.com/ 415
Multiple type parameters
Java provides the ability to use more than one type parameter in a generic class or interface.
Multiple type parameters can be used in a class or interface by placing a comma-separated list
of types between the angle brackets. Example:
public T getFirstParam() {
return firstParam;
}
public S getSecondParam() {
return secondParam;
}
https://riptutorial.com/ 416
public void usage() {
List<String> listString = makeList("Jeff", "Atwood");
List<Integer> listInteger = makeList(1, 2);
}
}
Notice that we don't have to pass an actual type argument to a generic method. The compiler
infers the type argument for us, based on the target type (e.g. the variable we assign the result to),
or on the types of the actual arguments. It will generally infer the most specific type argument that
will make the call type-correct.
Sometimes, albeit rarely, it can be necessary to override this type inference with explicit type
arguments:
void usage() {
consumeObjects(this.<Object>makeList("Jeff", "Atwood").stream());
}
It's necessary in this example because the compiler can't "look ahead" to see that Object is desired
for T after calling stream() and it would otherwise infer String based on the makeList arguments.
Note that the Java language doesn't support omitting the class or object on which the method is
called (this in the above example) when type arguments are explicitly provided.
The Diamond
Java SE 7
Java 7 introduced the Diamond1 to remove some boiler-plate around generic class instantiation.
With Java 7+ you can write:
One limitation is for Anonymous Classes, where you still must provide the type parameter in the
instantiation:
https://riptutorial.com/ 417
Comparator<String> caseInsensitiveComparator = new Comparator<>() {
@Override
public int compare(String s1, String s2) {
return s1.compareToIgnoreCase(s2);
}
};
Java SE 8
Although using the diamond with Anonymous Inner Classes is not supported in Java 7 and 8, it
will be included as a new feature in Java 9.
Footnote:
1 - Some people call the <> usage the "diamond operator". This is incorrect. The diamond does not behave as an
operator, and is not described or listed anywhere in the JLS or the (official) Java Tutorials as an operator. Indeed, <>
is not even a distinct Java token. Rather it is a < token followed by a > token, and it is legal (though bad style) to have
whitespace or comments between the two. The JLS and the Tutorials consistently refer to <> as "the diamond", and
that is therefore the correct term for it.
Example: we want to sort a list of numbers but Number doesn't implement Comparable.
In this example T must extend Number and implement Comparable<T> which should fit all "normal"
built-in number implementations like Integer or BigDecimal but doesn't fit the more exotic ones like
Striped64.
Since multiple inheritance is not allowed, you can use at most one class as a bound and it must be
the first listed. For example, <T extends Comparable<T> & Number> is not allowed because
Comparable is an interface, and not a class.
You can restrict the valid types used in a generic class by bounding that type in the class
definition. Given the following simple type hierarchy:
https://riptutorial.com/ 418
}
}
Without bounded generics, we cannot make a container class that is both generic and knows
that each element is an animal:
public AnimalContainer() {
col = new ArrayList<T>();
}
public BoundedAnimalContainer() {
col = new ArrayList<T>();
}
https://riptutorial.com/ 419
// Legal
AnimalContainer<Cat> a = new AnimalContainer<Cat>();
// Legal
AnimalContainer<String> a = new AnimalContainer<String>();
The syntax for Java generics bounded wildcards, representing the unknown type by ? is:
• ? extends Trepresents an upper bounded wildcard. The unknown type represents a type that
must be a subtype of T, or type T itself.
• ? super Trepresents a lower bounded wildcard. The unknown type represents a type that
must be a supertype of T, or type T itself.
Using extends or super is usually better because it makes your code more flexible (as in: allowing
the use of subtypes and supertypes), as you will see below.
class Shoe {}
class IPhone {}
interface Fruit {}
class Apple implements Fruit {}
class Banana implements Fruit {}
class GrannySmith extends Apple {}
https://riptutorial.com/ 420
fruitHelper.eatAll(fruits); // Allowed
Choosing the right T, ? super T or ? extends T is necessary to allow the use with subtypes. The
compiler can then ensure type safety; you should not need to cast (which is not type safe, and
may cause programming errors) if you use them properly.
(Producer has only write access, and Consumer has only read access)
Code that uses generics has many benefits over non-generic code. Below are the main benefits
Elimination of casts
https://riptutorial.com/ 421
The following code snippet without generics requires casting:
When re-written to use generics, the code does not require casting:
Generic parameters can also be bound to more than one type using the T extends Type1 & Type2 &
... syntax.
Let's say you want to create a class whose Generic type should implement both Flushable and
Closeable, you can write
Now, the ExampleClass only accepts as generic parameters, types which implement both Flushable
and Closeable.
ExampleClass<Console> arg4; // Does NOT work because Console only implements Flushable
ExampleClass<ZipFile> arg5; // Does NOT work because ZipFile only implements Closeable
ExampleClass<Flushable> arg2; // Does NOT work because Closeable bound is not satisfied.
ExampleClass<Closeable> arg3; // Does NOT work because Flushable bound is not satisfied.
The class methods can choose to infer generic type arguments as either Closeable or Flushable.
https://riptutorial.com/ 422
Flushable arg1 = param; // Works
Closeable arg2 = param; // Works too.
}
/* You can even invoke the methods of any valid type directly. */
public void test2 (T param) {
param.flush(); // Method of Flushable called on T and works fine.
param.close(); // Method of Closeable called on T and works fine too.
}
}
Note:
You cannot bind the generic parameter to either of the type using OR (|) clause. Only the AND (&)
clause is supported. Generic type can extends only one class and many interfaces. Class must be
placed at the beginning of the list.
The type T is erased. Since, at runtime, the JVM does not know what T originally was, it does not
know which constructor to call.
Workarounds
1. Passing T's class when calling genericMethod:
genericMethod(String.class);
Which throws exceptions, since there is no way to know if the passed class has an
accessible default constructor.
Java SE 8
https://riptutorial.com/ 423
public <T> void genericMethod(Supplier<T> cons) {
T t = cons.get();
}
genericMethod(String::new);
How do you go about using an instance of a (possibly further) inherited generic type within a
method declaration in the generic type itself being declared? This is one of the problems you will
face when you dig a bit deeper into generics, but still a fairly common one.
Assume we have a DataSeries<T> type (interface here), which defines a generic data series
containing values of type T. It is cumbersome to work with this type directly when we want to
perform a lot of operations with e.g. double values, so we define DoubleSeries extends
DataSeries<Double>. Now assume, the original DataSeries<T> type has a method add(values) which
adds another series of the same length and returns a new one. How do we enforce the type of
values and the type of the return to be DoubleSeries rather than DataSeries<Double> in our derived
class?
The problem can be solved by adding a generic type parameter referring back to and extending
the type being declared (applied to an interface here, but the same stands for classes):
Here T represents the data type the series holds, e.g. Double and DS the series itself. An inherited
type (or types) can now be easily implemented by substituting the above mentioned parameter by
a corresponding derived type, thus, yielding a concrete Double-based definition of the form:
At this moment even an IDE will implement the above interface with correct types in place, which,
after a bit of content filling may look like this:
DoubleSeriesImpl(Collection<Double> data) {
this.data = new ArrayList<>(data);
}
@Override
public DoubleSeries add(DoubleSeries values) {
List<Double> incoming = values != null ? values.data() : null;
https://riptutorial.com/ 424
if (incoming == null || incoming.size() != data.size()) {
throw new IllegalArgumentException("bad series");
}
List<Double> newdata = new ArrayList<>(data.size());
for (int i = 0; i < data.size(); i++) {
newdata.add(this.data.get(i) + incoming.get(i)); // beware autoboxing
}
return DoubleSeries.instance(newdata);
}
@Override
public List<Double> data() {
return Collections.unmodifiableList(data);
}
}
As you can see the add method is declared as DoubleSeries add(DoubleSeries values) and the
compiler is happy.
Consider the following generic class Example declared with the formal parameter <T>:
class Example<T> {
public boolean isTypeAString(String s) {
return s instanceof T; // Compilation error, cannot use T as class type here
}
}
This will always give a Compilation error because as soon as the compiler compiles the Java
source into Java bytecode it applies a process known as type erasure, which converts all generic
code into non-generic code, making impossible to distinguish among T types at runtime. The type
used with instanceof has to be reifiable, which means that all information about the type has to be
available at runtime, and this is usually not the case for generic types.
The following class represents what two different classes of Example, Example<String> and
Example<Number>, look like after generics has stripped off by type erasure:
Since types are gone, it's not possible for the JVM to know which type is T.
https://riptutorial.com/ 425
You can always use unbounded wildcard (?) for specifying a type in the instanceof as follows:
The other side of the coin is that using an instance t of T with instanceof is legal, as shown in the
following example:
class Example<T> {
public boolean isTypeAString(T t) {
return t instanceof String; // No compilation error this time
}
}
because after the type erasure the class will look like the following:
Since, even if the type erasure happen anyway, now the JVM can distinguish among different
types in memory, even if they use the same reference type (Object), as the following snippet
shows:
Object obj1 = new String("foo"); // reference type Object, object type String
Object obj2 = new Integer(11); // reference type Object, object type Integer
System.out.println(obj1 instanceof String); // true
System.out.println(obj2 instanceof String); // false, it's an Integer, not a String
https://riptutorial.com/ 426
Below are listed the possible ways to implement it.
Choose a specific type to replace the formal type parameter <T> of MyGenericClass and implement
it, as the following example does:
This class only deals with String, and this means that using MyGenericInterface with different
parameters (e.g. Integer, Object etc.) won't compile, as the following snippet shows:
Declare another generic interface with the formal type parameter <T> which implements
MyGenericInterface, as follows:
Note that a different formal type parameter may have been used, as follows:
Declare a non-generic class which implements MyGenericInteface as a raw type (not using generic
at all), as follows:
This way is not recommended, since it is not 100% safe at runtime because it mixes up raw type
(of the subclass) with generics (of the interface) and it is also confusing. Modern Java compilers
https://riptutorial.com/ 427
will raise a warning with this kind of implementation, nevertheless the code - for compatibility
reasons with older JVM (1.4 or earlier) - will compile.
All the ways listed above are also allowed when using a generic class as a supertype instead of a
generic interface.
The method will compile with a warning. The code is actually more safe than it looks because the
Java runtime will do a cast when you use it:
Here, the cast will work when the returned type is any kind of List (i.e. returning List<String>
would not trigger a ClassCastException; you'd eventually get it when taking elements out of the list).
To work around this problem, you can create an API which uses typed keys:
With this approach, you can't put the wrong type into the map, so the result will always be correct
(unless you accidentally create two keys with the same name but different types).
Related:
• Type-safe Map
Many unbound generic parameters, like those used in a static method, cannot be recovered at
runtime (see Other Threads on Erasure). However there is a common strategy employed for
accessing the type satisfying a generic parameter on a class at runtime. This allows for generic
https://riptutorial.com/ 428
code that depends on access to type without having to thread type information through every call.
Background
Generic parameterization on a class can be inspected by creating an anonymous inner class. This
class will capture the type information. In general this mechanism is referred to as super type
tokens, which are detailed in Neal Gafter's blog post.
Implementations
• Guava's TypeToken
• Spring's ParameterizedTypeReference
• Jackson's TypeReference
Example usage
https://riptutorial.com/ 429
Chapter 63: Getters and Setters
Introduction
This article discusses getters and setters; the standard way to provide access to data in Java
classes.
Examples
Adding Getters and Setters
Encapsulation is a basic concept in OOP. It is about wrapping data and code as a single unit. In
this case, it is a good practice to declare the variables as private and then access them through
Getters and Setters to view and/or modify them.
These private variables cannot be accessed directly from outside the class. Hence they are
protected from unauthorized access. But if you want to view or modify them, you can use Getters
and Setters.
getXxx() method will return the current value of the variable xxx, while you can set the value of the
variable xxx using setXxx().
The naming convention of the methods are (in example variable is called variableName):
https://riptutorial.com/ 430
• boolean variables
Public Getters and Setters are part of the Property definition of a Java Bean.
Setters and Getters allow for an object to contain private variables which can be accessed and
changed with restrictions. For example,
In this Person class, there is a single variable: name. This variable can be accessed using the
getName() method and changed using the setName(String) method, however, setting a name
requires the new name to have a length greater than 2 characters and to not be null. Using a
setter method rather than making the variable name public allows others to set the value of name with
certain restrictions. The same can be applied to the getter method:
In the modified getName() method above, the name is returned only if its length is less than or equal
to 16. Otherwise, "Name is too large" is returned. This allows the programmer to create variables
that are reachable and modifiable however they wish, preventing client classes from editing the
variables unwantedly.
Consider a basic class containing an object with getters and setters in Java:
https://riptutorial.com/ 431
public void setCount(int c) { count = c; }
}
We can't access the count variable because it's private. But we can access the getCount() and the
setCount(int) methods because they are public. To some, this might raise the question; why
introduce the middleman? Why not just simply make they count public?
For all intents and purposes, these two are exactly the same, functionality-wise. The difference
between them is the extensibility. Consider what each class says:
• First: "I have a method that will give you an int value, and a method that will set that value
to another int".
• Second: "I have an int that you can set and get as you please."
These might sound similar, but the first is actually much more guarded in its nature; it only lets you
interact with its internal nature as it dictates. This leaves the ball in its court; it gets to choose how
the internal interactions occur. The second has exposed its internal implementation externally, and
is now not only prone to external users, but, in the case of an API, committed to maintaining that
implementation (or otherwise releasing a non-backward-compatible API).
Lets consider if we want to synchronize access to modifying and accessing the count. In the first,
this is simple:
but in the second example, this is now nearly impossible without going through and modifying
each place where the count variable is referenced. Worse still, if this is an item that you're
providing in a library to be consumed by others, you do not have a way of performing that
modification, and are forced to make the hard choice mentioned above.
So it begs the question; are public variables ever a good thing (or, at least, not evil)?
I'm unsure. On one hand, you can see examples of public variables that have stood the test of
time (IE: the out variable referenced in System.out). On the other, providing a public variable gives
no benefit outside of extremely minimal overhead and potential reduction in wordiness. My
guideline here would be that, if you're planning on making a variable public, you should judge it
against these criteria with extreme prejudice:
1. The variable should have no conceivable reason to ever change in its implementation. This
is something that's extremely easy to screw up (and, even if you do get it right, requirements
can change), which is why getters/setters are the common approach. If you're going to have
https://riptutorial.com/ 432
a public variable, this really needs to be thought through, especially if released in a
library/framework/API.
2. The variable needs to be referenced frequently enough that the minimal gains from reducing
verbosity warrants it. I don't even think the overhead for using a method versus directly
referencing should be considered here. It's far too negligible for what I'd conservatively
estimate to be 99.9% of applications.
There's probably more than I haven't considered off the top of my head. If you're ever in doubt,
always use getters/setters.
https://riptutorial.com/ 433
Chapter 64: Hashtable
Introduction
Hashtable is a class in Java collections which implements Map interface and extends the
Dictionary Class
Examples
Hashtable
import java.util.*;
public class HashtableDemo {
public static void main(String args[]) {
// create and populate hash table
Hashtable<Integer, String> map = new Hashtable<Integer, String>();
map.put(101,"C Language");
map.put(102, "Domain");
map.put(104, "Databases");
System.out.println("Values before remove: "+ map);
// Remove value for key 102
map.remove(102);
System.out.println("Values after remove: "+ map);
}
}
https://riptutorial.com/ 434
Chapter 65: HttpURLConnection
Remarks
• Using HttpUrlConnection on Android requires that you add the Internet permission to your
app (in the AndroidManifest.xml).
• There are also other Java HTTP clients and libraries, such as Square's OkHttp, which are
easier to use, and may offer better performance or more features.
Examples
Get response body from a URL as a String
in.close();
return response.toString();
}
This will download text data from the specified URL, and return it as a String.
https://riptutorial.com/ 435
• Then, create InputStream basing on the response code (for error handling)
• Then, create a BufferedReader which allows us to read text from InputStream we get from the
connection.
Notes:
• This method will throw an IoException in case of failure (such as a network error, or no
internet connection), and it will also throw an unchecked MalformedUrlException if the given
URL is not valid.
• It can be used for reading from any URL which returns text, such as webpages (HTML),
REST APIs which return JSON or XML, etc.
Usage:
Is very simple:
POST data
public static void post(String url, byte [] data, String contentType) throws IOException {
HttpURLConnection connection = null;
OutputStream out = null;
InputStream in = null;
try {
connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestProperty("Content-Type", contentType);
connection.setDoOutput(true);
out = connection.getOutputStream();
out.write(data);
out.close();
in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
in.close();
} finally {
if (connection != null) connection.disconnect();
if (out != null) out.close();
https://riptutorial.com/ 436
if (in != null) in.close();
}
}
This will POST data to the specified URL, then read the response line-by-line.
How it works
• As usual we obtain the HttpURLConnection from a URL.
• Set the content type using setRequestProperty, by default it's application/x-www-form-
urlencoded
• setDoOutput(true) tells the connection that we will send data.
• Then we obtain the OutputStream by calling getOutputStream() and write data to it. Don't forget
to close it after you are done.
• At last we read the server response.
Delete resource
public static void delete (String urlString, String contentType) throws IOException {
HttpURLConnection connection = null;
try {
URL url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setRequestMethod("DELETE");
connection.setRequestProperty("Content-Type", contentType);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) connection.disconnect();
}
}
This will DELETE the resource in the specified URL, then print the response header.
https://riptutorial.com/ 437
How it works
• we obtain the HttpURLConnection from a URL.
• Set the content type using setRequestProperty, by default it's application/x-www-form-
urlencoded
• setDoInput(true) tells the connection that we intend to use the URL connection for input.
• setRequestMethod("DELETE") to perform HTTP DELETE
/**
* Checks if a resource exists by sending a HEAD-Request.
* @param url The url of a resource which has to be checked.
* @return true if the response code is 200 OK.
*/
public static final boolean checkIfResourceExists(URL url) throws IOException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("HEAD");
int code = conn.getResponseCode();
conn.disconnect();
return code == 200;
}
Explanation:
If you are just checking if a resource exists, it better to use a HEAD request than a GET. This
avoids the overhead of transferring the resource.
Note that the method only returns true if the response code is 200. If you anticipate redirect (i.e.
3XX) responses, then the method may need to be enhanced to honor them.
Example:
checkIfResourceExists(new URL("http://images.google.com/")); // true
checkIfResourceExists(new URL("http://pictures.google.com/")); // false
https://riptutorial.com/ 438
Chapter 66: Immutable Class
Introduction
Immutable objects are instances whose state doesn’t change after it has been initialized. For
example, String is an immutable class and once instantiated its value never changes.
Remarks
Some immutable classes in Java:
1. java.lang.String
2. The wrapper classes for the primitive types: java.lang.Integer, java.lang.Byte,
java.lang.Character, java.lang.Short, java.lang.Boolean, java.lang.Long, java.lang.Double,
java.lang.Float
3. Most enum classes are immutable, but this in fact depends on the concrete case.
4. java.math.BigInteger and java.math.BigDecimal (at least objects of those classes
themselves)
5. java.io.File. Note that this represents an object external to the VM (a file on the local
system), which may or may not exist, and has some methods modifying and querying the
state of this external object. But the File object itself stays immutable.
Examples
Rules to define immutable classes
The following rules define a simple strategy for creating immutable objects.
1. Don't provide "setter" methods - methods that modify fields or objects referred to by fields.
2. Make all fields final and private.
3. Don't allow subclasses to override methods. The simplest way to do this is to declare the
class as final. A more sophisticated approach is to make the constructor private and
construct instances in factory methods.
4. If the instance fields include references to mutable objects, don't allow those objects to be
changed:
5. Don't provide methods that modify the mutable objects.
6. Don't share references to the mutable objects. Never store references to external, mutable
objects passed to the constructor; if necessary, create copies, and store references to the
copies. Similarly, create copies of your internal mutable objects when necessary to avoid
returning the originals in your methods.
https://riptutorial.com/ 439
final private int red;
final private int green;
final private int blue;
In this case class Point is mutable and some user can modify state of object of this class.
class Point {
private int x, y;
//...
https://riptutorial.com/ 440
this.center = new Point(center.getX(), center.getY());
this.radius = radius;
}
By having an immutable object, one can ensure that all threads that are looking at the object will
be seeing the same state, as the state of an immutable object will not change.
https://riptutorial.com/ 441
Chapter 67: Immutable Objects
Remarks
Immutable objects have fixed state (no setters), so all state must be known at object creation time.
Although not technically required, it is best practice to make all fields final. This will make the
immutable class thread-safe (cf. Java Concurrency in Practice, 3.4.1).
The examples show several patterns that can assist with achieving this.
Examples
Creating an immutable version of a type using defensive copying.
Some basic types and classes in Java are fundamentally mutable. For example, all array types are
mutable, and so are classes like java.util.Data. This can be awkward in situations where an
immutable type is mandated.
One way to deal with this is to create an immutable wrapper for the mutable type. Here is a simple
wrapper for an array of integers
This class works by using defensive copying to isolate the mutable state (the int[]) from any code
that might mutate it:
• The constructor uses clone() to create a distinct copy of the parameter array. If the caller of
the constructor subsequent changed the parameter array, it would not affect the state of the
ImmutableIntArray.
• The getValue() method also uses clone() to create the array that is returned. If the caller
were to change the result array, it would not affect the state of the ImmutableIntArray.
We could also add methods to ImmutableIntArray to perform read-only operations on the wrapped
array; e.g. get its length, get the value at a particular index, and so on.
Note that an immutable wrapper type implemented this way is not type compatible with the original
https://riptutorial.com/ 442
type. You cannot simply substitute the former for the latter.
An immutable object is an object whose state cannot be changed. An immutable class is a class
whose instances are immutable by design, and implementation. The Java class which is most
commonly presented as an example of immutability is java.lang.String.
A variation on this is to declare the constructor as private and provide a public static factory
method instead.
• Immutability does not prevent object from being nullable; e.g. null can be assigned to a
String variable.
• If an immutable classes properties are declared as final, instances are inherently thread-
safe. This makes immutable classes a good building block for implementing multi-threaded
https://riptutorial.com/ 443
applications.
Using some setters, without setting all needed properties in the constructor(s)
To fix it, simply delete setSurname() and refactor the constructor as follows:
The following snippet shows that the above class is not immutable:
https://riptutorial.com/ 444
Exposing a mutable object of the class in a getter
import java.util.List;
import java.util.ArrayList;
public final class Names {
private final List<String> names;
public Names(List<String> names) {
this.names = new ArrayList<String>(names);
}
public List<String> getNames() {
return names;
}
public int size() {
return names.size();
}
}
Names class seems immutable at the first sight, but it is not as the following code shows:
This happened because a change to the reference List returned by getNames() can modify the
actual list of Names.
To fix this, simply avoid returning references that reference class's mutable objects either by
making defensive copies, as follows:
or by designing getters in way that only other immutable objects and primitives are returned, as
follows:
Injecting constructor with object(s) that can be modified outside the immutable class
This is a variation of the previous flaw. Take a look at the following class:
https://riptutorial.com/ 445
import java.util.List;
public final class NewNames {
private final List<String> names;
public Names(List<String> names) {
this.names = names;
}
public String getName(int index) {
return names.get(index);
}
public int size() {
return names.size();
}
}
As Names class before, also NewNames class seems immutable at the first sight, but it is not, in fact
the following snippet proves the contrary:
To fix this, as in the previous flaw, simply make defensive copies of the object without assigning it
directly to the immutable class, i.e. constructor can be changed as follows:
Person class seems immutable at the first sight, but suppose a new subclass of Person is defined:
https://riptutorial.com/ 446
public void setName(String name) {
newName = name;
}
}
now Person (im)mutability can be exploited through polymorphism by using the new subclass:
To fix this, either mark the class as final so it cannot be extended or declare all of its
constructor(s) as private.
https://riptutorial.com/ 447
Chapter 68: Inheritance
Introduction
Inheritance is a basic object oriented feature in which one class acquires and extends upon the
properties of another class, using the keyword extends. For Interfaces and the keyword implements,
see interfaces.
Syntax
• class ClassB extends ClassA {...}
• class ClassB implements InterfaceA {...}
• interface InterfaceB extends InterfaceA {...}
• class ClassB extends ClassA implements InterfaceC, InterfaceD {...}
• abstract class AbstractClassB extends ClassA {...}
• abstract class AbstractClassB extends AbstractClassA {...}
• abstract class AbstractClassB extends ClassA implements InterfaceC, InterfaceD {...}
Remarks
Inheritance is often combined with generics so that the base class has one or more type
parameters. See Creating a Generic Class.
Examples
Abstract Classes
An abstract class is a class marked with the abstract keyword. It, contrary to non-abstract class,
may contain abstract - implementation-less - methods. It is, however, valid to create an abstract
class without abstract methods.
An abstract class cannot be instantiated. It can be sub-classed (extended) as long as the sub-
class is either also abstract, or implements all methods marked as abstract by super classes.
https://riptutorial.com/ 448
The class must be marked abstract, when it has at least one abstract method. An abstract method
is a method that has no implementation. Other methods can be declared within an abstract class
that have implementation in order to provide common code for any sub-classes.
However a class that extends Component, and provides an implementation for all of its abstract
methods and can be instantiated.
@Override
public void render() {
//render a button
}
}
@Override
public void render() {
//render a textbox
}
}
Instances of inheriting classes also can be cast as the parent class (normal inheritance) and they
provide a polymorphic effect when the abstract method is called.
Abstract classes and interfaces both provide a way to define method signatures while requiring the
extending/implementing class to provide the implementation.
There are two key differences between abstract classes and interfaces:
• A class may only extend a single class, but may implement many interfaces.
• An abstract class can contain instance (non-static) fields, but interfaces may only contain
static fields.
Java SE 8
Methods declared in interfaces could not contain implementations, so abstract classes were used
when it was useful to provide additional methods which implementations called the abstract
https://riptutorial.com/ 449
methods.
Java SE 8
Java 8 allows interfaces to contain default methods, usually implemented using the other methods
of the interface, making interfaces and abstract classes equally powerful in this regard.
Static Inheritance
Static method can be inherited similar to normal methods, however unlike normal methods it is
impossible to create "abstract" methods in order to force static method overriding. Writing a
method with the same signature as a static method in a super class appears to be a form of
overriding, but really this simply creates a new function hides the other.
SubClass.sayHello();
//This will be different than the above statement's output, since it runs
//A different method
SubClass.sayHello(true);
StaticOverride.sayHello();
System.out.println("StaticOverride's num: " + StaticOverride.num);
}
}
https://riptutorial.com/ 450
}
Hello
BaseClass's num: 5
Hello
Hey
Static says Hi
StaticOverride's num: test
Note that unlike normal inheritance, in static inheritance methods are not hidden. You can always
call the base sayHello method by using BaseClass.sayHello(). But classes do inherit static methods
if no methods with the same signature are found in the subclass. If two method's signatures vary,
both methods can be run from the subclass, even if the name is the same.
Final classes
When used in a class declaration, the final modifier prevents other classes from being declared
that extend the class. A final class is a "leaf" class in the inheritance class hierarchy.
https://riptutorial.com/ 451
a class. This can be used to create a so-called "utility class" that only defines static members; i.e.
constants and static methods.
Immutable classes should also be declared as final. (An immutable class is one whose instances
cannot be changed after they have been created; see the Immutable Objects topic. ) By doing this,
you make it impossible to create a mutable subclass of an immutable class. That would violate the
Liskov Substitution Principle which requires that a subtype should obey the "behavioral contract"
of its supertypes.
From a practical perspective, declaring an immutable class to be final makes it easier to reason
about program behavior. It also addresses security concerns in the scenario where untrusted code
is executed in a security sandbox. (For instance, since String is declared as final, a trusted class
does not need to worry that it might be tricked into accepting mutable subclass, which the
untrusted caller could then surreptitiously change.)
One disadvantage of final classes is that they do not work with some mocking frameworks such
as Mockito. Update: Mockito version 2 now support mocking of final classes.
Final methods
The final modifier can also be applied to methods to prevent them being overridden in sub-
classes:
@Override
public void someMethod() { // Compiler error (overridden method is final)
}
}
Final methods are typically used when you want to restrict what a subclass can change in a class
without forbidding subclasses entirely.
https://riptutorial.com/ 452
The final modifier can also be applied to variables, but the meaning of final for variables is
unrelated to inheritance.
class A {...}
class B extends A {...}
This also applies when the type is an interface, where there doesn't need to any hierarchical
relationship between the objects:
interface Foo {
void bar();
}
Now the list contains objects that are not from the same class hierarchy.
Inheritance
With the use of the extends keyword among classes, all the properties of the superclass (also
known as the Parent Class or Base Class) are present in the subclass (also known as the Child
Class or Derived Class)
https://riptutorial.com/ 453
Instances of SubClass have inherited the method baseMethod():
Additional content can be added to a subclass. Doing so allows for additional functionality in the
subclass without any change to the base class or any other subclasses from that same base
class:
public int x;
public SubClassWithField(int x) {
this.x = x; //Can access fields
}
}
private fields and methods still exist within the subclass, but are not accessible:
private int x = 5;
https://riptutorial.com/ 454
In Java, each class may extend at most one other class.
This is known as multiple inheritance, and while it is legal in some languages, Java does not
permit it with classes.
As a result of this, every class has an unbranching ancestral chain of classes leading to Object,
from which all classes descend.
In Java, parent and child class both can have static methods with the same name. But in such
cases implementation of static method in child is hiding parent class' implementation, it's not
method overriding. For example:
class StaticMethodTest {
Static methods are bind to a class not to an instance and this method binding happens at compile
time. Since in the first call to staticMethod(), parent class reference p was used, Parent's version of
staticMethod() is invoked. In second case, we did cast p into Child class, Child's staticMethod()
executed.
Variable shadowing
Variables are SHADOWED and methods are OVERRIDDEN. Which variable will be used depends
on the class that the variable is declared of. Which method will be used depends on the actual
class of the object that is referenced by the variable.
class Car {
https://riptutorial.com/ 455
public int gearRatio = 8;
Casting an instance of a base class to a subclass as in : b = (B) a; is called narrowing (as you are
trying to narrow the base class object to a more specific class object) and needs an explicit type-
cast.
Casting an instance of a subclass to a base class as in: A a = b; is called widening and does not
need a type-cast.
class Vehicle {
}
class Test {
https://riptutorial.com/ 456
vehicle = car; // is valid, no cast needed
The statement Vehicle vehicle = new Car(); is a valid Java statement. Every instance of Car is also
a Vehicle. Therefore, the assignment is legal without the need for an explicit type-cast.
On the other hand, Car c = vehicle; is not valid. The static type of the vehicle variable is Vehicle
which means that it could refer to an instance of Car, Truck,MotorCycle, or any other current or
future subclass ofVehicle. (Or indeed, an instance ofVehicleitself, since we did not declare it
as anabstractclass.) The assignment cannot be allowed, since that might lead tocarreferring to a
Truck` instance.
The type-cast tells the compiler that we expect the value of vehicle to be a Car or a subclass of Car
. If necessary, compiler will insert code to perform a run-time type check. If the check fails, then a
ClassCastException will be thrown when the code is executed.
The Java compiler knows that an instance that is type compatible with Vehicle cannot ever be type
compatible with String. The type-cast could never succeed, and the JLS mandates that this gives
in a compilation error.
Programming to an interface
The idea behind programming to an interface is to base the code primarily on interfaces and only
use concrete classes at the time of instantiation. In this context, good code dealing with e.g. Java
collections will look something like this (not that the method itself is of any use at all, just
illustration):
https://riptutorial.com/ 457
Not only the former can be applied to a wider choice of arguments, its results will be more
compatible with code provided by other developers that generally adhere to the concept of
programming to an interface. However, the most important reasons to use the former are:
• most of the time the context, in which the result is used, does not and should not need that
many details as the concrete implementation provides;
• adhering to an interface forces cleaner code and less hacks such as yet another public
method gets added to a class serving some specific scenario;
• the code is more testable as interfaces are easily mockable;
• finally, the concept helps even if only one implementation is expected (at least for testability).
So how can one easily apply the concept of programming to an interface when writing new code
having in mind one particular implementation? One option that we commonly use is a combination
of the following patterns:
• programming to an interface
• factory
• builder
The following example based on these principles is a simplified and truncated version of an RPC
implementation written for a number of different protocols:
The above interface is not supposed to be instantiated directly via a factory, instead we derive
further more concrete interfaces, one for HTTP invocation and one for AMQP, each then having a
factory and a builder to construct instances, which in turn are also instances of the above
interface:
Instances of RemoteInvoker for the use with AMQP can now be constructed as easy as (or more
involved depending on the builder):
Due to Java 8 permitting placing of static methods directly into interfaces, the intermediate factory
https://riptutorial.com/ 458
has become implicit in the above code replaced with AmqpInvoker.with(). In Java prior to version 8,
the same effect can be achieved with an inner Factory class:
The builder used above could look like this (although this is a simplification as the actual one
permits defining of up to 15 parameters deviating from defaults). Note that the construct is not
public, so it is specifically usable only from the above AmqpInvoker interface:
Finally, the standard (and the only expected) implementation of this interface is defined as a
package-local class to enforce the use of the interface, the factory and the builder:
@Override
public <RQ, RS> CompletableFuture<RS> invoke(final RQ request, final Class<RS> respClass) {
...
}
}
https://riptutorial.com/ 459
Meanwhile, this pattern proved to be very efficient in developing all our new code not matter how
simple or complex the functionality is.
When to use abstract classes: To implement the same or different behaviour among multiple
related objects
Abstract classes create "is a" relations while interfaces provide "has a" capability.
System.out.println("Dog:"+dog);
System.out.println("Cat:"+cat);
dog.remember();
dog.protectOwner();
Learn dl = dog;
dl.learn();
cat.remember();
cat.protectOwner();
Climb c = cat;
c.climb();
Climb cm = man;
cm.climb();
Think t = man;
t.think();
Learn l = man;
l.learn();
Apply a = man;
a.apply();
}
}
https://riptutorial.com/ 460
public String toString(){
return this.getClass().getSimpleName()+":"+name+":"+lifeExpentency;
}
}
class Dog extends Animal implements Learn{
interface Learn {
void learn();
}
interface Apply{
void apply();
}
https://riptutorial.com/ 461
public void apply(){
System.out.println("I can apply:"+this.getClass().getSimpleName());
}
public void climb(){
System.out.println("I can climb:"+this.getClass().getSimpleName());
}
public String toString(){
return "Man :"+name+":Age:"+age;
}
}
output:
Dog:Dog:Jack:16
Cat:Cat:Joe:20
Dog can remember for 5 minutes
Dog will protect owner
Dog can learn:
Cat can remember for 16 hours
Cat won't protect owner
Cat can climb
Man :Ravindra:Age:40
I can climb:Man
I can think:Man
I can learn:Man
I can apply:Man
Key notes:
1. Animal is an abstract class with shared attributes: name and lifeExpectancy and abstract
methods: remember() and protectOwner(). Dog and Cat are Animals that have implemented the
remember() and protectOwner() methods.
2. Cat can climb() but Dog cannot. Dog can think() but Cat cannot. These specific capabilities are
added to Cat and Dog by implementation.
3. Man is not an Animal but he can Think , Learn, Apply, and Climb.
6. Man is neither a Cat nor a Dog but can have some of the capabilities of the latter two without
extending Animal, Cat, or Dog. This is done with Interfaces.
TL;DR:
Unrelated classes can have capabilities through interfaces, but related classes change the
behaviour through extension of base classes.
Refer to the Java documentation page to understand which one to use in a specific use case.
https://riptutorial.com/ 462
Consider using abstract classes if...
1. You expect that unrelated classes would implement your interface. For example, many
unrelated objects can implement the Serializable interface.
2. You want to specify the behaviour of a particular data type but are not concerned about who
implements its behaviour.
3. You want to take advantage of multiple inheritance of type.
Overriding in Inheritance
Overriding in Inheritance is used when you use a already defined method from a super class in a
sub class, but in a different way than how the method was originally designed in the super class.
Overriding allows the user to reuse code by using existing material and modifying it to suit the
user's needs better.
The following example demonstrates how ClassB overrides the functionality of ClassA by changing
what gets sent out through the printing method:
Example:
class ClassA {
public void printing() {
System.out.println("A");
}
}
Output:
https://riptutorial.com/ 463
Read Inheritance online: https://riptutorial.com/java/topic/87/inheritance
https://riptutorial.com/ 464
Chapter 69: InputStreams and OutputStreams
Syntax
• int read(byte[] b) throws IOException
Remarks
Note that most of the time you do NOT use InputStreams directly but use BufferedStreams, or
similar. This is because InputStream reads from the source every time the read method is called.
This can cause significant CPU usage in context switches into and out of the kernel.
Examples
Reading InputStream into a String
Sometimes you may wish to read byte-input into a String. To do this you will need to find
something that converts between byte and the "native Java" UTF-16 Codepoints used as char.
That is done with a InputStreamReader.
To speed the process up a bit, it's "usual" to allocate a buffer, so that we don't have too much
overhead when reading from Input.
Java SE 7
Transforming this example to Java SE 6 (and lower)-compatible code is left out as an exercise for
the reader.
https://riptutorial.com/ 465
byte b = 0x00;
stream.write( b );
stream.write( bytes );
int offset = 1;
int length = 2;
byte[] bytes = new byte[] { 0xFF, 0x00, 0x00, 0xFF };
Closing Streams
Most streams must be closed when you are done with them, otherwise you could introduce a
memory leak or leave a file open. It is important that streams are closed even if an exception is
thrown.
Java SE 7
Remember: try-with-resources guarantees, that the resources have been closed when the block is
exited, whether that happens with the usual control flow or because of an exception.
Java SE 6
Sometimes, try-with-resources is not an option, or maybe you're supporting older version of Java 6
or earlier. In this case, proper handling is to use a finally block:
FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter out = null;
try {
fw = new FileWriter("myfile.txt");
bw = new BufferedWriter(fw);
out = new PrintWriter(bw);
https://riptutorial.com/ 466
out.println("the text");
out.close();
} catch (IOException e) {
//handle this however you want
}
finally {
try {
if(out != null)
out.close();
} catch (IOException e) {
//typically not much you can do here...
}
}
Note that closing a wrapper stream will also close its underlying stream. This means you cannot
wrap a stream, close the wrapper and then continue using the original stream.
Example -
OutputStream and InputStream have many different classes, each of them with a unique
functionality. By wrapping a stream around another, you gain the functionality of both streams.
You can wrap a stream any number of times, just take note of the ordering.
Useful combinations
Writing characters to a file while using a buffer
Compressing and encrypting data before writing to a file while using a buffer
https://riptutorial.com/ 467
File myFile = new File("targetFile.enc");
BufferedOutputStream outputStream = new BufferedOutputStream(new DeflaterOutputStream(new
CipherOutputStream(new FileOutputStream(myFile), cipher)));
DeflaterOutputStream/
Performs data compression.
DeflaterInputStream
InflaterOutputStream/
Performs data decompression.
InflaterInputStream
CipherOutputStream/
Encrypts/Decrypts data.
CipherInputStream
DigestOutputStream/
Generates Message Digest to verify data integrity.
DigestInputStream
DataOutputStream/ Allows writing of primitive data types and Strings. Meant for
DataInputStream writing bytes. Platform independent.
DataInputStream Example
package com.streams;
import java.io.*;
public class DataStreamDemo {
public static void main(String[] args) throws IOException {
InputStream input = new FileInputStream("D:\\datastreamdemo.txt");
DataInputStream inst = new DataInputStream(input);
https://riptutorial.com/ 468
int count = input.available();
byte[] arr = new byte[count];
inst.read(arr);
for (byte byt : arr) {
char ki = (char) byt;
System.out.print(ki+"-");
}
}
}
https://riptutorial.com/ 469
Chapter 70: Installing Java (Standard Edition)
Introduction
This documentation page gives access to instructions for installing java standard edition on
Windows, Linux, and macOS computers.
Examples
Setting %PATH% and %JAVA_HOME% after installing on Windows
Assumptions:
• An Oracle JDK has been installed.
• The JDK was installed to the default directory.
Setup steps
1. Open Windows Explorer.
2. In the navigation pane on the left right click on This PC (or Computer for older Windows
versions). There is a shorter way without using the explorer in actual Windows versions: Just
press Win+Pause
3. In the newly opened Control Panel window, left click Advanced System Settings which
should be in the top left corner. This will open the System Properties window.
Alternatively, type SystemPropertiesAdvanced (case insensitive) in the Run (Win+R), and hit
Enter.
4. In the Advanced tab of System Properties select the Environment Variables... button in the
lower right corner of the window.
5. Add a New System Variable by clicking the New... button in System Variables with the
https://riptutorial.com/ 470
name JAVA_HOME and whose value is the path to the directory where the JDK was installed.
After entering these values, press OK.
6. Scroll down the list of System Variables and select the Path variable.
It is better to append at the begining of the line because Oracle's software used to register their
own version of Java in Path - This will cause your version to be ignored if it occurs after Oracle's
declaration.
Note: If you have to try again, close the prompt before checking your work. This will force windows
to get the new version of Path.
There have been many releases of Java since the original Java 1.0 release in 1995. (Refer to
Java version history for a summary.) However most releases have passed their official End Of Life
dates. This means that the vendor (typically Oracle now) has ceased new development for the
release, and no longer provides public / free patches for any bugs or security issues. (Private
patch releases are typically available for people / organizations with a support contract; contact
your vendor's sales office.)
In general, the recommended Java SE release for use will be the latest update for the latest public
version. Currently, this means the latest available Java 8 release. Java 9 is due for public release
in 2017. (Java 7 has passed its End Of Life and the last public release was in April 2015. Java 7
and earlier releases are not recommended.)
This recommendation applies for all new Java development, and anyone learning Java. It also
https://riptutorial.com/ 471
applies to people who just want to run Java software provided by a third-party. Generally
speaking, well-written Java code will work on a newer release of Java. (But check the software's
release notes, and contact the author / supplier / vendor if you have doubts.)
If you are working on an older Java codebase, you would be advised to ensure that your code
runs on the latest release of Java. Deciding when to start using the features of newer Java
releases is more difficult, as this will impact your ability to support customers who are unable or
unwilling their Java installation.
Java release naming is a little confusing. There are actually two systems of naming and
numbering, as shown in this table:
... ...
jdk-1.6 Java SE 6
jdk-1.7 Java SE 7
jdk-1.8 Java SE 8
1 - It appears that Oracle intends to break from their previous practice of using a "semantic version number" scheme
in the Java version strings. It remains to be seen if they will follow through with this.
The "SE" in the marketing names refers to Standard Edition. This is the base release for running
Java on most laptops, PCs and servers (apart from Android).
There are two other official editions of Java: "Java ME" is the Micro Edition, and "Java EE" is the
Enterprise Edition. The Android flavor of Java is also significantly different from Java SE. Java ME,
Java EE and Android Java are outside of the scope of this Topic.
The full version number for a Java release looks like this:
1.8.0_101-b13
This says JDK 1.8.0, Update 101, Build #13. Oracle refers to this in the release notes as:
https://riptutorial.com/ 472
Java™ SE Development Kit 8, Update 101 (JDK 8u101)
The update number is important -- Oracle regularly issue updates to a major release with security
patches, bug fixes and (in some cases) new features. The build number is usually irrelevant. Note
that Java 8 and Java 1.8 refer to the same thing; Java 8 is just the "marketing" name for Java 1.8.
A JDK installation and a text editor are the bare minimum for Java development. (It is nice to have
a text editor that can do Java syntax highlighting, but you can do without.)
However for serious development work it is recommended that you also use the following:
As a general rule, the procedure is to open terminal window and run the commands shown below.
(It is assumed that you have sufficient access to run commands as the "root" user ... which is what
the sudo command does. If you do not, then please talk to your system's administrators.)
Using the package manager is recommended because it (generally) makes it easier to keep your
Java installation up to date.
Note: To automatically set up the Java 8 environment variables, you can install the following
package:
https://riptutorial.com/ 473
If you prefer to create the .deb file yourself from the .tar.gz file downloaded from Oracle, do the
following (assuming you've downloaded the .tar.gz to ./<jdk>.tar.gz):
dnf, Fedora
In recent Fedora releases, there are no packages for installing Java 7 and earlier.
Gentoo Linux
The Gentoo Java guide is maintained by the Gentoo Java team and keeps an updated wiki page
including the correct portage packages and USE flags needed.
1. Download the appropriate Oracle archive ("tar.gz") file for the desired release from the
Oracle Java downloads site.
2. Change directory to the place where you want to put the installation;
https://riptutorial.com/ 474
Installing from an Oracle Java RPM file.
1. Retrieve the required RPM file for the desired release from the Oracle Java downloads site.
Only Oracle JDKs and JREs are available for Windows platforms. The installation procedure is
straight-forward:
An alternate way to install Java on Windows using the command prompt is to use Chocolately:
2. Open a cmd instance, for example hit Win+R and then type "cmd" in the "Run" window
followed by an enter.
3. In your cmd instance, run the following command to download and install a Java 8 JDK:
There are instances where you might want to install JDK/JRE on a system with limited privileges
like a VM or you might want to install and use multiple versions or architectures (x64/x86) of
JDK/JRE. The steps remain same till the point you download the installer (.EXE). The steps after
that are as follows (The steps are applicable for JDK/JRE 7 and above, for older versions they are
slightly different in the names of folders and files):
1. Move the file to an appropriate location where you would want your Java binaries to reside
permanently.
3. With 7-Zip, extract the files from the Java installer EXE to the location.
https://riptutorial.com/ 475
4. Open up command prompt there by holding Shift and Right-Clicking in the folder in explorer
or navigate to that location from anywhere.
5. Navigate to the newly created folder. Let's say the folder name is jdk-7u25-windows-x64. So
type cd jdk-7u25-windows-x64. Then type the following commands in order :
cd .rsrc\JAVA_CAB10
extrac32 111
6. This will create a tools.zip file in that location. Extract the tools.zip with 7-Zip so that the
files inside it are now created under tools in the same directory.
cd tools
8. Wait for the command to complete. Copy the contents of tools to the location where you
want your binaries to be.
This way, you can install any versions of JDK/JRE you need to be installed simultaneously.
Java 7 and Java 8 for macOS are available from Oracle. This Oracle page answers a lot of
questions about Java for Mac. Note that Java 7 prior to 7u25 have been disabled by Apple for
security reasons.
In general, Oracle Java (Version 7 and later) requires an Intel-based Mac running macOS 10.7.3
or later.
Java 7 & 8 JDK and JRE installers for macOS can be downloaded from Oracle’s website:
After downloading the relevant package, double click on the package and go through the normal
installation process. A JDK should get installed here:
/Library/Java/JavaVirtualMachines/<version>.jdk/Contents/Home
Command-Line Switching
https://riptutorial.com/ 476
When Java is installed, the installed version is automatically set as the default. To switch between
different, use:
The following functions can be added to the ~/.bash_profile (If you use the default Bash shell) for
ease of use:
function java_version {
echo 'java -version';
}
function java_set {
if [[ $1 == "6" ]]
then
export JAVA_HOME='/usr/libexec/java_home -v 1.6';
echo "Setting Java to version 6..."
echo "$JAVA_HOME"
elif [[ $1 == "7" ]]
then
export JAVA_HOME='/usr/libexec/java_home -v 1.7';
echo "Setting Java to version 7..."
echo "$JAVA_HOME"
elif [[ $1 == "8" ]]
then
export JAVA_HOME='/usr/libexec/java_home -v 1.8';
echo "Setting Java to version 8..."
echo "$JAVA_HOME"
fi
}
On older versions of macOS (10.11 El Capitan and earlier), Apple's release of Java 6 comes pre-
installed. If installed, it can be be found at this location:
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
Note that Java 6 passed its end-of-life long ago, so upgrading to a newer version is
recommended. There is more information on reinstalling Apple Java 6 on the Oracle website.
Using Alternatives
Many Linux distributions use the alternatives command for switching between different versions of
a command. You can use this for switching between different versions of Java installed on a
machine.
1. In a command shell, set $JDK to the pathname of a newly installed JDK; e.g.
https://riptutorial.com/ 477
$ JDK=/Data/jdk1.8.0_67
2. Use alternatives --install to add the commands in the Java SDK to alternatives:
And so on.
Now you can switch between different versions of a Java command as follows:
Selection Command
-----------------------------------------------
*+ 1 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.101-1.b14.fc23.x86_64/bin/javac
2 /Data/jdk1.8.0_67/bin/javac
For more information on using alternatives, refer to the alternatives(8) manual entry.
$ archlinux-java status
Available Java environments:
java-7-openjdk (default)
java-8-openjdk/jre
Eg:
https://riptutorial.com/ 478
Post-installation checking and configuration on Linux
After installing a Java SDK, it is advisable to check that it is ready to use. You can do this by
running these two commands, using your normal user account:
$ java -version
$ javac -version
These commands print out the version information for the JRE and JDK (respectively) that are on
your shell's command search path. Look for the JDK / JRE version string.
• If either of the above commands fails, saying "command not found", then the JRE or JDK is
not on the search path at all; go to Configuring PATH directly below.
• If either of the above commands displays a different version string to what you were
expecting, then either your search path or the "alternatives" system needs adjusting; go to
Checking Alternatives
• If the correct version strings are displayed, you are nearly done; skip to Checking
JAVA_HOME
If there is no java or javac on the search path at the moment, then the simple solution is to add it to
your search path.
First, find where you installed Java; see Where was Java installed? below if you have doubts.
Next, assuming that bash is your command shell, use a text editor to add the following lines to the
end of either ~/.bash_profile or ~/.bashrc (If you use Bash as your shell).
JAVA_HOME=<installation directory>
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME
export PATH
... replacing <installation directory> with the pathname for your Java installation directory. Note
that the above assumes that the installation directory contains a bin directory, and the bin directory
contains the java and javac commands that you are trying to use.
Next, source the file that you just edited, so that the environment variables for your current shell
are updated.
$ source ~/.bash_profile
Next, repeat the java and javac version checks. If there are still problems, use which java and which
javac to verify that you have updates the environment variables correctly.
Finally, logout and login again so that the updated environment variables ptopagate to all of your
https://riptutorial.com/ 479
shells. You should now be done.
Checking Alternatives
If java -version or javac -version worked but gave an unexpected version number, you need to
check where the commands are coming from. Use which and ls -l to find this out as follows:
$ ls -l `which java`
then the alternatives version switching is being used. You needs to decide whether to continue
using it, or simply override it by setting the PATH directly.
If you are having difficultly finding the installation directory, We suggest that you use find (or
slocate) to find the command. For example:
This gives you the pathnames for all files called java on your system. (The redirection of standard
error to "/dev/null" suppresses messages about files and directories that you can't access.)
Follow the below steps to install Oracle JDK from the latest tar file:
1. Download the latest tar file from here - Current latest is Java SE Development Kit 8u112.
sudo su
https://riptutorial.com/ 480
mkdir /opt/jdk
ls /opt/jdk
and
java -version
Expected output:
https://riptutorial.com/ 481
Chapter 71: Interfaces
Introduction
An interface is a reference type, similar to a class, which can be declared by using interface
keyword. Interfaces can contain only constants, method signatures, default methods, static
methods, and nested types. Method bodies exist only for default methods and static methods. Like
abstract classes, Interfaces cannot be instantiated—they can only be implemented by classes or
extended by other interfaces. Interface is a common way to achieve full abstraction in Java.
Syntax
• public interface Foo { void foo(); /* any other methods */ }
• public interface Foo1 extends Foo { void bar(); /* any other methods */ }
• public class Foo2 implements Foo, Foo1 { /* implementation of Foo and Foo1 */ }
Examples
Declaring and Implementing an Interface
Override Annotation
@Override
public String getSound() {
// Code goes here...
}
This forces the compiler to check that we are overriding and prevents the program from defining a
new method or messing up the method signature.
@Override
public String getSound() {
return "meow";
}
}
https://riptutorial.com/ 482
@Override
public String getSound() {
return "woof";
}
}
In the example, classes Cat and Dog must define the getSound() method as methods of an interface
are inherently abstract (with the exception of default methods).
@Override
public void eat(Food food) {
System.out.println("meows appreciatively");
}
}
Notice how the Cat class must implement the inherited abstract methods in both the interfaces.
Furthermore, notice how a class can practically implement as many interfaces as needed (there is
a limit of 65,535 due to JVM Limitation).
https://riptutorial.com/ 483
Note:
Extending an interface
Now a class implementing ExtendedResourceService will need to implement both getResource() and
updateResource().
Unlike classes, the extends keyword can be used to extend multiple interfaces (Separated by
commas) allowing for combinations of interfaces into a new interface
https://riptutorial.com/ 484
Let's say you want to define an interface that allows publishing / consuming data to and from
different types of channels (e.g. AMQP, JMS, etc), but you want to be able to switch out the
implementation details ...
Let's define a basic IO interface that can be re-used across multiple implementations:
Now I can instantiate that interface, but since we don't have default implementations for those
methods, it'll need an implementation when we instantiate it:
@Override
public void publish(String data) {
System.out.println("Publishing " + data + " to " + channel);
}
@Override
public String consume() {
System.out.println("Consuming from " + channel);
return "some useful data";
}
@Override
public String RPCSubmit(String data) {
return "received " + data + " just now ";
}
};
We can also do something more useful with that interface, let's say we want to use it to wrap some
basic RabbitMQ functions:
https://riptutorial.com/ 485
@Override
public void publish(String data) {
rabbit.basicPublish(exchange, queue, data.getBytes());
}
@Override
public String consume() {
return rabbit.basicConsume(exchange, queue);
}
@Override
public String RPCSubmit(String data) {
return rabbit.rpcPublish(exchange, queue, data);
}
Let's say I want to use this IO interface now as a way to count visits to my website since my last
system restart and then be able to display the total number of visits - you can do something like
this:
import java.util.concurrent.atomic.AtomicLong;
@Override
public void publish(Integer count) {
websiteCounter.addAndGet(count);
}
@Override
public Long consume() {
return websiteCounter.get();
}
@Override
public Long RPCSubmit(Integer count) {
return websiteCounter.addAndGet(count);
}
// show data for stats counter page, but include that as a page view
System.out.println(counter.RPCSubmit(1)); // prints 6
https://riptutorial.com/ 486
When implementing multiple interfaces, you can't implement the same interface twice. That also
applies to generic interfaces. Thus, the following code is invalid, and will result in a compile error:
interface Printer<T> {
void print(T value);
}
// Invalid!
class SystemPrinter implements Printer<Double>, Printer<Integer> {
@Override public void print(Double d){ System.out.println("Decimal: " + d); }
@Override public void print(Integer i){ System.out.println("Discrete: " + i); }
}
Usefulness of interfaces
Interfaces can be extremely helpful in many cases. For example, say you had a list of animals and
you wanted to loop through the list, each printing the sound they make.
One way to do this would be to use interfaces. This would allow for the same method to be called
on all of the classes
Any class that implements Animal also must have a getSound() method in them, yet they can all
have different implementations
We now have three different classes, each of which has a getSound() method. Because all of these
classes implement the Animal interface, which declares the getSound() method, any instance of an
Animal can have getSound() called on it
https://riptutorial.com/ 487
Animal dog = new Dog();
Animal cat = new Cat();
Animal bird = new Bird();
dog.getSound(); // "Woof"
cat.getSound(); // "Meow"
bird.getSound(); // "Chirp"
Because each of these is an Animal, we could even put the animals in a list, loop through them,
and print out their sounds
Because the order of the array is Dog, Cat, and then Bird, "Woof Meow Chirp" will be printed to the
console.
Interfaces can also be used as the return value for functions. For example, returning a Dog if the
input is "dog", Cat if the input is "cat", and Bird if it is "bird", and then printing the sound of that
animal could be done using
Interfaces are also useful for extensibility, because if you want to add a new type of Animal, you
wouldn't need to change anything with the operations you perform on them.
https://riptutorial.com/ 488
A method defined in an interface is by default public abstract. When an abstract class
implements an interface, any methods which are defined in the interface do not have to be
implemented by the abstract class. This is because a class that is declared abstract can contain
abstract method declarations. It is therefore the responsibility of the first concrete sub-class to
implement any abstract methods inherited from any interfaces and/or the abstract class.
@Override
public void eat() {
System.out.println("Dog eats some kibble.");
}
}
From Java 8 onward it is possible for an interface to declare default implementations of methods
which means the method won't be abstract, therefore any concrete sub-classes will not be forced
to implement the method but will inherit the default implementation unless overridden.
Default methods
interface Observer {
void onAction(String a);
}
interface Observable{
public abstract List<Observer> getObservers();
https://riptutorial.com/ 489
}
Now, any class can be made "Observable" just by implementing the Observable interface, while
being free to be part of a different class hierarchy.
@Override
public List<Observer> getObservers() {
return myObservers;
}
@Override
public void work(){
notify("Started work");
notify("Completed work");
}
w.addListener(new Observer() {
@Override
public void onAction(String a) {
System.out.println(a + " (" + new Date() + ")");
}
});
w.work();
}
}
Diamond problem
The compiler in Java 8 is aware of the diamond problem which is caused when a class is
implementing interfaces containing a method with the same signature.
In order to solve it, an implementing class must override the shared method and provide its own
implementation.
https://riptutorial.com/ 490
interface InterfaceA {
public default String getName(){
return "a";
}
}
interface InterfaceB {
public default String getName(){
return "b";
}
}
@Override
public String getName() {
//Must provide its own implementation
return InterfaceA.super.getName() + InterfaceB.super.getName();
}
There's still the issue of having methods with the same name and parameters with different return
types, which will not compile.
To avoid breaking up the entire system, you can provide a default method implementation when
you add a method to an interface. This way, the system will still compile and the actual
implementations can be done step by step.
Modifiers in Interfaces
(See Modifiers in Oracle Official Code Standard for the context and a link to the actual Oracle
https://riptutorial.com/ 491
document.)
This style guidance applies particularly to interfaces. Let's consider the following code snippet:
interface I {
public static final int VARIABLE = 0;
Variables
All interface variables are implicitly constants with implicit public (accessible for all), static (are
accessible by interface name) and final (must be initialized during declaration) modifiers:
Methods
1. All methods which don't provide implementation are implicitly public and abstract.
Java SE 8
2. All methods with static or default modifier must provide implementation and are implicitly
public.
After all of the above changes have been applied, we will get the following:
interface I {
int VARIABLE = 0;
void method();
Bounded type parameters allow you to set restrictions on generic type arguments:
https://riptutorial.com/ 492
class SomeClass {
An interface type can be bound to a type that already had a binding. This is achieved using the &
symbol:
interface SomeInterface {
This strengthens the bind, potentially requiring type arguments to derive from multiple types.
But should be used with caution. Multiple interface bindings is usually a sign of a code smell,
suggesting that a new type should be created which acts as an adapter for the other types:
https://riptutorial.com/ 493
Chapter 72: Iterator and Iterable
Introduction
The java.util.Iterator is the standard Java SE interface for object that implement the Iterator
design pattern. The java.lang.Iterable interface is for objects that can provide an iterator.
Remarks
It is possible to iterate over an array using the for-each loop, though java arrays do not implement
Iterable; iterating is done by JVM using a non-accessible index in the background.
Examples
Using Iterable in for loop
Classes implementing Iterable<> interface can be used in for loops. This is actually only syntactic
sugar for getting an iterator from the object and using it to get all elements sequentially; it makes
code clearer, faster to write end less error-prone.
// foreach-like loop
for (Integer i: iterable) {
System.out.println(i);
}
While using the foreach loop (or "extended for loop") is simple, it's sometimes beneficial to use the
iterator directly. For example, if you want to output a bunch of comma-separated values, but don't
want the last item to have a comma:
https://riptutorial.com/ 494
Iterator<String> iterator = yourData.iterator();
while (iterator.hasNext()){
// next() "moves" the iterator to the next entry and returns it's value.
String entry = iterator.next();
System.out.print(entry);
if (iterator.hasNext()){
// If the iterator has another element after the current one:
System.out.print(",");
}
}
This is much easier and clearer than having a isLastEntry variable or doing calculations with the
loop index.
To create your own Iterable as with any interface you just implement the abstract methods in the
interface. For Iterable there is only one which is called iterator(). But its return type Iterator is
itself an interface with three abstract methods. You can return an iterator associated with some
collection or create your own custom implementation:
@Override
public Iterator<Character> iterator() {
return new Iterator<Character>() {
char letter = 'a';
@Override
public boolean hasNext() {
return letter <= 'z';
}
@Override
public Character next() {
return letter++;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Doesn't make sense to remove a
letter");
}
};
}
}
To use:
https://riptutorial.com/ 495
The new Iterator should come with a state pointing to the first item, each call to next updates its
state to point to the next one. The hasNext() checks to see if the iterator is at the end. If the iterator
were connected to a modifiable collection then the iterator's optional remove() method might be
implemented to remove the item currently pointed to from the underlying collection.
The Iterator.remove() method is an optional method that removes the element returned by the
previous call to Iterator.next(). For example, the following code populates a list of strings and
then removes all of the empty strings.
Output :
Old Size : 5
New Size : 3
Note that is the code above is the safe way to remove elements while iterating a typical collection.
If instead, you attempt to do remove elements from a collection like this:
a typical collection (such as ArrayList) which provides iterators with fail fast iterator semantics will
throw a ConcurrentModificationException.
The remove() method can only called (once) following a next() call. If it is called before calling
next() or if it is called twice following a next() call, then the remove() call will throw an
IllegalStateException.
The remove operation is described as an optional operation; i.e. not all iterators will allow it.
Examples where it is not supported include iterators for immutable collections, read-only views of
collections, or fixed sized collections. If remove() is called when the iterator does not support
removal, it will throw an UnsupportedOperationException.
https://riptutorial.com/ 496
Read Iterator and Iterable online: https://riptutorial.com/java/topic/172/iterator-and-iterable
https://riptutorial.com/ 497
Chapter 73: Java Agents
Examples
Modifying classes with agents
Firstly, make sure that the agent being used has the following attributes in the Manifest.mf:
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Starting a java agent will let the agent access the class Instrumentation. With Instrumentation you
can call addTransformer(ClassFileTransformer transformer). ClassFileTransformers will let you
rewrite the bytes of classes. The class has only a single method which supplies the ClassLoader
that loads the class, the class's name, a java.lang.Class instance of it, it's ProtectionDomain, and
lastly the bytes of the class itself.
Modifying a class purely from bytes can take ages. To remedy this there are libraries that can be
used to convert the class bytes into something more usable.
In this example I'll be using ASM, but other alternatives like Javassist and BCEL have similar
features.
From here changes can be made to the ClassNode object. This makes changing field/method
access incredibly easy. Plus with ASM's Tree API modifying the bytecode of methods is a breeze.
Once the edits are finished you can convert the ClassNode back into bytes with the following
method and return them in the transform method:
https://riptutorial.com/ 498
ClassWriter cw = new ClassWriter(useMaxs ? ClassWriter.COMPUTE_MAXS :
ClassWriter.COMPUTE_FRAMES);
cn.accept(cw);
byte[] b = cw.toByteArray();
return b;
}
Agents can be added to a JVM at runtime. To load an agent you will need to use the Attach API's
VirtualMachine.attatch(String id). You can then load a compiled agent jar with the following
method:
This will not call premain((String agentArgs, Instrumentation inst) in the loaded agent, but instead
will call agentmain(String agentArgs, Instrumentation inst). This requires Agent-Class to be set in
the agent Manifest.mf.
The Premain class will contain the method "premain(String agentArgs Instrumentation inst)"
Here is an example:
import java.lang.instrument.Instrumentation;
When compiled into a jar file open the Manifest and ensure that it has the Premain-Class attribute.
Here is an example:
Premain-Class: PremainExample
To use the agent with another java program "myProgram" you must define the agent in the JVM
https://riptutorial.com/ 499
arguments:
https://riptutorial.com/ 500
Chapter 74: Java Compiler - 'javac'
Remarks
The javac command is used for compiling Java source files to bytecode files. Bytecode files are
platform independent. This means that you can compile your code on one kind of hardware and
operating system, and then run the code on any other platform that supports Java.
The javac command is included in the Java Development Kit (JDK) distributions.
The Java compiler and the rest of the standard Java toolchain places the following restrictions on
the code:
Note: The javac compiler should not be confused with the Just in Time (JIT) compiler which
compiles bytecodes to native code.
Examples
The 'javac' command - getting started
Simple example
Assuming that the "HelloWorld.java" contains the following Java source:
(For an explanation of the above code, please refer to Getting started with Java Language .)
$ javac HelloWorld.java
This produces a file called "HelloWorld.class", which we can then run as follows:
$ java HelloWorld
Hello world!
https://riptutorial.com/ 501
The key points to note from this example are:
1. The source filename "HelloWorld.java" must match the class name in the source file ... which
is HelloWorld. If they don't match, you will get a compilation error.
2. The bytecode filename "HelloWorld.class" corresponds to the classname. If you were to
rename the "HelloWorld.class", you would get an error when your tried to run it.
3. When running a Java application using java, you supply the classname NOT the bytecode
filename.
If we wanted to declare the HelloWorld class in a package call com.example, the "HelloWorld.java"
would contain the following Java source:
package com.example;
This source code file needs to stored in a directory tree whose structure corresponds to the
package naming.
$ javac com/example/HelloWorld.java
This produces a file called "com/example/HelloWorld.class"; i.e. after compilation, the file structure
should look like this:
https://riptutorial.com/ 502
We can then run the application as follows:
$ java com.example.HelloWorld
Hello world!
$ javac *.java
$ javac com/example/*.java
$ javac */**/*.java #Only works on Zsh or with globstar enabled on your shell
This will compile all Java source files in the current directory, in the "com/example" directory, and
recursively in child directories respectively. A third alternative is to supply a list of source filenames
(and compiler options) as a file. For example:
$ javac @sourcefiles
Foo.java
Bar.java
com/example/HelloWorld.java
Note: compiling code like this is appropriate for small one-person projects, and for once-off
programs. Beyond that, it is advisable to select and use a Java build tool. Alternatively, most
programmers use a Java IDE (e.g. NetBeans, eclipse, IntelliJ IDEA) which offers an embedded
compiler and incremental building of "projects".
https://riptutorial.com/ 503
• The -d option sets a destination directory for writing the ".class" files.
• The -sourcepath option sets a source code search path.
• The -cp or -classpath option sets the search path for finding external and previously
compiled classes. For more information on the classpath and how to specify it, refer to the
The Classpath Topic.
• The -version option prints the compiler's version information.
References
The definitive reference for the javac command is the Oracle manual page for javac.
The Java programming language (and its runtime) has undergone numerous changes since its
release since its initial public release. These changes include:
With very few exceptions (for example the enum keyword, changes to some "internal" classes, etc),
these changes are backwards compatible.
• A Java program that was compiled using an older version of the Java toolchain will run on a
newer version Java platform without recompilation.
• A Java program that was written in an older version of Java will compile successfully with a
new Java compiler.
the following is required to compile the class using a Java 5 compiler (or later):
https://riptutorial.com/ 504
If you need to compile Java to run on an older Java platforms, the simplest approach is to install a
JDK for the oldest version you need to support, and use that JDK's compiler in your builds.
You can also compile with a newer Java compiler, but there are complicated. First of all, there
some important preconditions that must be satisfied:
• The code you are compiling must not use Java language constructs that were not available
in the version of Java that you are targeting.
• The code must not depend on standard Java classes, fields, methods and so on that were
not available in the older platforms.
• Third party libraries that the code depends must also be built for the older platform and
available at compile-time and run-time.
Given the preconditions are met, you can recompile code for an older platform using the -target
option. For example,
will compile the above class to produce bytecodes that are compatible with Java 1.4 or later JVM.
(In fact, the -source option implies a compatible -target, so javac -source 1.4 ... would have the
same effect. The relationship between -source and -target is described in the Oracle
documentation.)
Having said that, if you simply use -target or -source, you will still be compiling against the
standard class libraries provided by the compiler's JDK. If you are not careful, you can end up with
classes with the correct bytecode version, but with dependencies on APIs that are not available.
The solution is to use the -bootclasspath option. For example:
will compile against an alternative set of runtime libraries. If the class being compiled has
(accidental) dependencies on newer libraries, this will give you compilation errors.
https://riptutorial.com/ 505
Chapter 75: Java deployment
Introduction
There are a variety of technologies for "packaging" Java applications, webapps and so forth, for
deployment to the platform on which they will run. They range from simple library or executable
JAR files, WAR and EAR files, through to installers and self-contained executables.
Remarks
At the most fundamental level, a Java program can be deployed by copying a compiled class (i.e.
a ".class" file) or a directory tree containing compiled classes. However Java is normally deployed
in one of the following ways:
• By copying a JAR file or collection of JAR files to the system where they will be executed;
e.g. using javac.
• By running some kind of application installer that automates the above. The installer might
also install an embedded JRE.
• By putting the JAR files for the application onto a web server to allow them to be launched
using Java WebStart.
The Creating JAR, WAR and EAR files example summarizes the different ways to create these
files.
There are numerous open source and commercial "installer generator" and "EXE generator" tools
for Java. Similarly, there are tools for obfuscating Java class files (to make reverse engineering
harder) and for adding runtime license checking. These are all out of scope for the "Java
Programming Language" documentation.
Examples
Making an executable JAR from the command line
To make a jar, you need one or more class files. This should have a main method if it is to be run
by a double click.
import javax.swing.*;
import java.awt.Container;
https://riptutorial.com/ 506
public class HelloWorld {
You may use any program you want to do this. To run from the command line, see the
documentation on compiling and running your first java program.
Once you have HelloWorld.class, make a new folder and call it whatever you want.
Main-Class: HelloWorld
Class-Path: HelloWorld.jar
When that is done, type in jar -cvfm HelloWorld.jar manifest.txt HelloWorld.class and press
enter. This makes a jar file (in the folder with your manifest and HelloWorld.class) using the .class
files specified and named HelloWorld.jar. See the Syntax section for information about the options
(like -m and -v).
After these steps, go to your directory with the manifest file and you should find HelloWorld.jar
Clicking on it should display Hello, World in a text box.
The JAR, WAR and EAR files types are fundamentally ZIP files with a "manifest" file and (for WAR
and EAR files) a particular internal directory / file structure.
The recommended way to create these files is to use a Java-specific build tool which
"understands" the requirements for the respective file types. If you don't use a build tool, then IDE
"export" is the next option to try.
https://riptutorial.com/ 507
(Editorial note: the descriptions of how to create these files are best placed in the documentation
for the respective tools. Put them there. Please show some self-restraint and DON'T shoe-horn
them into this example!)
<packaging>jar</packaging>
or
<packaging>war</packaging>
For more details. Maven can be configured to create "executable" JAR files by adding the requisite
information about the entry-point class and external dependencies as plugin properties for the
maven jar plugin. There is even a plugin for creating "uberJAR" files that combine an application
and its dependencies into a single JAR file.
• Eclipse - http://www.riptutorial.com/topic/1143
• NetBeans - http://www.riptutorial.com/topic/5438
• Intellij-IDEA - Exporting
Creating JAR, WAR and EAR files using the jar command.
It is also possible to create these files "by hand" using the jar command. It is simply a matter of
assembling a file tree with the correct component files in the correct place, creating a manifest file,
and running jar to create the JAR file.
Please refer to the jar command Topic ( Creating and modifying JAR files ) for more information
https://riptutorial.com/ 508
Introduction to Java Web Start
Java Web Start software provides the power to launch full-featured applications with a
single click. Users can download and launch applications, such as a complete
spreadsheet program or an Internet chat client, without going through lengthy
installation procedures.
Other advantages of Java Web Start are support for signed code and explicit declaration of
platform dependencies, and support for code caching and deployment of application updates.
Java Web Start is also referred to as JavaWS and JAWS. The primary sources of information are:
Prerequisites
At a high level, Web Start works by distributing Java applications packed as JAR files from a
remote webserver. The prerequisites are:
• A pre-existing Java installation (JRE or JDK) on the target machine where the application is
to run. Java 1.2.2 or higher is required:
○ From Java 5.0 onwards, Web Start support is included in the JRE / JDK.
○ For earlier releases, Web Start support is installed separately.
○ The Web Start infrastructure includes some Javascript that can be included in a web
page to assist the user to install the necessary software.
• The webserver that hosts the software must be accessible to the target machine.
• If the user is going to launch a Web Start application using a link in a web page, then:
https://riptutorial.com/ 509
href="demo_webstart.jnlp">
<information>
<title>Demo</title>
<vendor>The Example.com Team</vendor>
</information>
<resources>
<!-- Application Resources -->
<j2se version="1.7+" href="http://java.sun.com/products/autodl/j2se"/>
<jar href="Demo.jar" main="true"/>
</resources>
<application-desc
name="Demo Application"
main-class="com.example.jwsdemo.Main"
width="300"
height="300">
</application-desc>
<update check="background"/>
</jnlp>
As you can see, a JNLP file XML-based, and the information is all contained in the <jnlp> element.
• The spec attribute gives the version of the JNPL spec that this file conforms to.
• The codebase attribute gives the base URL for resolving relative href URLs in the rest of the
file.
• The href attribute gives the definitive URL for this JNLP file.
• The <information> element contains metadata the application including its title, authors,
description and help website.
• The <resources> element describes the dependencies for the application including the
required Java version, OS platform and JAR files.
• The <application-desc> (or <applet-desc>) element provides information needed to launch the
application.
The JNLP file and the application's JAR files must be installed on the webserver so that they are
available using the URLs indicated by the JNLP file.
• If you can assume that Java Web Start is already installed on the user's machine, then the
web page simply needs to contain a link for launching the application. For example.
https://riptutorial.com/ 510
• Otherwise, the page should also include some scripting to detect the kind of browser the
user is using and request to download and install the required version of Java.
NOTE: It is a bad idea to encourage users to encourage to install Java this way, or even to enable
Java in their web browsers so that JNLP web page launch will work.
$ javaws <url>
where <url> is the URL for the JNLP file on the remote server.
A common requirement for a Java application is that can be deployed by copying a single file. For
simple applications that depend only on the standard Java SE class libraries, this requirement is
satisfied by creating a JAR file containing all of the (compiled) application classes.
Things are not so straightforward if the application depends on third-party libraries. If you simply
put dependency JAR files inside an application JAR, the standard Java class loader will not be
able to find the library classes, and your application will not start. Instead, you need to create a
single JAR file that contains the application classes and associated resources together with the
dependency classes and resources. These need to be organized as a single namespace for the
classloader to search.
$ mkdir tempDir
$ cd tempDir
2. For each dependent JAR file, in the reverse order that they need to appear on the
application's classpath, used the jar command to unpack the JAR into the temporary
directory.
https://riptutorial.com/ 511
$ jar -xf <path/to/file.jar>
Doing this for multiple JAR files will overlay contents of the JARs.
3. Copy the application classes from the build tree into the temporary directory
$ cp -r path/to/classes .
In addition, if you use an appropriate tooling to create the UberJAR, you will have the option of
excluding library classes that are not used from the JAR file. However, that this is typically done by
static analysis of the classes. If your application uses reflection, annotation processing and similar
techniques, you need to be careful that classes are not excluded incorrectly.
• If you have lots of UberJARs with the same dependencies, then each one will contain a copy
of the dependencies.
• Some open source libraries have licenses which may preclude 1 their use in an UberJAR.
1 - Some open source library licenses allow you to use the library only of the end-user is able to replace one version
of the library with another. UberJARs can make replacement of version dependencies difficult.
https://riptutorial.com/ 512
Chapter 76: Java Editions, Versions,
Releases and Distributions
Examples
Differences between Java SE JRE or Java SE JDK distributions
Sun / Oracle releases of Java SE come in two forms: JRE and JDK. In simple terms, JREs support
running Java applications, and JDKs also support Java development.
• The java command for running a Java program in a JVM (Java Virtual Machine)
• The jjs command for running the Nashorn Javascript engine.
• The keytool command for manipulating Java keystores.
• The policytool command for editing security sandbox security policies.
• The pack200 and unpack200 tools for packing and unpacking "pack200" file for web
deployment.
• The orbd, rmid, rmiregistry and tnameserv commands that support Java CORBA and RMI
applications.
"Desktop JRE" installers include a Java plugin suitable for some web browser. This is deliberately
left out of "Server JRE" installers.linux syscall read benchmarku
From Java 7 update 6 onwards, JRE installers have included JavaFX (version 2.2 or later).
• The javac command, which compiles Java source code (".java") to bytecode files (".class").
• The tools for creating JAR files such as jar and jarsigner
• Development tools such as:
appletviewer for running applets
○
https://riptutorial.com/ 513
• Diagnostic tools such as:
○jdb the basic Java debugger
○jmap and jhat for dumping and analysing a Java heap.
○jstack for getting a thread stack dump.
○javap for examining ".class" files.
• Application management and monitoring tools such as:
○jconsole a management console,
○jstat, jstatd, jinfo and jps for application monitoring
A typical Sun / Oracle JDK installation also includes a ZIP file with the source code of the Java
libraries. Prior to Java 6, this was the only publicly available Java source code.
From Java 6 onwards, the complete source code for OpenJDK is available for download from the
OpenJDK site. It is typically not included in (Linux) JDK packages, but is available as a separate
package.
Orthogonal to the JRE versus JDK dichotomy, there are two types of Java release that are widely
available:
• The Oracle Hotspot releases are the ones that you download from the Oracle download
sites.
• The OpenJDK releases are the ones that are built (typically by third-party providers) from the
OpenJDK source repositories.
In functional terms, there is little difference between a Hotspot release and an OpenJDK release.
There are some extra "enterprise" features in Hotspot that Oracle (paying) Java customers can
enable, but apart from that the same technology are present in both Hotspot and OpenJDK.
Another advantage of Hotspot over OpenJDK is that patch releases for Hotspot tend to be
available a bit earlier. This also depends on how agile your OpenJDK provider is; e.g. how long it
takes a Linux distribution's build team to prepare and QA a new OpenJDK build, and get it into
their public repositories.
The flipside is that the Hotspot releases are not available from the package repositories for most
Linux distributions. This means that keeping your Java software up-to-date on a Linux machine is
usually more work if you use Hotspot.
Java technology is both a programming language and a platform. The Java programming
language is a high-level object-oriented language that has a particular syntax and style. A Java
platform is a particular environment in which Java programming language applications run.
There are several Java platforms. Many developers, even long-time Java programming language
developers, do not understand how the different platforms relate to each other.
https://riptutorial.com/ 514
The Java Programming Language Platforms
There are four platforms of the Java programming language:
• Java FX
All Java platforms consist of a Java Virtual Machine (VM) and an application programming
interface (API). The Java Virtual Machine is a program, for a particular hardware and software
platform, that runs Java technology applications. An API is a collection of software components
that you can use to create other software components or applications. Each Java platform
provides a virtual machine and an API, and this allows applications written for that platform to run
on any compatible system with all the advantages of the Java programming language: platform-
independence, power, stability, ease-of-development, and security.
Java SE
When most people think of the Java programming language, they think of the Java SE API. Java
SE's API provides the core functionality of the Java programming language. It defines everything
from the basic types and objects of the Java programming language to high-level classes that are
used for networking, security, database access, graphical user interface (GUI) development, and
XML parsing.
In addition to the core API, the Java SE platform consists of a virtual machine, development tools,
deployment technologies, and other class libraries and toolkits commonly used in Java technology
applications.
Java EE
The Java EE platform is built on top of the Java SE platform. The Java EE platform provides an
API and runtime environment for developing and running large-scale, multi-tiered, scalable,
reliable, and secure network applications.
Java ME
The Java ME platform provides an API and a small-footprint virtual machine for running Java
programming language applications on small devices, like mobile phones. The API is a subset of
the Java SE API, along with special class libraries useful for small device application development.
https://riptutorial.com/ 515
Java ME applications are often clients of Java EE platform services.
Java FX
Java FX technology is a platform for creating rich internet applications written in Java FX
ScriptTM. Java FX Script is a statically-typed declarative language that is compiled to Java
technology bytecode, which can then be run on a Java VM. Applications written for the Java FX
platform can include and link to Java programming language classes, and may be clients of Java
EE platform services.
Java SE Versions
End-of-life (free2
Java SE Version1 Code Name Release Date
)
prior to 2009-11-
Java SE 1.4.2 Mantis 2003-06-26
04
prior to 2009-11-
Java SE 1.4 Merlin 2002-02-06
04
prior to 2009-11-
Java SE 1.3.1 Ladybird 2001-05-17
04
prior to 2009-11-
Java SE 1.3 Kestrel 2000-05-08
04
https://riptutorial.com/ 516
End-of-life (free2
Java SE Version1 Code Name Release Date
)
prior to 2009-11-
Java SE 1.2 Playground 1998-12-08
04
prior to 2009-11-
Java SE 1.1 Sparkler 1997-02-19
04
prior to 2009-11-
Java SE 1.0 Oak 1996-01-21
04
Footnotes:
1. The links are to online copies of the respective releases documentation on Oracle's website.
The documentation for many older releases no longer online, though it typically can be
downloaded from the Oracle Java Archives.
2. Most historical versions of Java SE have passed their official "end of life" dates. When a
Java version passes this milestone, Oracle stop providing free updates for it. Updates are
still available to customers with support contracts.
Source:
Java SE
Highlights
Version
https://riptutorial.com/ 517
Java SE
Highlights
Version
The assert keyword. Regular expression classes. Exception chaining. NIO APIs -
Java SE non-blocking I/O, Buffer and Channel. java.util.logging.* API. Image I/O API.
1.4 Integrated XML and XSLT (JAXP). Integrated security and cryptography (JCE,
JSSE, JAAS). Integrated Java Web Start. Preferences API.
Java SE HotSpot JVM included. CORBA / RMI integration. Java Naming and Directory
1.3 Interface (JNDI). Debugger framework (JPDA). JavaSound API. Proxy API.
Java SE The strictfp keyword. Swing APIs. The Java plugin (for web browsers). CORBA
1.2 interoperability. Collections framework.
Source:
https://riptutorial.com/ 518
Chapter 77: Java Floating Point Operations
Introduction
Floating-point numbers are numbers that have fractional parts (usually expressed with a decimal
point). In Java, there is two primitive types for floating-point numbers which are float (uses 4
bytes), and double (uses 8 bytes). This documentation page is for detailing with examples
operations that can be done on floating points in Java.
Examples
Comparing floating point values
You should be careful when comparing floating-point values (float or double) using relational
operators: ==, !=, < and so on. These operators give results according to the binary representations
of the floating point values. For example:
The calculation oneThird has introduced a tiny rounding error, and when we multiply oneThird by 3
we get a result that is slightly different to 1.0.
This problem of inexact representations is more stark when we attempt to mix double and float in
calculations. For example:
System.out.println(floatVal); // 0.1
System.out.println(doubleVal); // 0.1
System.out.println(doubleValCopy); // 0.10000000149011612
The floating point representations used in Java for the float and double types have limited number
of digits of precision. For the float type, the precision is 23 binary digits or about 8 decimal digits.
For the double type, it is 52 bits or about 15 decimal digits. On top of that, some arithmetical
https://riptutorial.com/ 519
operations will introduce rounding errors. Therefore, when a program compares floating point
values, it standard practice to define an acceptable delta for the comparison. If the difference
between the two numbers is less than the delta, they are deemed to be equal. For example
System.out.println();
}
}
}
Result:
delta: 0.01
1.0 == 1.0001 ? true
1.0001 == 1.0000001 ? true
1.0000001 == 1.000000001 ? true
1.000000001 == 1.0000000000001 ? true
delta: 1.0E-5
1.0 == 1.0001 ? false
1.0001 == 1.0000001 ? false
1.0000001 == 1.000000001 ? true
1.000000001 == 1.0000000000001 ? true
delta: 1.0E-7
1.0 == 1.0001 ? false
1.0001 == 1.0000001 ? false
1.0000001 == 1.000000001 ? true
https://riptutorial.com/ 520
1.000000001 == 1.0000000000001 ? true
delta: 1.0E-10
1.0 == 1.0001 ? false
1.0001 == 1.0000001 ? false
1.0000001 == 1.000000001 ? false
1.000000001 == 1.0000000000001 ? false
delta: 0.0
1.0 == 1.0001 ? false
1.0001 == 1.0000001 ? false
1.0000001 == 1.000000001 ? false
1.000000001 == 1.0000000000001 ? false
Also for comparison of double and float primitive types static compare method of corresponding
boxing type can be used. For example:
double a = 1.0;
double b = 1.0001;
System.out.println(Double.compare(a, b));//-1
System.out.println(Double.compare(b, a));//1
Finally, determining what deltas are most appropriate for a comparison can be tricky. A commonly
used approach is to pick delta values that are our intuition says are about right. However, if you
know scale and (true) accuracy of the input values, and the calculations performed, it may be
possible to come up with mathematically sound bounds on the accuracy of the results, and hence
for the deltas. (There is a formal branch of Mathematics known as Numerical Analysis that used to
be taught to computational scientists that covered this kind of analysis.)
The float data type is a single-precision 32-bit IEEE 754 floating point.
Float overflow
Maximum possible value is 3.4028235e+38 , When it exceeds this value it produces Infinity
float f = 3.4e38f;
float result = f*2;
System.out.println(result); //Infinity
Float UnderFlow
Minimum value is 1.4e-45f, when is goes below this value it produces 0.0
float f = 1e-45f;
float result = f/1000;
System.out.println(result);
https://riptutorial.com/ 521
double data type
The double data type is a double-precision 64-bit IEEE 754 floating point.
Double OverFlow
double d = 1e308;
double result=d*2;
System.out.println(result); //Infinity
Double UnderFlow
Minimum value is 4.9e-324, when is goes below this value it produces 0.0
double d = 4.8e-323;
double result = d/1000;
System.out.println(result); //0.0
Floating point Numbers can be formatted as a decimal number using String.format with 'f' flag
https://riptutorial.com/ 522
System.out.println(format); //123456789
By default, floating point operations on float and double do not strictly adhere to the rules of the
IEEE 754 specification. An expression is allowed to use implementation-specific extensions to the
range of these values; essentially allowing them to be more accurate than required.
strictfp disables this behavior. It is applied to a class, interface, or method, and applies to
everything contained in it, such as classes, interfaces, methods, constructors, variable initializers,
etc. With strictfp, the intermediate values of a floating-point expression must be within the float
value set or the double value set. This causes the results of such expressions to be exactly those
that the IEEE 754 specification predicts.
All constant expressions are implicitly strict, even if they aren't inside a strictfp scope.
Therefore, strictfp has the net effect of sometimes making certain corner case computations less
accurate, and can also make floating point operations slower (as the CPU is now doing more work
to ensure any native extra precision does not affect the result). However, it also causes the results
to be exactly the same on all platforms. It is therefore useful in things like scientific programs,
where reproducibility is more important than speed.
public static final strictfp class Ops { // strictfp affects all enclosed entities
private StrictOps() {}
https://riptutorial.com/ 523
Chapter 78: Java Memory Management
Remarks
In Java, objects are allocated in the heap, and heap memory is reclaimed by automatic garbage
collection. An application program cannot explicitly delete a Java object.
The basic principles of Java garbage collection are described in the Garbage collection example.
Other examples describe finalization, how to trigger the garbage collector by hand, and the
problem of storage leaks.
Examples
Finalization
A Java object may declare a finalize method. This method is called just before Java releases the
memory for the object. It will typically look like this:
@Override
protected void finalize() throws Throwable {
// Cleanup code
}
}
The caveats above mean that it is a bad idea to rely on the finalize method to perform cleanup (or
other) actions that must be performed in a timely fashion. Over reliance on finalization can lead to
storage leaks, memory leaks and other problems.
In short, there are very few situation where finalization is actually a good solution.
https://riptutorial.com/ 524
public class CaptainJack {
public static CaptainJack notDeadYet = null;
When an instance of CaptainJack becomes unreachable and the garbage collector attempts to
reclaim it, the finalize() method will assign a reference to the instance to the notDeadYet variable.
That will make the instance reachable once more, and the garbage collector won't delete it.
Answer: No.
The catch is the JVM will only run a finalizer on an object once in its lifetime. If you assign null to
notDeadYet causing a resurected instance to be unreachable once more, the garbage collector
won't call finalize() on the object.
1 - See https://en.wikipedia.org/wiki/Jack_Harkness.
Manually triggering GC
System.gc();
However, Java does not guarantee that the Garbage Collector has run when the call returns. This
method simply "suggests" to the JVM (Java Virtual Machine) that you want it to run the garbage
collector, but does not force it to do so.
It is generally considered a bad practice to attempt to manually trigger garbage collection. The
JVM can be run with the -XX:+DisableExplicitGC option to disable calls to System.gc(). Triggering
garbage collection by calling System.gc() can disrupt normal garbage management / object
promotion activities of the specific garbage collector implementation in use by the JVM.
Garbage collection
• If program forgets to delete an object and just "forgets" about it, the associated memory is
lost to the application. The term for this situation is a memory leak, and it too much memory
leaks an application is liable to use more and more memory, and eventually crash.
https://riptutorial.com/ 525
• On the other hand, if an application attempts to delete the same object twice, or use an
object after it has been deleted, then the application is liable to crash due to problems with
memory corruption
In a complicated C++ program, implementing memory management using new and delete can be
time consuming. Indeed, memory management is a common source of bugs.
At any time during the execution of a Java program, we can divide the set of all existing objects
into two distinct subsets1:
A reachable object is any object that can be accessed in any potential continuing
computation from any live thread.
In practice, this means that there is a chain of references starting from an in-scope local
variable or a static variable by which some code might be able to reach the object.
Any objects that are unreachable are eligible for garbage collection. This does not mean that they
will be garbage collected. In fact:
The Java language Specification gives a lot of latitude to a JVM implementation to decide when to
collect unreachable objects. It also (in practice) gives permission for a JVM implementation to be
conservative in how it detects unreachable objects.
The one thing that the JLS guarantees is that no reachable objects will ever be garbage collected.
When the GC detects an unreachable object, the following events can occur.
1. If there are any Reference objects that refer to the object, those references will be cleared
before the object is deleted.
https://riptutorial.com/ 526
2. If the object is finalizable, then it will be finalized. This happens before the object is deleted.
3. The object can be deleted, and the memory it occupies can be reclaimed.
Note that there is a clear sequence in which the above events can occur, but nothing requires the
garbage collector to perform the final deletion of any specific object in any specific time-frame.
Let us examine what happens when test() is called. Statements T1, T2 and T3 create Node
objects, and the objects are all reachable via the n1, n2 and n3 variables respectively. Statement T4
assigns the reference to the 2nd Node object to the next field of the first one. When that is done, the
2nd Node is reachable via two paths:
n2 -> Node2
n1 -> Node1, Node1.next -> Node2
In statement T5, we assign null to n2. This breaks the first of the reachability chains for Node2, but
the second one remains unbroken, so Node2 is still reachable.
In statement T6, we assign null to n3. This breaks the only reachability chain for Node3, which
makes Node3 unreachable. However, Node1 and Node2 are both still reachable via the n1 variable.
Finally, when the test() method returns, its local variables n1, n2 and n3 go out of scope, and
therefore cannot be accessed by anything. This breaks the remaining reachability chains for Node1
and Node2, and all of the Node objects are nor unreachable and eligible for garbage collection.
https://riptutorial.com/ 527
1 - This is a simplification that ignores finalization, and Reference classes. 2 - Hypothetically, a Java implementation
could do this, but the performance cost of doing this makes it impractical.
When a Java virtual machine starts, it needs to know how big to make the Heap, and the default
size for thread stacks. These can be specified using command-line options on the java command.
For versions of Java prior to Java 8, you can also specify the size of the PermGen region of the
Heap.
Note that PermGen was removed in Java 8, and if you attempt to set the PermGen size the option
will be ignored (with a warning message).
If you don't specify Heap and Stack sizes explicitly, the JVM will use defaults that are calculated in
a version and platform specific way. This may result in your application using too little or too much
memory. This is typically OK for thread stacks, but it can be problematic for a program that uses a
lot of memory.
The <size> parameter can be a number of bytes, or can have a suffix of k, m or g. The latter specify
the size in kilobytes, megabytes and gigabytes respectively.
Examples:
The -XX:+printFlagsFinal option can be used to print the values of all flags before starting the JVM.
This can be used to print the defaults for the heap and stack size settings as follows:
• For Windows:
https://riptutorial.com/ 528
The output of the above commands will resemble the following:
In the Garbage collection example, we implied that Java solves the problem of memory leaks. This
is not actually true. A Java program can leak memory, though the causes of the leaks are rather
different.
When you push an object and then immediately pop it, there will still be a reference to the object in
the stack array.
The logic of the stack implementation means that that reference cannot be returned to a client of
the API. If an object has been popped then we can prove that it cannot "be accessed in any
potential continuing computation from any live thread". The problem is that a current generation
JVM cannot prove this. Current generation JVMs do not consider the logic of the program in
determining whether references are reachable. (For a start, it is not practical.)
But setting aside the issue of what reachability really means, we clearly have a situation here
https://riptutorial.com/ 529
where the NaiveStack implementation is "hanging onto" objects that ought to be reclaimed. That is
a memory leak.
This strategy can be very effective if implemented properly. However, if implemented incorrectly, a
cache can be a memory leak. Consider the following example:
The problem with this code is that while any call to doRequest could add a new entry to the cache,
there is nothing to remove them. If the service is continually getting different tasks, then the cache
will eventually consume all available memory. This is a form of memory leak.
One approach to solving this is to use a cache with a maximum size, and throw out old entries
when the cache exceeds the maximum. (Throwing out the least recently used entry is a good
strategy.) Another approach is to build the cache using WeakHashMap so that the JVM can evict
cache entries if the heap starts getting too full.
https://riptutorial.com/ 530
Chapter 79: Java Memory Model
Remarks
The Java Memory Model is the section of the JLS that specifies the conditions under which one
thread is guaranteed to see the effects of memory writes made by another thread. The relevant
section in recent editions is "JLS 17.4 Memory Model" (in Java 8, Java 7, Java 6)
There was a major overhaul of the Java Memory Model in Java 5 which (among other things)
changed the way that volatile worked. Since then, the memory model been essentially
unchanged.
Examples
Motivation for the Memory Model
If this class is used is a single-threaded application, then the observable behavior will be exactly
as you would expect. For instance:
will output:
0, 0
1, 1
As far as the "main" thread can tell, the statements in the main() method and the doIt() method
will be executed in the order that they are written in the source code. This is a clear requirement of
the Java Language Specification (JLS).
https://riptutorial.com/ 531
Now consider the same class used in a multi-threaded application.
In fact, according to the JLS it is not possible to predict that this will print:
Reordering of assignments
One possible explanation for unexpected results is that the JIT compiler has changed the order of
the assignments in the doIt() method. The JLS requires that statements appear to execute in
order from the perspective of the current thread. In this case, nothing in the code of the doIt()
method can observe the effect of a (hypothetical) reordering of those two statement. This means
that the JIT compiler would be permitted to do that.
On typical modern hardware, machine instructions are executed using a instruction pipeline which
allows a sequence of instructions to be in different stages. Some phases of instruction execution
take longer than others, and memory operations tend to take a longer time. A smart compiler can
optimize the instruction throughput of the pipeline by ordering the instructions to maximize the
amount of overlap. This may lead to executing parts of statements out of order. The JLS permits
this provided that not affect the result of the computation from the perspective of the current thread
.
https://riptutorial.com/ 532
A second possible explanation is effect of memory caching. In a classical computer architecture,
each processor has a small set of registers, and a larger amount of memory. Access to registers is
much faster than access to main memory. In modern architectures, there are memory caches that
are slower than registers, but faster than main memory.
A compiler will exploit this by trying to keep copies of variables in registers, or in the memory
caches. If a variable does not need to be flushed to main memory, or does not need to be read
from memory, there are significant performance benefits in not doing this. In cases where the JLS
does not require memory operations to be visible to another thread, the Java JIT compiler is likely
to not add the "read barrier" and "write barrier" instructions that will force main memory reads and
writes. Once again, the performance benefits of doing this are significant.
Proper synchronization
So far, we have seen that the JLS allows the JIT compiler to generate code that makes single-
threaded code faster by reordering or avoiding memory operations. But what happens when other
threads can observe the state of the (shared) variables in main memory?
The answer is, that the other threads are liable to observe variable states which would appear to
be impossible ... based on the code order of the Java statements. The solution to this is to use
appropriate synchronization. The three main approaches are:
But even with this, it is important to understand where synchronization is needed, and what effects
that you can rely on. This is where the Java Memory Model comes in.
Armed with this, it is possible to reason about memory coherency in a Java program, and decide
whether this will be predictable and consistent for all execution platforms.
Happens-before relationships
(The following is a simplified version of what the Java Language Specification says. For a deeper
understanding, you need to read the specification itself.)
https://riptutorial.com/ 533
Happens-before relationships are the part of the Memory Model that allow us to understand and
reason about memory visibility. As the JLS says (JLS 17.4.5):
Actions
The actions that the above quote refers to are specified in JLS 17.4.2. There are 5 kinds of action
listed defined by the spec:
• Synchronization actions:
• External Actions. An action that has a result that depends on the environment in which the
program.
• Thread divergence actions. These model the behavior of certain kinds of infinite loop.
Program order describes the order of statement execution within a single thread.
Synchronization order describes the order of statement execution for two statements connected by
a synchronization:
• An unlock action on monitor synchronizes-with all subsequent lock actions on that monitor.
• A write to a volatile variable synchronizes-with all subsequent reads of the same variable by
any thread.
https://riptutorial.com/ 534
• An action that starts a thread (i.e. the call to Thread.start()) synchronizes-with the first action
in the thread it starts (i.e. the call to the thread's run() method).
• The default initialization of fields synchronizes-with the first action in every thread. (See the
JLS for an explanation of this.)
• The final action in a thread synchronizes-with any action in another thread that detects the
termination; e.g. the return of a join() call or isTerminated() call that returns true.
• If one thread interrupts another thread, the interrupt call in the first thread synchronizes-with
the point where another thread detects that the thread was interrupted.
Happens-before Order
This ordering ( JLS 17.4.5 ) is what determines whether a memory write is guaranteed to be visible
to a subsequent memory read.
More specifically, a read of a variable v is guaranteed to observe a write to v if and only if write(v)
happens-before read(v) AND there is no intervening write to v. If there are intervening writes, then
the read(v) may see the results of them rather than the earlier one.
• Happens-Before Rule #1 - If x and y are actions of the same thread and x comes before y
in program order, then x happens-before y.
In addition, various classes in the Java standard libraries are specified as defining happens-before
relationships. You can interpret this as meaning that it happens somehow, without needing to
know exactly how the guarantee is going to be met.
We will present some examples to show how to apply happens-before reasoning to check that
writes are visible to subsequent reads.
Single-threaded code
As you would expect, writes are always visible to subsequent reads in a single-threaded program.
https://riptutorial.com/ 535
public class SingleThreadExample {
public int a, b;
Summing up:
6. The write(a) happens-before read(a) relation means that the a + b statement is guaranteed
to see the correct value of a.
7. The write(b) happens-before read(b) relation means that the a + b statement is guaranteed
to see the correct value of b.
https://riptutorial.com/ 536
is called in one thread, and
3. ve.observe() is called in another thread.
3. The volatile-write(a) action in the first thread happens-before the volatile-read(a) action in
the second thread.
4. The write(b) action in the first thread happens-before the read(b) action in the second
thread.
In other words, for this particular sequence, we are guaranteed that the 2nd thread will see the
update to the non-volatile variable b made by the first thread. However, it is should also be clear
that if the assignments in the update method were the other way around, or the observe() method
read the variable b before a, then the happens-before chain would be broken. The chain would
also be broken if volatile-read(a) in the second thread was not subsequent to the volatile-
write(a) in the first thread.
When the chain is broken, there is no guarantee that observe() will see the correct value of b.
To analyse this completely, we need to consider all of the possible interleavings of the statements
in thread one and thread two. Instead, we will consider just two of them.
In this case, it is easy to see that there is an unbroken happens-before chain from write(b, 3) to
read(b). Furthermore there is no intervening write to b. So, for this scenario, the third thread is
guaranteed to see b as having value 3.
https://riptutorial.com/ 537
Scenario #2 - suppose that update(1, 2) and update(3,4) overlap and the ations are interleaved as
follows:
Now, while there is a happens-before chain from write(b, 3) to read(b), there is an intervening
write(b, 1) action performed by the other thread. This means we cannot be certain which value
read(b) will see.
(Aside: This demonstrates that we cannot rely on volatile for ensuring visibility of non-volatile
variables, except in very limited situations.)
The Memory Model is difficult to understand, and difficult to apply. It is useful if you need to reason
about the correctness of multi-threaded code, but you do not want to have to do this reasoning for
every multi-threaded application that you write.
If you adopt the following principals when writing concurrent code in Java, you can largely avoid
the need to resort to happens-before reasoning.
• Use immutable data structures where possible. A properly implemented immutable class will
be thread-safe, and will not introduce thread-safety issues when you use it with other
classes.
• Use primitive mutexes or Lock objects to synchronize access to state in mutable objects that
need to be thread-safe1.
• Use Executor / ExecutorService or the fork join framework rather than attempting to create
manage threads directly.
• Use the `java.util.concurrent classes that provide advanced locks, semaphores, latches and
barriers, instead of using wait/notify/notifyAll directly.
• Use the java.util.concurrent versions of maps, sets, lists, queues and deques rather than
external synchonization of non-concurrent collections.
The general principle is to try to use Java's built-in concurrency libraries rather than "rolling your
own" concurrency. You can rely on them working, if you use them properly.
1 - Not all objects need to be thread safe. For example, if an object or objects is thread-confined (i.e. it is only
accessible to one thread), then its thread-safety is not relevant.
https://riptutorial.com/ 538
Chapter 80: Java Native Access
Examples
Introduction to JNA
What is JNA?
Java Native Access (JNA) is a community-developed library providing Java programs an easy
access to native shared libraries (.dll files on windows, .so files on Unix ...)
For the purpose of this introduction, we suppose the native platform in use is Windows.
If you're running on another platform simply replace the string "msvcrt" with the string
"c" in the code below.
The small Java program below will print a message on the console by calling the C printf
function.
CRuntimeLibrary.java
package jna.introduction;
import com.sun.jna.Library;
import com.sun.jna.Native;
// We declare the printf function we need and the library containing it (msvcrt)...
public interface CRuntimeLibrary extends Library {
CRuntimeLibrary INSTANCE =
(CRuntimeLibrary) Native.loadLibrary("msvcrt", CRuntimeLibrary.class);
MyFirstJNAProgram.java
package jna.introduction;
https://riptutorial.com/ 539
public static void main(String args[]) {
CRuntimeLibrary.INSTANCE.printf("Hello World from JNA !");
}
}
Where to go now?
Jump into another topic here or jump to the official site.
https://riptutorial.com/ 540
Chapter 81: Java Native Interface
Parameters
Parameter Details
Remarks
Setting up JNI requires both a Java and a native compiler. Depending on the IDE and OS, there is
some setting up required. A guide for Eclipse can be found here. A full tutorial can be found here.
These are the steps for setting up the Java-C++ linkage on windows:
• Compile the Java source files (.java) into classes (.class) using javac.
• Create header (.h) files from the Java classes containing native methods using javah. These
files "instruct" the native code which methods it is responsible for implementing.
• Include the header files (#include) in the C++ source files (.cpp) implementing the native
methods.
• Compile the C++ source files and create a library (.dll). This library contains the native code
implementation.
• Specify the library path (-Djava.library.path) and load it in the Java source file (
System.loadLibrary(...)).
Callbacks (Calling Java methods from native code) requires to specify a method descriptor. If the
descriptor is incorrect, a runtime error occurs. Because of this, it is helpful to have the descriptors
made for us, this can be done with javap -s.
Examples
Calling C++ methods from Java
Static and member methods in Java can be marked as native to indicate that their implementation
is to be found in a shared library file. Upon execution of a native method, the JVM looks for a
corresponding function in loaded libraries (see Loading native libraries), using a simple name
mangling scheme, performs argument conversion and stack setup, then hands over control to
native code.
Java code
https://riptutorial.com/ 541
/*** com/example/jni/JNIJava.java **/
package com.example.jni;
C++ code
Header files containing native function declarations should be generated using the javah tool on
target classes. Running the following command at the build directory :
... produces the following header file (comments stripped for brevity) :
// com_example_jni_JNIJava.hpp
#ifndef _Included_com_example_jni_JNIJava
#define _Included_com_example_jni_JNIJava
#ifdef __cplusplus
extern "C" { // This is absolutely required if using a C++ compiler
#endif
#ifdef __cplusplus
}
#endif
#endif
https://riptutorial.com/ 542
// com_example_jni_JNIJava.cpp
#include <iostream>
#include "com_example_jni_JNIJava.hpp"
Output
Running the example class above yields the following output :
1. obtain a method pointer with the GetMethodID JNI function, using the method name and
descriptor ;
2. call one of the Call*Method functions listed here.
Java code
package com.example.jni;
https://riptutorial.com/ 543
}
C++ code
// com_example_jni_JNICppCallback.cpp
#include <iostream>
#include "com_example_jni_JNIJavaCallback.h"
Output
Got float from C++: 5.221
Got int from C++: 17
https://riptutorial.com/ 544
static {};
descriptor: ()V
public com.example.jni.JNIJavaCallback();
descriptor: ()V
The common idiom for loading shared library files in Java is the following :
Calls to System.loadLibrary are almost always static so as to occur during class loading, ensuring
that no native method can execute before the shared library has been loaded. However the
following is possible :
...
This allows to defer shared library loading until necessary, but requires extra care to avoid
java.lang.UnsatisfiedLinkErrors.
https://riptutorial.com/ 545
Watch out for system path separators : for example, Windows uses ; instead of :.
Note that System.loadLibrary resolves library filenames in a platform-dependent manner : the code
snippet above expects a file named libExample.so on Linux, and Example.dll on Windows.
...
https://riptutorial.com/ 546
Chapter 82: Java Performance Tuning
Examples
General approach
The internet is packed with tips for performance improvement of Java programs. Perhaps the
number one tip is awareness. That means:
The first point should be done during the design stage if speaking about a new system or module.
If speaking about legacy code, analyzing and testing tools come into the picture. The most basic
tool for analyzing your JVM performance is JVisualVM, which is included in the JDK.
The third point is mostly about experience and extensive research, and of course raw tips that will
show up on this page and others, like this.
In Java, it's too "easy" to create many String instances which are not needed. That and other
reasons might cause your program to have lots of Strings that the GC is busy cleaning up.
myString += "foo";
The problem is that each + creates a new String (usually, since new compilers optimize some
cases). A possible optimization can be made using StringBuilder or StringBuffer:
If you build long Strings often (SQLs for example), use a String building API.
https://riptutorial.com/ 547
• Reduce usage of replace, substring etc.
• Avoid String.toArray(), especially in frequently accessed code.
• Log prints which are destined to be filtered (due to log level for example) should not be
generated (log level should be checked in advance).
• Use libraries like this if necessary.
• StringBuilder is better if the variable is used in a non-shared manner (across threads).
"Programmers waste enormous amounts of time thinking about, or worrying about, the
speed of noncritical parts of their programs, and these attempts at efficiency actually
have a strong negative impact when debugging and maintenance are considered. We
should forget about small efficiencies, say about 97% of the time: premature
optimization is the root of all evil. Yet we should not pass up our opportunities in that
critical 3%."
source
Bearing that sage advice in mind, here is the recommended procedure for optimizing programs:
1. First of all, design and code your program or library with a focus on simplicity and
correctness. To start with, don't spend much effort on performance.
2. Get it to a working state, and (ideally) develop unit tests for the key parts of the codebase.
3. Develop an application level performance benchmark. The benchmark should cover the
performance critical aspects of your application, and should perform a range of tasks that are
typical of how the application will be used in production.
5. Compare the measured performance against your criteria for how fast the application needs
to be. (Avoid unrealistic, unattainable or unquantifiable criteria such as "as fast as possible".)
6. If you have met the criteria, STOP. You job is done. (Any further effort is probably a waste of
time.)
8. Examine the profiling results and pick the biggest (unoptimized) "performance hotspots"; i.e.
sections of the code where the application seems to be spending the most time.
9. Analyse the hotspot code section to try to understand why it is a bottleneck, and think of a
way to make it faster.
11. Rerun the benchmark to see if the code change has improved the performance:
https://riptutorial.com/ 548
• If Yes, then return to step 4.
• If No, then abandon the change and return to step 9. If you are making no progress,
pick a different hotspot for your attention.
Eventually you will get to a point where the application is either fast enough, or you have
considered all of the significant hotspots. At this point you need to stop this approach. If a section
of code is consuming (say) 1% of the overall time, then even a 50% improvement is only going to
make the application 0.5% faster overall.
Clearly, there is a point beyond which hotspot optimization is a waste of effort. If you get to that
point, you need to take a more radical approach. For example:
But wherever possible, rely on tools and measurement rather than instinct to direct your
optimization effort.
https://riptutorial.com/ 549
Chapter 83: Java Pitfalls - Exception usage
Introduction
Several Java programming language misusage might conduct a program to generate incorrect
results despite being compiled correctly. This topic main purpose is to list common pitfalls related
to exception handling, and to propose the correct way to avoid having such pitfalls.
Examples
Pitfall - Ignoring or squashing exceptions
Exceptions are usually thrown (by something) to notify other parts of the program that some
significant (i.e. "exceptional") event has occurred. Generally (though not always) an exception
means that something has gone wrong. If you code your program to squash the exception, there is
a fair chance that the problem will reappear in another form. To make things worse, when you
squash the exception, you are throwing away the information in the exception object and its
associated stack trace. That is likely to make it harder to figure out what the original source of the
problem was.
In practice, exception squashing frequently happens when you use an IDE's auto-correction
feature to "fix" a compilation error caused by an unhandled exception. For example, you might see
code like this:
try {
inputStream = new FileInputStream("someFile");
} catch (IOException e) {
/* add exception handling code here */
}
Clearly, the programmer has accepted the IDE's suggestion to make the compilation error go
away, but the suggestion was inappropriate. (If the file open has failed, the program should most
likely do something about it. With the above "correction", the program is liable to fail later; e.g. with
a NullPointerException because inputStream is now null.)
Having said that, here is an example of deliberately squashing an exception. (For the purposes of
argument, assume that we have determined that an interrupt while showing the selfie is harmless.)
The comment tells the reader that we squashed the exception deliberately, and why we did that.
try {
selfie.show();
https://riptutorial.com/ 550
} catch (InterruptedException e) {
// It doesn't matter if showing the selfie is interrupted.
}
Another conventional way to highlight that we are deliberately squashing an exception without
saying why is to indicate this with the exception variable's name, like this:
try {
selfie.show();
} catch (InterruptedException ignored) { }
Some IDEs (like IntelliJ IDEA) won't display a warning about the empty catch block if the variable
name is set to ignored.
A common thought pattern for inexperienced Java programmers is that exceptions are "a problem"
or "a burden" and the best way to deal with this is catch them all1 as soon as possible. This leads
to code like this:
....
try {
InputStream is = new FileInputStream(fileName);
// process the input
} catch (Exception ex) {
System.out.println("Could not open file " + fileName);
}
The above code has a significant flaw. The catch is actually going to catch more exceptions than
the programmer is expecting. Suppose that the value of the fileName is null, due to a bug
elsewhere in the application. This will cause the FileInputStream constructor to throw a
NullPointerException. The handler will catch this, and report to the user:
which is unhelpful and confusing. Worse still, suppose that the it was the "process the input" code
that threw the unexpected exception (checked or unchecked!). Now the user will get the
misleading message for a problem that didn't occur while opening the file, and may not be related
to I/O at all.
The root of the problem is that the programmer has coded a handler for Exception. This is almost
always a mistake:
• Catching Exception will catch all checked exceptions, and most unchecked exceptions as
well.
• Catching RuntimeException will catch most unchecked exceptions.
• Catching Error will catch unchecked exceptions that signal JVM internal errors. These errors
are generally not recoverable, and should not be caught.
• Catching Throwable will catch all possible exceptions.
https://riptutorial.com/ 551
The problem with catching too broad a set of exceptions is that the handler typically cannot handle
all of them appropriately. In the case of the Exception and so on, it is difficult for the programmer to
predict what could be caught; i.e. what to expect.
In general, the correct solution is to deal with the exceptions that are thrown. For example, you
can catch them and handle them in situ:
try {
InputStream is = new FileInputStream(fileName);
// process the input
} catch (FileNotFoundException ex) {
System.out.println("Could not open file " + fileName);
}
There are very few situations where catching Exception is appropriate. The only one that arises
commonly is something like this:
Here we genuinely want to deal with all exceptions, so catching Exception (or even Throwable) is
correct.
While catching the Throwable, Exception, Error and RuntimeException exceptions is bad, throwing
them is even worse.
The basic problem is that when your application needs to handle exceptions, the presence of the
top level exceptions make it hard to discriminate between different error conditions. For example
try {
InputStream is = new FileInputStream(someFile); // could throw IOException
...
if (somethingBad) {
throw new Exception(); // WRONG
}
} catch (IOException ex) {
System.err.println("cannot open ...");
https://riptutorial.com/ 552
} catch (Exception ex) {
System.err.println("something bad happened"); // WRONG
}
The problem is that because we threw an Exception instance, we are forced to catch it. However
as described in another example, catching Exception is bad. In this situation, it becomes difficult to
discriminate between the "expected" case of an Exception that gets thrown if somethingBad is true,
and the unexpected case where we actually catch an unchecked exception such as
NullPointerException.
• We now have to remember all of the different reasons that we threw the top-level, and
discriminate / handle them.
• In the case of Exception and Throwable we also need to add these exceptions to the throws
clause of methods if we want the exception to propagate. This is problematic, as described
below.
In short, don't throw these exceptions. Throw a more specific exception that more closely
describes the "exceptional event" that has happened. If you need to, define and use a custom
exception class.
This advice means that certain other patterns should be avoided. For example:
try {
doSomething();
} catch (Exception ex) {
report(ex);
throw ex;
}
The above attempts to log all exceptions as they pass, without definitively handling them.
Unfortunately, prior to Java 7, the throw ex; statement caused the compiler to think that any
Exception
https://riptutorial.com/ 553
could be thrown. That could force you to declare the enclosing method as throws Exception. From
Java 7 onwards, the compiler knows that the set of exceptions that could be (re-thrown) there is
smaller.
try {
// Some code
} catch (Exception) {
// Some error handling
}
Comes with a lot of different problems. But one perticular problem is that it can lead to deadlocks
as it breaks the interrupt system when writing multi-threaded applications.
If you start a thread you usually also need to be able to stop it abruptly for various reasons.
t.start();
The t.interrupt() will raise an InterruptedException in that thread, than is intended to shut down
the thread. But what if the Thread needs to clean up some resources before its completely
stopped? For this it can catch the InterruptedException and do some cleanup.
https://riptutorial.com/ 554
// In this case a simple return would do.
// But if you are not 100% sure that the thread ends after
// catching the InterruptedException you will need to raise another
// one for the layers surrounding this code.
Thread.currentThread().interrupt();
}
}
}
But if you have a catch-all expression in your code, the InterruptedException will be caught by it as
well and the interruption will not continue. Which in this case could lead to a deadlock as the
parent thread waits indefinitely for this thead to stop with t.join().
So it is better to catch Exceptions individually, but if you insist on using a catch-all, at least catch
the InterruptedException individually beforehand.
Thread.currentThread().interrupt();
}
}
}
https://riptutorial.com/ 555
There is a mantra that some Java experts are wont to recite:
The essence of this is that is it is a bad idea (in Java) to use exceptions and exception handling to
implement normal flow control. For example, compare these two ways of dealing with a parameter
that could be null.
In this example, we are (by design) treating the case where word is null as if it is an empty word.
The two versions deal with null either using conventional if ... else and or try ... catch. How should
we decide which version is better?
The first criterion is readability. While readability is hard to quantify objectively, most programmers
would agree that the essential meaning of the first version is easier to discern. Indeed, in order to
truly understand the second form, you need to understand that a NullPointerException cannot be
thrown by the Math.min or String.substring methods.
The second criterion is efficiency. In releases of Java prior to Java 8, the second version is
significantly (orders of magnitude) slower than the first version. In particular, the construction of an
exception object entails capturing and recording the stackframes, just in case the stacktrace is
required.
On the other hand, there are many situations where using exceptions is more readable, more
efficient and (sometimes) more correct than using conditional code to deal with "exceptional"
events. Indeed, there are rare situations where it is necessary to use them for "non-exceptional"
events; i.e. events that occur relatively frequently. For the latter, it is worth looking at ways to
reduce the overheads of creating exception objects.
One of the more annoying things that programmers can do is to scatter calls to printStackTrace()
throughout their code.
The problem is that the printStackTrace() is going to write the stacktrace to standard output.
https://riptutorial.com/ 556
• For an application that is intended for end-users who are not Java programmers, a
stacktrace is uninformative at best, and alarming at worst.
• For a server-side application, the chances are that nobody will look at the standard output.
A better idea is to not call printStackTrace directly, or if you do call it, do it in a way that the stack
trace is written to a log file or error file rather than to the end-user's console.
One way to do this is to use a logging framework, and pass the exception object as a parameter of
the log event. However, even logging the exception can be harmful if done injudiciously. Consider
the following:
If the exception is thrown in method2, you are likely to see two copies of the same stacktrace in the
logfile, corresponding to the same failure.
In short, either log the exception or re-throw it further (possibly wrapped with another exception).
Don't do both.
Throwable has two direct subclasses, Exception and Error. While it's possible to create a new class
that extends Throwable directly, this is inadvisable as many applications assume only Exception and
Error exist.
More to the point there is no practical benefit to directly subclassing Throwable, as the resulting
class is, in effect, simply a checked exception. Subclassing Exception instead will result in the
same behavior, but will more clearly convey your intent.
https://riptutorial.com/ 557
Chapter 84: Java Pitfalls - Language syntax
Introduction
Several Java programming language misusage might conduct a program to generate incorrect
results despite being compiled correctly. This topic main purpose is to list common pitfalls with
their causes, and to propose the correct way to avoid falling in such problems.
Remarks
This topic is about specific aspects of the Java language syntax that are either error prone or that
that should not be used in certain ways.
Examples
Pitfall - Ignoring method visibility
Even experienced Java developers tend to think that Java has only three protection modifiers. The
language actually has four! The package private (a.k.a. default) level of visibility is often
forgotten.
You should pay attention to what methods you make public. The public methods in an application
are the application’s visible API. This should be as small and compact as possible, especially if
you are writing a reusable library (see also the SOLID principle). It is important to similarly
consider the visibility of all methods, and to only use protected or package private access where
appropriate.
When you declare methods that should be private as public, you expose the internal
implementation details of the class.
A corollary to this is that you only unit test the public methods of your class - in fact you can only
test public methods. It is bad practice to increase the visibility of private methods just to be able to
run unit tests against those methods. Testing public methods that call the methods with more
restrictive visibility should be sufficient to test an entire API. You should never expand your API
with more public methods only to allow unit testing.
These Java issues can be very embarrassing, and sometimes remain undiscovered until run in
production. Fallthrough behavior in switch statements is often useful; however, missing a “break”
keyword when such behavior is not desired can lead to disastrous results. If you have forgotten to
put a “break” in “case 0” in the code example below, the program will write “Zero” followed by
“One”, since the control flow inside here will go through the entire “switch” statement until it
reaches a “break”. For example:
https://riptutorial.com/ 558
public static void switchCasePrimer() {
int caseIndex = 0;
switch (caseIndex) {
case 0:
System.out.println("Zero");
case 1:
System.out.println("One");
break;
case 2:
System.out.println("Two");
break;
default:
System.out.println("Default");
}
}
In most cases, the cleaner solution would be to use interfaces and move code with specific
behaviour into separate implementations (composition over inheritance)
switch(caseIndex) {
[...]
case 2:
System.out.println("Two");
// fallthrough
default:
System.out.println("Default");
This is a mistake that causes real confusion for Java beginners, at least the first time that they do
it. Instead of writing this:
if (feeling == HAPPY)
System.out.println("Smile");
else
System.out.println("Frown");
if (feeling == HAPPY);
System.out.println("Smile");
else
System.out.println("Frown");
and are puzzled when the Java compiler tells them that the else is misplaced. The Java compiler
with interpret the above as follows:
if (feeling == HAPPY)
/*empty statement*/ ;
https://riptutorial.com/ 559
System.out.println("Smile"); // This is unconditional
else // This is misplaced. A statement cannot
// start with 'else'
System.out.println("Frown");
In other cases, there will be no be compilation errors, but the code won't do what the programmer
intends. For example:
only prints "Hello" once. Once again, the spurious semicolon means that the body of the for loop
is an empty statement. That means that the println call that follows is unconditional.
Another variation:
This will give a "Cannot find symbol" error for i. The presence of the spurious semicolon means
that the println call is attempting to use i outside of its scope.
In those examples, there is a straight-forward solution: simply delete the spurious semicolon.
However, there are some deeper lessons to be drawn from these examples:
1. The semicolon in Java is not "syntactic noise". The presence or absence of a semicolon can
change the meaning of your program. Don't just add them at the end of every line.
2. Don't trust your code's indentation. In the Java language, extra whitespace at the beginning
of a line is ignored by the compiler.
3. Use an automatic indenter. All IDEs and many simple text editors understand how to
correctly indent Java code.
4. This is the most important lesson. Follow the latest Java style guidelines, and put braces
around the "then" and "else" statements and the body statement of a loop. The open brace (
{) should not be on a new line.
If the programmer followed the style rules then the if example with a misplaced semicolons would
look like this:
if (feeling == HAPPY); {
System.out.println("Smile");
} else {
System.out.println("Frown");
}
That looks odd to an experienced eye. If you auto-indented that code, it would probably look like
this:
https://riptutorial.com/ 560
if (feeling == HAPPY); {
System.out.println("Smile");
} else {
System.out.println("Frown");
}
Pitfall - Leaving out braces: the "dangling if" and "dangling else" problems
The latest version of the Oracle Java style guide mandates that the "then" and "else" statements in
an if statement should always be enclosed in "braces" or "curly brackets". Similar rules apply to
the bodies of various loop statements.
This is not actually required by Java language syntax. Indeed, if the "then" part of an if statement
is a single statement, it is legal to leave out the braces
if (a)
doSomething();
or even
if (a) doSomething();
However there are dangers in ignoring Java style rules and leaving out the braces. Specifically,
you significantly increase the risk that code with faulty indentation will be misread.
if (a)
doSomething();
doSomeMore();
This code seems to say that the calls to doSomething and doSomeMore will both occur if and only if a is
true. In fact, the code is incorrectly indented. The Java Language Specification that the
doSomeMore() call is a separate statement following the if statement. The correct indentation is as
follows:
if (a)
doSomething();
doSomeMore();
https://riptutorial.com/ 561
A second problem appears when we add else to the mix. Consider the following example with
missing braces.
if (a)
if (b)
doX();
else if (c)
doY();
else
doZ();
The code above seems to say that doZ will be called when a is false. In fact, the indentation is
incorrect once again. The correct indentation for the code is:
if (a)
if (b)
doX();
else if (c)
doY();
else
doZ();
If the code was written according to the Java style rules, it would actually look like this:
if (a) {
if (b) {
doX();
} else if (c) {
doY();
} else {
doZ();
}
}
To illustrate why that is better, suppose that you had accidentally mis-indented the code. You
might end up with something like this:
if (a) { if (a) {
if (b) { if (b) {
doX(); doX();
} else if (c) { } else if (c) {
doY(); doY();
} else { } else {
doZ(); doZ();
} }
} }
But in both cases, the mis-indented code "looks wrong" to the eye of an experienced Java
programmer.
https://riptutorial.com/ 562
public final class Person {
private final String firstName;
private final String lastName;
This code is not going to behave as expected. The problem is that the equals and hashcode
methods for Person do not override the standard methods defined by Object.
• The equals method has the wrong signature. It should be declared as equals(Object) not
equals(String).
• The hashcode method has the wrong name. It should be hashCode() (note the capital C).
These mistakes mean that we have declared accidental overloads, and these won't be used if
Person is used in a polymorphic context.
However, there is a simple way to deal with this (from Java 5 onwards). Use the @Override
annotation whenever you intend your method to be an override:
Java SE 5
@Override
public boolean equals(String other) {
....
}
@Override
public hashcode() {
....
}
}
When we add an @Override annotation to a method declaration, the compiler will check that the
method does override (or implement) a method declared in a superclass or interface. So in the
example above, the compiler will give us two compilation errors, which should be enough to alert
us to the mistake.
https://riptutorial.com/ 563
Pitfall - Octal literals
A Java beginner might be surprised to know that the above program prints the wrong answer. It
actually prints the sum of the numbers 1 to 8.
The reason is that an integer literal that starts with the digit zero ('0') is interpreted by the Java
compiler as an octal literal, not a decimal literal as you might expect. Thus, 010 is the octal number
10, which is 8 in decimal.
Sometimes, programmers who are new to Java make the mistake of defining a class with a name
that is the same as a widely used class. For example:
package com.example;
/**
* My string utilities
*/
public class String {
....
}
Then they wonder why they get unexpected errors. For example:
package com.example;
If you compile and then attempt to run the above classes you will get an error:
$ javac com/example/*.java
$ java com.example.Test
Error: Main method not found in class test.Test, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
Someone looking at the code for the Test class would see the declaration of main and look at its
signature and wonder what the java command is complaining about. But in fact, the java command
https://riptutorial.com/ 564
is telling the truth.
When we declare a version of String in the same package as Test, this version takes precedence
over the automatic import of java.lang.String. Thus, the signature of the Test.main method is
actually
instead of
and the java command will not recognize that as an entrypoint method.
Lesson: Do not define classes that have the same name as existing classes in java.lang, or other
commonly used classes in the Java SE library. If you do that, you are setting yourself open for all
sorts of obscure errors.
An experienced programmer would spot that as being clumsy and want to rewrite it as:
However, there is more wrong with ok == true than simple clumsiness. Consider this variation:
Here the programmer has mistyped == as = ... and now the code has a subtle bug. The expression
x = true unconditionally assigns true to x and then evaluates to true. In other words, the check
method will now print "It is OK" no matter what the parameter was.
The lesson here is to get out of the habit of using == false and == true. In addition to being
verbose, they make your coding more error prone.
https://riptutorial.com/ 565
Note: A possible alternative to ok == true that avoids the pitfall is to use Yoda conditions; i.e. put
the literal on the left side of the relational operator, as in true == ok. This works, but most
programmers would probably agree that Yoda conditions look odd. Certainly ok (or !ok) is more
concise and more natural.
import com.example.somelib.*;
import com.acme.otherlib.*;
Suppose that when when you first developed the code against version 1.0 of somelib and version
1.0 of otherlib. Then at some later point, you need to upgrade your dependencies to a later
versions, and you decide to use otherlib version 2.0. Also suppose that one of the changes that
they made to otherlib between 1.0 and 2.0 was to add a Context class.
Now when you recompile Test, you will get a compilation error telling you that Context is an
ambiguous import.
If you are familiar with the codebase, this probably is just a minor inconvenience. If not, then you
have some work to do to address this problem, here and potentially elsewhere.
The problem here is the wildcard imports. On the one hand, using wildcards can make your
classes a few lines shorter. On the other hand:
• Upwards compatible changes to other parts of your codebase, to Java standard libraries or
to 3rd party libraries can lead to compilation errors.
• Readability suffers. Unless you are using an IDE, figuring out which of the wildcard imports is
pulling in a named class can be difficult.
The lesson is that it is a bad idea to use wildcard imports in code that needs to be long lived.
Specific (non-wildcard) imports are not much effort to maintain if you use an IDE, and the effort is
worthwhile.
https://riptutorial.com/ 566
• Throwing an IllegalArgumentException using custom code.
• Using the Preconditions methods available in Google Guava library.
• Using the Validate methods available in Apache Commons Lang3 library.
This is what the Java Language Specification (JLS 14.10, for Java 8) advises on this matter:
Typically, assertion checking is enabled during program development and testing, and
disabled for deployment, to improve performance.
Because assertions may be disabled, programs must not assume that the expressions
contained in assertions will be evaluated. Thus, these boolean expressions should
generally be free of side effects. Evaluating such a boolean expression should not
affect any state that is visible after the evaluation is complete. It is not illegal for a
boolean expression contained in an assertion to have a side effect, but it is generally
inappropriate, as it could cause program behavior to vary depending on whether
assertions were enabled or disabled.
In light of this, assertions should not be used for argument checking in public methods.
Argument checking is typically part of the contract of a method, and this contract must
be upheld whether assertions are enabled or disabled.
A secondary problem with using assertions for argument checking is that erroneous
arguments should result in an appropriate run-time exception (such as
IllegalArgumentException, ArrayIndexOutOfBoundsException, or NullPointerException). An
assertion failure will not throw an appropriate exception. Again, it is not illegal to use
assertions for argument checking on public methods, but it is generally inappropriate. It
is intended that AssertionError never be caught, but it is possible to do so, thus the
rules for try statements should treat assertions appearing in a try block similarly to the
current treatment of throw statements.
// example:
Boolean ignore = null;
if (ignore == false) {
System.out.println("Do not ignore!");
}
}
}
The pitfall here is that null is compared to false. Since we're comparing a primitive boolean against
a Boolean, Java attempts to unbox the the Boolean Object into a primitive equivalent, ready for
comparison. However, since that value is null, a NullPointerException is thrown.
Java is incapable of comparing primitive types against null values, which causes a
NullPointerException at runtime. Consider the primitive case of the condition false == null; this
would generate a compile time error incomparable types: int and <null>.
https://riptutorial.com/ 567
Read Java Pitfalls - Language syntax online: https://riptutorial.com/java/topic/5382/java-pitfalls---
language-syntax
https://riptutorial.com/ 568
Chapter 85: Java Pitfalls - Nulls and
NullPointerException
Remarks
The value null is the default value for an uninitialized value of a field whose type is a reference
type.
NullPointerException (or NPE) is the exception that is thrown when you attempt to perform an
inappropriate operation on the null object reference. Such operations include:
• The get(key) method in the Map API will return a null if you call it with a key that doesn't have
a mapping.
• The getResource(path) and getResourceAsStream(path) methods in the ClassLoader and Class
APIs will return null if the resource cannot be found.
• The get() method in the Reference API will return null if the garbage collector has cleared the
reference.
• Various getXxxx methods in the Java EE servlet APIs will return null if you attempt fetch a
non-existent request parameter, session or session attribute and so on.
There are strategies for avoiding unwanted NPEs, such as explicitly testing for null or using "Yoda
Notation", but these strategies often have the undesirable result of hiding problems in your code
that really ought to be fixed.
Examples
Pitfall - Unnecessary use of Primitive Wrappers can lead to
https://riptutorial.com/ 569
NullPointerExceptions
Sometimes, programmers who are new Java will use primitive types and wrappers
interchangeably. This can lead to problems. Consider this example:
...
MyRecord record = new MyRecord();
record.a = 1; // OK
record.b = record.b + 1; // OK
record.c = 1; // OK
record.d = record.d + 1; // throws a NullPointerException
Our MyRecord class1 relies on default initialization to initialize the values on its fields. Thus, when
we new a record, the a and b fields will be set to zero, and the c and d fields will be set to null.
When we try to use the default initialized fields, we see that the int fields works all of the time, but
the Integer fields work in some cases and not others. Specifically, in the case that fails (with d),
what happens is that the expression on the right-hand side attempts to unbox a null reference,
and that is what causes the NullPointerException to be thrown.
• If the fields c and d need to be primitive wrappers, then either we should not be relying on
default initialization, or we should be testing for null. For former is the correct approach
unless there is a definite meaning for the fields in the null state.
• If the fields don't need to be primitive wrappers, then it is a mistake to make them primitive
wrappers. In addition to this problem, the primitive wrappers have extra overheads relative to
primitive types.
The lesson here is to not use primitive wrapper types unless you really need to.
1 - This class is not an example of good coding practice. For instance, a well-designed class would not have public
fields. However, that is not the point of this example.
Some programmers think that it is a good idea to save space by using a null to represent an
empty array or collection. While it is true that you can save a small amount of space, the flipside is
that it makes your code more complicated, and more fragile. Compare these two versions of a
method for summing an array:
The first version is how you would normally code the method:
/**
https://riptutorial.com/ 570
* Sum the values in an array of integers.
* @arg values the array to be summed
* @return the sum
**/
public int sum(int[] values) {
int sum = 0;
for (int value : values) {
sum += value;
}
return sum;
}
The second version is how you need to code the method if you are in the habit of using null to
represent an empty array.
/**
* Sum the values in an array of integers.
* @arg values the array to be summed, or null.
* @return the sum, or zero if the array is null.
**/
public int sum(int[] values) {
int sum = 0;
if (values != null) {
for (int value : values) {
sum += value;
}
}
return sum;
}
As you can see, the code is a bit more complicated. This is directly attributable to the decision to
use null in this way.
Now consider if this array that might be a null is used in lots of places. At each place where you
use it, you need to consider whether you need to test for null. If you miss a null test that needs to
be there, you risk a NullPointerException. Hence, the strategy of using null in this way leads to
your application being more fragile; i.e. more vulnerable to the consequences of programmer
errors.
The lesson here is to use empty arrays and empty lists when that is what you mean.
The space overhead is small, and there are other ways to minimize it if this this is a worthwhile
thing to do.
https://riptutorial.com/ 571
public String joinStrings(String a, String b) {
if (a == null) {
a = "";
}
if (b == null) {
b = "";
}
return a + ": " + b;
}
Often, this is accompanied with an assertion that is "best practice" to test for null like this to avoid
NullPointerException.
There are some underlying assumptions that need to be questioned before we can say if it is a
good idea to do this in our joinStrings:
The problem with "making good" is that it is liable to either hide the problem, or make it harder to
diagnose.
https://riptutorial.com/ 572
"making good" is liable to impact on the performance of your application.
In summary
If null is a meaningful value, then testing for the null case is the correct approach. The corollary is
that if a null value is meaningful, then this should be clearly documented in the javadocs of any
methods that accept the null value or return it.
Otherwise, it is a better idea to treat an unexpected null as a programming error, and let the
NullPointerException happen so that the developer gets to know there is a problem in the code.
Some Java programmers have a general aversion to throwing or propagating exceptions. This
leads to code like the following:
The problem is that the getReader is returning a null as a special value to indicate that the Reader
could not be opened. Now the returned value needs to be tested to see if it is null before it is
used. If the test is left out, the result will be a NullPointerException.
In fact, assuming that the exception did need to be caught early like this, there were a couple of
alternatives to returning null:
1. It would be possible to implement a NullReader class; e.g. one where API's operations
behaves as if the reader was already at the "end of file" position.
2. With Java 8, it would be possible to declare getReader as returning an Optional<Reader>.
Pitfall - Not checking if an I/O stream isn't even initialized when closing it
To prevent memory leaks, one should not forget to close an input stream or an output stream
whose job is done. This is usually done with a try-catch-finally statement without the catch part:
https://riptutorial.com/ 573
void writeNullBytesToAFile(int count, String filename) throws IOException {
FileOutputStream out = null;
try {
out = new FileOutputStream(filename);
for(; count > 0; count--)
out.write(0);
} finally {
out.close();
}
}
While the above code might look innocent, it has a flaw that can make debugging impossible. If
the line where out is initialized (out = new FileOutputStream(filename)) throws an exception, then
out will be null when out.close() is executed, resulting in a nasty NullPointerException!
To prevent this, simply make sure the stream isn't null before trying to close it.
An even better approach is to try-with-resources, since it'll automatically close the stream with a
probability of 0 to throw an NPE without the need of a finally block.
if ("A".equals(someString)) {
// do something
}
This does "prevent" or "avoid" a possible NullPointerException in the case that someString is null.
Furthermore, it is arguable that
"A".equals(someString)
is better than:
https://riptutorial.com/ 574
someString != null && someString.equals("A")
(It is more concise, and in some circumstances it might be more efficient. However, as we argue
below, conciseness could be a negative.)
However, the real pitfall is using the Yoda test to avoid NullPointerExceptions as a matter of habit.
When you write "A".equals(someString) you are actually "making good" the case where someString
happens to be null. But as another example (Pitfall - "Making good" unexpected nulls ) explains,
"making good" null values can be harmful for a variety of reasons.
This means that Yoda conditions are not "best practice"1. Unless the null is expected, it is better
to let the NullPointerException happen so that you can get a unit test failure (or a bug report). That
allows you to find and fix the bug that caused the unexpected / unwanted null to appear.
Yoda conditions should only be used in cases where the null is expected because the object you
are testing has come from an API that is documented as returning a null. And arguably, it could
be better to use one of the less pretty ways expressing the test because that helps to highlight the
null test to someone who is reviewing your code.
1 - According to Wikipedia: "Best coding practices are a set of informal rules that the software development
community has learned over time which can help improve the quality of software.". Using Yoda notation does not
achieve this. In a lot of situations, it makes the code worse.
https://riptutorial.com/ 575
Chapter 86: Java Pitfalls - Performance
Issues
Introduction
This topic describes a number of "pitfalls" (i.e. mistakes that novice java programmers make) that
relate to Java application performance.
Remarks
This topic describes some "micro" Java coding practices that are inefficient. In most cases, the
inefficiencies are relatively small, but it is still worth avoiding them is possible.
Examples
Pitfall - The overheads of creating log messages
TRACE and DEBUG log levels are there to be able to convey high detail about the operation of the
given code at runtime. Setting the log level above these is usually recommended, however some
care must be taken for these statements to not affect performance even when seemingly "turned
off".
Even when the log level is set to INFO, arguments passed to debug() will be evaluated on each
execution of the line. This makes it unnecessarily consuming on several counts:
Solution
Most logging framework provide means to create log messages using fix strings and object
references. The log message will be evaluated only if the message is actually logged. Example:
https://riptutorial.com/ 576
This works very well as long as all parameters can be converted to strings using
String.valueOf(Object). If the log message compuation is more complex, the log level can be
checked before logging:
if (LOG.isDebugEnabled()) {
// Argument expression evaluated only when DEBUG is enabled
LOG.debug("Request coming from {}, parameters: {}", myInetAddress,
Arrays.toString(veryLongParamArray);
}
Here, LOG.debug() with the costly Arrays.toString(Obect[]) computation is processed only when
DEBUG is actually enabled.
Unfortunate this code is inefficient if the words list is long. The root of the problem is this statement:
For each loop iteration, this statement creates a new message string containing a copy of all
characters in the original message string with extra characters appended to it. This generates a lot
of temporary strings, and does a lot of copying.
When we analyse joinWords, assuming that there are N words with an average length of M, we find
that O(N) temporary strings are created and O(M.N2) characters will be copied in the process. The
N2 component is particularly troubling.
The recommended approach for this kind of problem1 is to use a StringBuilder instead of string
concatenation as follows:
The analysis of joinWords2 needs to take account of the overheads of "growing" the StringBuilder
backing array that holds the builder's characters. However, it turns out that the number of new
objects created is O(logN) and that the number of characters copied is O(M.N) characters. The
https://riptutorial.com/ 577
latter includes characters copied in the final toString() call.
(It may be possible to tune this further, by creating the StringBuilder with the correct capacity to
start with. However, the overall complexity remains the same.)
Returning to the original joinWords method, it turns out that the critical statement will be optimized
by a typical Java compiler to something like this:
However, the Java compiler will not "hoist" the StringBuilder out of the loop, as we did by hand in
the code for joinWords2.
Reference:
1 - In Java 8 and later, the Joiner class can be used to solve this particular problem. However, that is not what this
example is really supposed to be about.
The Java language allows you to use new to create instances Integer, Boolean and so on, but it is
generally a bad idea. It is better to either use autoboxing (Java 5 and later) or the valueOf method.
The reason that using new Integer(int) explicitly is a bad idea is that it creates a new object
(unless optimized out by JIT compiler). By contrast, when autoboxing or an explicit valueOf call are
used, the Java runtime will try to reuse an Integer object from a cache of pre-existing objects.
Each time the runtime has a cache "hit", it avoids creating an object. This also saves heap
memory and reduces GC overheads caused by object churn.
Notes:
1. In recent Java implementations, autoboxing is implemented by calling valueOf, and there are
caches for Boolean, Byte, Short, Integer, Long and Character.
2. The caching behavior for the integral types is mandated by the Java Language Specification.
Using new String(String) to duplicate a string is inefficient and almost always unnecessary.
• String objects are immutable, so there is no need to copy them to protect against changes.
• In some older versions of Java, String objects can share backing arrays with other String
https://riptutorial.com/ 578
objects. In those versions, it is possible to leak memory by creating a (small) substring of a
(large) string and retaining it. However, from Java 7 onwards, String backing arrays are not
shared.
In the absence of any tangible benefit, calling new String(String) is simply wasteful:
"Calling the gc method suggests that the Java Virtual Machine expend effort toward
recycling unused objects in order to make the memory they currently occupy available
for quick reuse. When control returns from the method call, the Java Virtual Machine
has made a best effort to reclaim space from all discarded objects."
There are a couple of important points that can be drawn from this:
1. The use of the word "suggests" rather than (say) "tells" means that the JVM is free to ignore
the suggestion. The default JVM behavior (recent releases) is to follow the suggestion, but
this can be overridden by setting -XX:+DisableExplicitGC when when launching the JVM.
2. The phrase "a best effort to reclaim space from all discarded objects" implies that calling gc
will trigger a "full" garbage collection.
First, running a full garbage collection is expensive. A full GC involves visiting and "marking" every
object that is still reachable; i.e. every object that is not garbage. If you trigger this when there isn't
much garbage to be collected, then the GC does a lot of work for relatively little benefit.
Second, a full garbage collection is liable to disturb the "locality" properties of the objects that are
not collected. Objects that are allocated by the same thread at roughly the same time tend to be
allocated close together in memory. This is good. Objects that are allocated at the same time are
likely to be related; i.e. reference each other. If your application uses those references, then the
chances are that memory access will be faster because of various memory and page caching
effects. Unfortunately, a full garbage collection tend to move objects around so that objects that
were once close are now further apart.
Third, running a full garbage collection is liable to make your application pause until the collection
is complete. While this is happening, your application will be non-responsive.
In fact, the best strategy is to let the JVM decide when to run the GC, and what kind of collection
https://riptutorial.com/ 579
to run. If you don't interfere, the JVM will choose a time and collection type that optimizes
throughput or minimizes GC pause times.
At the beginning we said "... (almost always) a bad idea ...". In fact there are a couple of scenarios
where it might be a good idea:
1. If you are implementing a unit test for some code that is garbage collection sensitive (e.g.
something involving finalizers or weak / soft / phantom references) then calling System.gc()
may be necessary.
2. In some interactive applications, there can be particular points in time where the user won't
care if there is a garbage collection pause. One example is a game where there are natural
pauses in the "play"; e.g. when loading a new level.
int a = 1000;
int b = a + 1;
and
Integer a = 1000;
Integer b = a + 1;
Answer: The two versions look almost the identical, but the first version is a lot more efficient than
the second one.
The second version is using a representation for the numbers that uses more space, and is relying
on auto-boxing and auto-unboxing behind the scenes. In fact the second version is directly
equivalent to the following code:
Comparing this to the other version that uses int, there are clearly three extra method calls when
Integer is used. In the case of valueOf, the calls are each going to create and initialize a new
Integer object. All of this extra boxing and unboxing work is likely to make the second version an
order of magnitude slower than the first one.
In addition to that, the second version is allocating objects on the heap in each valueOf call. While
the space utilization is platform specific, it is likely to be in the region of 16 bytes for each Integer
object. By contrast, the int version needs zero extra heap space, assuming that a and b are local
variables.
https://riptutorial.com/ 580
Another big reason why primitives are faster then their boxed equivalent is how their respective
array types are laid out in memory.
If you take int[] and Integer[] as an example, in the case of an int[] the int values are
contiguously laid out in memory. But in the case of an Integer[] it's not the values that are laid out,
but references (pointers) to Integer objects, which in turn contain the actual int values.
Besides being an extra level of indirection, this can be a big tank when it comes to cache locality
when iterating over the values. In the case of an int[] the CPU could fetch all the values in the
array, into it's cache at once, because they are contiguous in memory. But in the case of an
Integer[] the CPU potentially has to do an additional memory fetch for each element, since the
array only contains references to the actual values.
In short, using primitive wrapper types is relatively expensive in both CPU and memory resources.
Using them unnecessarily is in efficient.
That is because it requires a map lookup (the get() method) for each key in the map. This lookup
may not be efficient (in a HashMap, it entails calling hashCode on the key, then looking up the
correct bucket in internal data structures, and sometimes even calling equals). On a large map, this
may not be a trivial overhead.
The correct way of avoiding this is to iterate on the map's entries, which is detailed in the
Collections topic
The Java Collections Framework provides two related methods for all Collection objects:
Both methods can be used to test for collection emptiness. For example:
While these approaches look the same, some collection implementations do not store the size. For
such a collection, the implementation of size() needs to calculate the size each time it is called.
https://riptutorial.com/ 581
For instance:
• A simple linked list class (but not the java.util.LinkedList) might need to traverse the list to
count the elements.
• The ConcurrentHashMap class needs to sum the entries in all of the map's "segments".
• A lazy implementation of a collection might need to realize the entire collection in memory in
order to count the elements.
By contrast, an isEmpty() method only needs to test if there is at least one element in the
collection. This does not entail counting the elements.
While size() == 0 is not always less efficient that isEmpty(), it is inconceivable for a properly
implemented isEmpty() to be less efficient than size() == 0. Hence isEmpty() is preferred.
Regular expression matching is a powerful tool (in Java, and in other contexts) but it does have
some drawbacks. One of these that regular expressions tends to be rather expensive.
/**
* Test if all strings in a list consist of English letters and numbers.
* @param strings the list to be checked
* @return 'true' if an only if all strings satisfy the criteria
* @throws NullPointerException if 'strings' is 'null' or a 'null' element.
*/
public boolean allAlphanumeric(List<String> strings) {
for (String s : strings) {
if (!s.matches("[A-Za-z0-9]*")) {
return false;
}
}
return true;
}
This code is correct, but it is inefficient. The problem is in the matches(...) call. Under the hood,
s.matches("[A-Za-z0-9]*") is equivalent to this:
Pattern.matches(s, "[A-Za-z0-9]*")
Pattern.compile("[A-Za-z0-9]*").matcher(s).matches()
The Pattern.compile("[A-Za-z0-9]*") call parses the regular expression, analyze it, and construct a
Pattern object that holds the data structure that will be used by the regex engine. This is a non-
trivial computation. Then a Matcher object is created to wrap the s argument. Finally we call match()
https://riptutorial.com/ 582
to do the actual pattern matching.
The problem is that this work is all repeated for each loop iteration. The solution is to restructure
the code as follows:
Instances of this class are immutable and are safe for use by multiple concurrent
threads. Instances of the Matcher class are not safe for such use.
if (s.matches(".*[0-9]{3}.*")) {
System.out.println("matches");
}
or
if (Pattern.compile("[0-9]{3}").matcher(s).find()) {
System.out.println("matches");
}
The first one is more concise, but it is also likely to be less efficient. On the face of it, the first
version is going to try to match the entire string against the pattern. Furthermore, since ".*" is a
"greedy" pattern, the pattern matcher is likely to advance "eagerly" try to the end of the string, and
backtrack until it finds a match.
By contrast, the second version will search from left to right and will stop searching as soon as it
finds the 3 digits in a row.
https://riptutorial.com/ 583
Pattern.compile("ABC").matcher(s).find()
s.contains("ABC")
except that the latter is a lot more efficient. (Even if you can amortize the cost of compiling the
regular expression.)
Often, the non-regex form is more complicated. For example, the test performed by the matches()
call the earlier allAlplanumeric method can be rewritten as:
Now that is more code than using a Matcher, but it is also going to be significantly faster.
Catastrophic Backtracking
(This is potentially a problem with all implementations of regular expressions, but we will mention it
here because it is a pitfall for Pattern usage.)
The first println call will quickly print true. The second one will print false. Eventually. Indeed, if
you experiment with the code above, you will see that each time you add an A before the C, the
time take will double.
This is behavior is an example of catastrophic backtracking. The pattern matching engine that
implements the regex matching is fruitlessly trying all of the possible ways that the pattern might
match.
Let us look at what (A+)+B actually means. Superficially, it seems to say "one or more A characters
followed by a B value", but in reality it says one or more groups, each of which consists of one or
more A characters. So, for example:
https://riptutorial.com/ 584
• 'AAAB' matches four ways: '(AAA)B' or '(AA)(A)Bor '(A)(AA)B or '(A)(A)(A)B`
• and so on
In other words, the number of possible matches is 2N where N is the number of A characters.
The above example is clearly contrived, but patterns that exhibit this kind of performance
characteristics (i.e. O(2^N) or O(N^K) for a large K) arise frequently when ill-considered regular
expressions are used. There are some standard remedies:
Finally, beware of situations where a user or an API client can supply a regex string with
pathological characteristics. That can lead to accidental or deliberate "denial of service".
References:
their initial reaction is to intern strings so that they can use ==. (After all == is faster than calling
String.equals(...), isn't it.)
Fragility
First of all, you can only safely use == if you know that all of the String objects you are testing have
been interned. The JLS guarantees that String literals in your source code will have been interned.
However, none of the standard Java SE APIs guarantee to return interned strings, apart from
String.intern(String) itself. If you miss just one source of String objects that haven't been
interned, your application will be unreliable. That unreliability will manifest itself as false negatives
rather than exceptions which is liable to make it harder to detect.
https://riptutorial.com/ 585
Under the hood, interning works by maintaining a hash table that contains previously interned
String objects. Some kind of weak reference mechanism is used so that the interning hash table
does not become a storage leak. While the hash table is implemented in native code (unlike
HashMap, HashTable and so on), the intern calls are still relatively costly in terms of CPU and
memory used.
This cost has to be compared with the saving of we are going to get by using == instead of equals.
In fact, we are not going to break even unless each interned string is compared with other strings
"a few" times.
(Aside: the few situations where interning is worthwhile tend to be about reducing the memory foot
print of an application where the same strings recur many times, and those strings have a long
lifetime.)
For versions of Java prior to Java 7, interned strings are held in the "PermGen" space which is
collected infrequently. If PermGen needs to be collected, this (typically) triggers a full garbage
collection. If the PermGen space fills completely, the JVM crashes, even if there was free space in
the regular heap spaces.
In Java 7, the string pool was moved out of "PermGen" into the normal heap. However, the hash
table is still going to be a long-lived data structure, which is going to cause any interned strings to
be long-lived. (Even if the interned string objects were allocated in Eden space they would most
likely be promoted before they were collected.)
Thus in all cases, interning a string is going to prolong its lifetime relative to an ordinary string.
That will increase the garbage collection overheads over the lifetime of the JVM.
The second issue is that the hash table needs to use a weak reference mechanism of some kind
to prevent string interning leaking memory. But such a mechanism is more work for the garbage
collector.
These garbage collection overheads are difficult to quantify, but there is little doubt that they do
exist. If you use intern extensively, they could be significant.
The bottom line is that if you do intend to use intern intensively in your code, it is advisable to pick
https://riptutorial.com/ 586
a version of Java where the hashtable size is tunable and make sure that you tune the size it
appropriately. Otherwise, the performance of intern is liable to degrade as the pool gets larger.
(There are simpler / more effective ways to launch a DoS attack against a service. However, this
vector could be used if the goal of the DoS attack is to break security, or to evade first-line DoS
defences.)
import java.io.*;
(We have deliberated omitted normal argument checking, error reporting and so on because they
are not relevant to point of this example.)
If you compile the above code and use it to copy a huge file, you will notice that it is very slow. In
fact, it will be at least a couple of orders of magnitude slower than the standard OS file copy
utilities.
The primary reason that the example above is slow (in the large file case) is that it is performing
one-byte reads and one-byte writes on unbuffered byte streams. The simple way to improve
performance is to wrap the streams with buffered streams. For example:
import java.io.*;
https://riptutorial.com/ 587
public static void main(String[] args) throws Exception {
try (InputStream is = new BufferedInputStream(
new FileInputStream(args[0]));
OutputStream os = new BufferedOutputStream(
new FileOutputStream(args[1]))) {
int octet;
while ((octet = is.read()) != -1) {
os.write(octet);
}
}
}
}
These small changes will improve data copy rate by at least a couple of orders of magnitude,
depending on various platform-related factors. The buffered stream wrappers cause the data to be
read and written in larger chunks. The instances both have buffers implemented as byte arrays.
• With is, data is read from the file into the buffer a few kilobytes at a time. When read() is
called, the implementation will typically return a byte from the buffer. It will only read from the
underlying input stream if the buffer has been emptied.
• The behavior for os is analogous. Calls to os.write(int) write single bytes into the buffer.
Data is only written to the output stream when the buffer is full, or when os is flushed or
closed.
• InputStream and OutputStream are the base APIs for stream-based binary I/O
• Reader and Writer are the base APIs for stream-based text I/O.
For text I/O, BufferedReader and BufferedWriter are the equivalents for BufferedInputStream and
BufferedOutputStream.
• Java method in a Java application, or native procedure calls in the JVM's native runtime
libraries are fast. They typically take a couple of machine instructions and have minimal
performance impact.
• By contrast, JVM runtime calls to the operating system are not fast. They involve something
known as a "syscall". The typical pattern for a syscall is as follows:
https://riptutorial.com/ 588
3. The trap handler switched to privileged state and changes the virtual memory
mappings. Then it dispatches to the code to handle the specific syscall.
4. The syscall handler checks the arguments, taking care that it isn't being told to access
memory that the user process should not see.
5. The syscall specific work is performed. In the case of a read syscall, this may involve:
1. checking that there is data to be read at the file descriptor's current position
2. calling the file system handler to fetch the required data from disk (or wherever it
is stored) into the buffer cache,
3. copying data from the buffer cache to the JVM-supplied address
4. adjusting thstream pointerse file descriptor position
6. Return from the syscall. This entails changing VM mappings again and switching out of
privileged state.
As you can imagine, performing a single syscall can thousands of machine instructions.
Conservatively, at least two orders of magnitude longer than a regular method call. (Probably
three or more.)
Given this, the reason that buffered streams make a big difference is that they drastically reduce
the number of syscalls. Instead of doing a syscall for each read() call, the buffered input stream
reads a large amount of data into a buffer as required. Most read() calls on the buffered stream do
some simple bounds checking and return a byte that was read previously. Similar reasoning
applies in the output stream case, and also the character stream cases.
(Some people think that buffered I/O performance comes from the mismatch between the read
request size and the size of a disk block, disk rotational latency and things like that. In fact, a
modern OS uses a number of strategies to ensure that the application typically doesn't need to
wait for the disk. This is not the real explanation.)
https://riptutorial.com/ 589
Chapter 87: Java Pitfalls - Threads and
Concurrency
Examples
Pitfall: incorrect use of wait() / notify()
The methods object.wait(), object.notify() and object.notifyAll() are meant to be used in a very
specific way. (see http://stackoverflow.com/documentation/java/5409/wait-
notify#t=20160811161648303307 )
The reason this is wrong is that it depends on some other thread to call lock.notify() or
lock.notifyAll(), but nothing guarantees that the other thread did not make that call before the
consumer thread called lock.wait().
lock.notify() and lock.notifyAll() do not do anything at all if some other thread is not already
waiting for the notification. The thread that calls myConsumer() in this example will hang forever if it
is too late to catch the notification.
https://riptutorial.com/ 590
(The design for wait() / notify() requires that the lock is held because this is necessary to avoid
systemic race conditions. If it was possible to call wait() or notify() without locking, then it would
be impossible to implement the primary use-case for these primitives: waiting for a condition to
occur.)
The javadoc for the Thread class shows two ways to define and use a thread:
Using a Runnable:
The custom thread class approach works, but it has a few problems:
https://riptutorial.com/ 591
1. It is awkward to use PrimeThread in a context that uses a classic thread pool, an executor, or
the ForkJoin framework. (It is not impossible, because PrimeThread indirectly implements
Runnable, but using a custom Thread class as a Runnable is certainly clumsy, and may not be
viable ... depending on other aspects of the class.)
2. There is more opportunity for mistakes in other methods. For example, if you declared a
PrimeThread.start() without delegating to Thread.start(), you would end up with a "thread"
that ran on the current thread.
The approach of putting the thread logic into a Runnable avoids these problems. Indeed, if you use
an anonymous class (Java 1.1 onwards) to implement the Runnable the result is more succinct, and
more readable than the examples above.
With a lambda expression (Java 8 onwards), the above example would become even more
elegant:
A lot of people who are new to multi-threading think that using threads automatically make an
application go faster. In fact, it is a lot more complicated than that. But one thing that we can state
with certainty is that for any computer there is a limit on the number of threads that can be run at
the same time:
This tells us that simply creating more and more Java threads cannot make the application go
faster and faster. But there are other considerations as well:
• Each thread requires an off-heap memory region for its thread stack. The typical (default)
thread stack size is 512Kbytes or 1Mbytes. If you have a significant number of threads, the
memory usage can be significant.
• Each active thread will refer to a number of objects in the heap. That increases the working
https://riptutorial.com/ 592
set of reachable objects, which impacts on garbage collection and on physical memory
usage.
• The overheads of switching between threads is non-trivial. It typically entails a switch into the
OS kernel space to make a thread scheduling decision.
• The overheads of thread synchronization and inter-thread signaling (e.g. wait(), notify() /
notifyAll) can be significant.
Depending on the details of your application, these factors generally mean that there is a "sweet
spot" for the number of threads. Beyond that, adding more threads gives minimal performance
improvement, and can make performance worse.
If your application create for each new task, then an unexpected increase in the workload (e.g. a
high request rate) can lead to catastrophic behavior.
A better way to deal with this is to use bounded thread pool whose size you can control (statically
or dynamically). When there is too much work to do, the application needs to queue the requests.
If you use an ExecutorService, it will take care of the thread pool management and task queuing.
The first benchmark simply creates, starts and joins threads. The thread's Runnable does no work.
$ java ThreadTest
34627.91355
33596.66021
33661.19084
33699.44895
33603.097
33759.3928
33671.5719
33619.46809
33679.92508
33500.32862
33409.70188
https://riptutorial.com/ 593
33475.70541
33925.87848
33672.89529
^C
On a typical modern PC running Linux with 64bit Java 8 u101, this benchmark shows an average
time taken to create, start and join thread of between 33.6 and 33.9 microseconds.
The second benchmark does the equivalent to the first but using an ExecutorService to submit
tasks and a Future to rendezvous with the end of the task.
import java.util.concurrent.*;
$ java ExecutorTest
6714.66053
5418.24901
5571.65213
5307.83651
5294.44132
5370.69978
5291.83493
5386.23932
5384.06842
5293.14126
5445.17405
5389.70685
^C
As you can see, the averages are between 5.3 and 5.6 microseconds.
While the actual times will depend on a variety of factors, the difference between these two results
is significant. It is clearly faster to use a thread pool to recycle threads than it is to create new
threads.
https://riptutorial.com/ 594
public class ThreadTest implements Runnable {
The intent of this program is intended to start a thread, let it run for 1000 milliseconds, and then
cause it to stop by setting the stop flag.
An application does not necessarily stop when the main method returns. If another thread has been
created, and that thread has not been marked as a daemon thread, then the application will
continue to run after the main thread has ended. In this example, that means that the application
will keep running until child thread ends. That should happens when tt.stop is set to true.
But that is actually not strictly true. In fact, the child thread will stop after it has observed stop with
the value true. Will that happen? Maybe yes, maybe no.
The Java Language Specification guarantees that memory reads and writes made in a thread are
visible to that thread, as per the order of the statements in the source code. However, in general,
this is NOT guaranteed when one thread writes and another thread (subsequently) reads. To get
guaranteed visibility, there needs to be a chain of happens-before relations between a write and a
subsequent read. In the example above, there is no such chain for the update to the stop flag, and
therefore it is not guaranteed that the child thread will see stop change to true.
(Note to authors: There should be a separate Topic on the Java Memory Model to go into the deep
technical details.)
https://riptutorial.com/ 595
private volatile boolean stop = false;
For a volatile variable, the JLS specifies that there is a happens-before relation between a
write by one thread and a later read by a second thread.
In addition to ensuring that there is mutual exclusion, the JLS specifies that there is a happens-
before relation between the releasing a mutex in one thread and gaining the same mutex in a
second thread.
However, that fact does not mean that the effects of update will be visible simultaneously to all
threads. Only a proper chain of happens-before relations will guarantee that.
It actually comes down to a compromise between performance and ease of use (for the
https://riptutorial.com/ 596
programmer).
A modern computer architecture consists of multiple processors (cores) with individual register
sets. Main memory is accessible either to all processors or to groups of processors. Another
property of modern computer hardware is that access to registers is typically orders of magnitude
faster to access than access to main memory. As the number of cores scales up, it is easy to see
that reading and writing to main memory can become a system's main performance bottleneck.
This mismatch is addressed by implementing one or more levels of memory caching between the
processor cores and main memory. Each core access memory cells via its cache. Normally, a
main memory read only happens when there is a cache miss, and a main memory write only
happens when a cache line needs to be flushed. For an application where each core's working set
of memory locations will fit into its cache, the core speed is no longer limited by main memory
speed / bandwidth.
But that gives us a new problem when multiple cores are reading and writing shared variables.
The latest version of a variable may sit in one core's cache. Unless the that core flushes the cache
line to main memory, AND other cores invalidate their cached copy of older versions, some of
them are liable to see stale versions of the variable. But if the caches were flushed to memory
each time there is a cache write ("just in case" there was a read by another core) that would
consume main memory bandwidth unnecessarily.
The standard solution used at the hardware instruction set level is to provide instructions for cache
invalidation and a cache write-through, and leave it to the compiler to decide when to use them.
Returning to Java. the Memory Model is designed so that the Java compilers are not required to
issue cache invalidation and write-through instructions where they are not really needed. The
assumption is that the programmer will use an appropriate synchronization mechanism (e.g.
primitive mutexes, volatile, higher-level concurrency classes and so on) to indicate that it needs
memory visibility. In the absence of a happens-before relation, the Java compilers are free to
assume that no cache operations (or similar) are required.
This has significant performance advantages for multi-threaded applications, but the downside is
that writing correct multi-threaded applications is not a simple matter. The programmer does have
to understand what he or she is doing.
1. As explained above, the consequence of not dealing with memory visibility issues problems
properly is typically that your compiled application does not handle the memory caches
correctly. However, as we alluded to above, memory caches often get flushed anyway.
2. When you change the hardware platform, the characteristics of the memory caches may
change. This can lead to different behavior if your application does not synchronize correctly.
3. You may be observing the effects of serendipitous synchronization. For example, if you add
https://riptutorial.com/ 597
traceprints, their is typically some synchronization happening behind the scenes in the I/O
streams that causes cache flushes. So adding traceprints often causes the application to
behave differently.
These things make bugs that are due to inadequate synchronization particularly difficult to solve.
https://riptutorial.com/ 598
Chapter 88: Java plugin system
implementations
Remarks
If you use an IDE and/or build system, it is much easier to set up this kind of project. You create a
main application module, then API module, then create a plugin module and make it dependent on
the API module or both. Next, you configure where the project artifacts are to be put - in our case
the compiled plugin jars can be sent straight to 'plugins' directory, thus avoiding doing manual
movement.
Examples
Using URLClassLoader
There are several ways to implement a plugin system for a Java application. One of the simplest is
to use URLClassLoader. The following example will involve a bit of JavaFX code.
Suppose we have a module of a main application. This module is supposed to load plugins in form
of Jars from 'plugins' folder. Initial code:
package main;
package main;
https://riptutorial.com/ 599
default void initialize()
{
System.out.println("Initialized "+this.getClass().getName());
}
default String name(){return getClass().getSimpleName();}
}
We want to load classes which implement this interface, so first we need to filter files which have a
'.jar' extension:
If there are any files, we need to create collections of URLs and class names:
Let's add a static HashSet to MainApplication which will hold loaded plugins:
Next, we instantiate a URLClassLoader, and iterate over class names, instantiating classes which
implement Plugin interface:
https://riptutorial.com/ 600
}
}
}
catch (Exception e){e.printStackTrace();}
});
package main;
public class MainApplication extends Application
{
static HashSet<Plugin> plugins=new HashSet<>();
@Override
public void start(Stage primaryStage) throws Exception
{
File pluginDirectory=new File("plugins");
if(!pluginDirectory.exists())pluginDirectory.mkdir();
File[] files=pluginDirectory.listFiles((dir, name) -> name.endsWith(".jar"));
VBox loadedPlugins=new VBox(6);
loadedPlugins.setAlignment(Pos.CENTER);
if(files!=null && files.length>0)
{
ArrayList<String> classes=new ArrayList<>();
ArrayList<URL> urls=new ArrayList<>(files.length);
for(File file:files)
{
JarFile jar=new JarFile(file);
jar.stream().forEach(jarEntry -> {
if(jarEntry.getName().endsWith(".class"))
{
classes.add(jarEntry.getName());
}
});
URL url=file.toURI().toURL();
urls.add(url);
}
URLClassLoader urlClassLoader=new URLClassLoader(urls.toArray(new
URL[urls.size()]));
classes.forEach(className->{
try
{
Class
cls=urlClassLoader.loadClass(className.replaceAll("/",".").replace(".class",""));
Class[] interfaces=cls.getInterfaces();
for(Class intface:interfaces)
{
if(intface.equals(Plugin.class))
{
Plugin plugin=(Plugin) cls.newInstance();
plugins.add(plugin);
break;
https://riptutorial.com/ 601
}
}
}
catch (Exception e){e.printStackTrace();}
});
if(!plugins.isEmpty())loadedPlugins.getChildren().add(new Label("Loaded
plugins:"));
plugins.forEach(plugin -> {
plugin.initialize();
loadedPlugins.getChildren().add(new Label(plugin.name()));
});
}
Rectangle2D screenbounds=Screen.getPrimary().getVisualBounds();
Scene scene=new
Scene(loadedPlugins,screenbounds.getWidth()/2,screenbounds.getHeight()/2);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] a)
{
launch(a);
}
}
Let's create two plugins. Obviously, the plugin's source should be in a separate module.
package plugins;
import main.Plugin;
Second plugin:
package plugins;
import main.Plugin;
These plugins have to be packaged into standard Jars - this process depends on your IDE or
other tools.
When Jars will be put into 'plugins' directly, MainApplication will detect them and instantiate
appropriate classes.
https://riptutorial.com/ 602
plugin-system-implementations
https://riptutorial.com/ 603
Chapter 89: Java Print Service
Introduction
The Java Print Service API provides functionalities to discover print services and send print
requests for them.
It includes extensible print attributes based on the standard attributes specified in the Internet
Printing Protocol (IPP) 1.1 from the IETF Specification, RFC 2911.
Examples
Discovering the available print services
To discovery all the available print services, we can use the PrintServiceLookup class. Let's see
how:
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
This program, when executed on a Windows environment, will print something like this:
To discovery the default print service, we can use the PrintServiceLookup class. Let's see how::
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
https://riptutorial.com/ 604
public static void main(String[] args) {
discoverDefaultPrintService();
}
A print job is a request of printing something in a specific print service. It consists, basically, by:
• the data that will be printed (see Building the Doc that will be printed)
• a set of attributes
After picking-up the right print service instance, we can request the creation of a print job:
printJob.print(doc, pras);
Doc is an interface and the Java Print Service API provide a simple implementation called SimpleDoc
.
• the print data content itself (an E-mail, an image, a document etc)
• the print data format, called DocFlavor (MIME type + Representation class).
https://riptutorial.com/ 605
Before creating the Doc object, we need to load our document from somewhere. In the example,
we will load an specific file from the disk:
So now, we have to choose a DocFlavor that matches our content. The DocFlavor class has a bunch
of constants to represent the most usual types of data. Let's pick the INPUT_STREAM.PDF one:
The doc object now can be sent to the print job request (see Creating a print job from a print
service).
Sometimes we need to determine some aspects of the print request. We will call them attribute.
Before choosing one of them and which value each one will have, first we need to build a set of
attributes:
pras.add(new Copies(5));
pras.add(MediaSize.ISO_A4);
pras.add(OrientationRequested.PORTRAIT);
pras.add(PrintQuality.NORMAL);
The pras object now can be sent to the print job request (see Creating a print job from a print
service).
For the most printing clients, is extremely useful to know if a print job has finished or failed.
https://riptutorial.com/ 606
The Java Print Service API provide some functionalities to get informed about these scenarios. All
we have to do is:
When the print job state changes, we will be notified. We can do anything is needed, for example:
In the example bellow, we will log every print job status change:
import javax.print.event.PrintJobEvent;
import javax.print.event.PrintJobListener;
Finally, we can add our print job listener implementation on the print job before the print request
itself, as follows:
printJob.addPrintJobListener(new LoggerPrintJobListener());
https://riptutorial.com/ 607
printJob.print(doc, pras);
pje.getPrintJob().getAttributes();
Will return a PrintJobAttributeSet object instance and you can run them in a for-each way.
import javax.print.event.PrintJobEvent;
import javax.print.event.PrintJobAdapter;
As the same way in the example implementing the interface PrintJobListener, we add the listener
to the print job before sending it to print:
printJob.addPrintJobListener(new LoggerPrintJobAdapter());
printJob.print(doc, pras);
https://riptutorial.com/ 608
Chapter 90: Java SE 7 Features
Introduction
In this topic you'll find a summary of the new features added to the Java programming language in
Java SE 7. There are many other new features in other fields such as JDBC and Java Virtual
Machine (JVM) that are not going to be covered in this topic.
Remarks
Enhancements in Java SE 7
Examples
New Java SE 7 programming language features
• Binary Literals: The integral types (byte, short, int, and long) can also be expressed using the
binary number system. To specify a binary literal, add the prefix 0b or 0B to the number.
• Strings in switch Statements: You can use a String object in the expression of a switch
statement
• The try-with-resources Statement: The try-with-resources statement is a try statement that
declares one or more resources. A resource is as an object that must be closed after the
program is finished with it. The try-with-resources statement ensures that each resource is
closed at the end of the statement. Any object that implements java.lang.AutoCloseable,
which includes all objects which implement java.io.Closeable, can be used as a resource.
• Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type
Checking: a single catch block can handle more than one type of exception. This feature can
reduce code duplication and lessen the temptation to catch an overly broad exception.
• Underscores in Numeric Literals: Any number of underscore characters (_) can appear
anywhere between digits in a numerical literal. This feature enables you, for example, to
separate groups of digits in numeric literals, which can improve the readability of your code.
• Type Inference for Generic Instance Creation: You can replace the type arguments required
to invoke the constructor of a generic class with an empty set of type parameters (<>) as
long as the compiler can infer the type arguments from the context. This pair of angle
brackets is informally called the diamond.
• Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with
Varargs Methods
Binary Literals
https://riptutorial.com/ 609
short aShort = (short)0b1010000101000101;
The example reads the first line from a file. It uses an instance of BufferedReader to read data from
the file. BufferedReader is a resource that must be closed after the program is finished with it:
In this example, the resource declared in the try-with-resources statement is a BufferedReader. The
declaration statement appears within parentheses immediately after the try keyword. The class
BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because
the BufferedReader instance is declared in a try-with-resource statement, it will be closed
regardless of whether the try statement completes normally or abruptly (as a result of the method
BufferedReader.readLine throwing an IOException).
The following example shows other ways you can use the underscore in numeric literals:
You can place underscores only between digits; you cannot place underscores in the following
places:
https://riptutorial.com/ 610
You can use
instead of
list.addAll(new ArrayList<>());
because it can't compile. Note that the diamond often works in method calls; however, it is
suggested that you use the diamond primarily for variable declarations.
https://riptutorial.com/ 611
Chapter 91: Java SE 8 Features
Introduction
In this topic you'll find a summary of the new features added to the Java programming language in
Java SE 8. There are many other new features in other fields such as JDBC and Java Virtual
Machine (JVM) that are not going to be covered in this topic.
Remarks
Reference: Enhancements in Java SE 8
Examples
New Java SE 8 programming language features
• Lambda Expressions, a new language feature, has been introduced in this release. They
enable you to treat functionality as a method argument, or code as data. Lambda
expressions let you express instances of single-method interfaces (referred to as functional
interfaces) more compactly.
○Method references provide easy-to-read lambda expressions for methods that already
have a name.
○Default methods enable new functionality to be added to the interfaces of libraries and
ensure binary compatibility with code written for older versions of those interfaces.
○New and Enhanced APIs That Take Advantage of Lambda Expressions and Streams
in Java SE 8 describe new and enhanced classes that take advantage of lambda
expressions and streams.
• Improved Type Inference - The Java compiler takes advantage of target typing to infer the
type parameters of a generic method invocation. The target type of an expression is the data
type that the Java compiler expects depending on where the expression appears. For
example, you can use an assignment statement's target type for type inference in Java SE 7.
However, in Java SE 8, you can use the target type for type inference in more contexts.
○Target Typing in Lambda Expressions
○Type Inference
• Repeating Annotations provide the ability to apply the same annotation type more than once
to the same declaration or type use.
• Type Annotations provide the ability to apply an annotation anywhere a type is used, not just
on a declaration. Used with a pluggable type system, this feature enables improved type
checking of your code.
• Method parameter reflection - You can obtain the names of the formal parameters of any
method or constructor with the method java.lang.reflect.Executable.getParameters. (The
classes Method and Constructor extend the class Executable and therefore inherit the
method Executable.getParameters) However, .class files do not store formal parameter names
by default. To store formal parameter names in a particular .class file, and thus enable the
https://riptutorial.com/ 612
Reflection API to retrieve formal parameter names, compile the source file with the -
parameters option of the javac compiler.
• Date-time-api - Added new time api in java.time. If used this, you don't need to designate
timezone.
https://riptutorial.com/ 613
Chapter 92: Java Sockets
Introduction
Sockets are a low-level network interface that helps in creating a connection between two program
mainly clients which may or may not be running on the same machine.
Remarks
There are two types of Internet Protocol Traffic -
1. TCP - Transmission Control Protocol 2. UDP - User Datagram Protocol
TCP is suited for applications that require high reliability, and transmission time is relatively less
critical.
UDP is suitable for applications that need fast, efficient transmission, such as games. UDP's
stateless nature is also useful for servers that answer small queries from huge numbers of clients.
In simpler words -
Use TCP when you cannot afford to loose data and when time to send and receive data doesn't
matter. Use UDP when you cannot afford to loose time and when loss of data doesn't matter.
There is an absolute guarantee that the data transferred remains intact and arrives in the same
order in which it was sent in case of TCP.
whereas there is no guarantee that the messages or packets sent would reach at all in UDP.
Examples
A simple TCP echo back server
Our TCP echo back server will be a separate thread. It's simple as its a start. It will just echo back
whatever you send it but in capitalised form.
// This class implements server sockets. A server socket waits for requests to come
// in over the network only when it is allowed through the local firewall
ServerSocket serverSocket;
https://riptutorial.com/ 614
serverSocket = new ServerSocket(port);
// SoTimeout is basiacally the socket timeout.
// timeout is the time until socket timeout in milliseconds
serverSocket.setSoTimeout(timeout);
} catch (IOException ex) {
Logger.getLogger(CAPECHOServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void run(){
try {
// We want the server to continuously accept connections
while(!Thread.interrupted()){
}
// Close the server once done.
serverSocket.close();
} catch (IOException ex) {
Logger.getLogger(CAPECHOServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void run(){
while(!Thread.interrupted()){
try {
// Log with the port number and machine ip
Logger.getLogger((this.getClass().getName())).log(Level.INFO, "Listening for
Clients at {0} on {1}", new Object[]{serverSocket.getLocalPort(),
InetAddress.getLocalHost().getHostAddress()});
Socket client = serverSocket.accept(); // Accept client conncetion
// Now get DataInputStream and DataOutputStreams
DataInputStream istream = new DataInputStream(client.getInputStream()); // From
client's input stream
DataOutputStream ostream = new DataOutputStream(client.getOutputStream());
// Important Note
/*
The server's input is the client's output
The client's input is the server's output
*/
// Send a welcome message
ostream.writeUTF("Welcome!");
try {
https://riptutorial.com/ 615
serverSocket.close();
} catch (IOException ex) {
Logger.getLogger(CAPECHOServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
Now if you can open telnet and try connecting You'll see a Welcome message.
You must connect with the port you specified and IP Adress.
Welcome!
Well, the connection was lost because we terminated it. Sometimes we would have to program our
own TCP client. In this case, we need a client to request input from the user and send it across the
network, receive the capitalised input.
If the server sends data first, then the client must read the data first.
Socket server;
Scanner key; // Scanner for input
@Override
public void run(){
DataInputStream istream = null;
DataOutputStream ostream = null;
try {
istream = new DataInputStream(server.getInputStream()); // Familiar lines
ostream = new DataOutputStream(server.getOutputStream());
System.out.println(istream.readUTF()); // Print what the server sends
System.out.print(">");
String tosend = key.nextLine();
ostream.writeUTF(tosend); // Send whatever the user typed to the server
System.out.println(istream.readUTF()); // Finally read what the server sends
before exiting.
} catch (IOException ex) {
Logger.getLogger(CAPECHOClient.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
istream.close();
ostream.close();
server.close();
} catch (IOException ex) {
https://riptutorial.com/ 616
Logger.getLogger(CAPECHOClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
ostream.writeUTF("Welcome!");
And now run the server and client, You should have an output similar to this
Welcome!
>
https://riptutorial.com/ 617
Chapter 93: Java Virtual Machine (JVM)
Examples
These are the basics.
JVM is an abstract computing machine or Virtual machine that resides in your RAM. It has a
platform-independent execution environment that interprets Java bytecode into native machine
code. (Javac is Java Compiler which compiles your Java code into Bytecode)
Java program will be running inside the JVM which is then mapped onto the underlying physical
machine. It is one of programming tool in JDK.
(Byte code is platform-independent code which is run on every platform and Machine code is
platform-specific code which is run in only specific platform such as windows or linux; it depend on
execution.)
(Edited)
https://riptutorial.com/ 618
Chapter 94: JavaBean
Introduction
JavaBeans (TM) is a pattern for designing Java class APIs that allows instances (beans) to be
used in various contexts and using various tools without explicitly writing Java code. The patterns
consists of conventions for defining getters and setters for properties, for defining constructors,
and for defining event listener APIs.
Syntax
• JavaBean Property Naming Rules
• If the property is not a boolean, the getter method's prefix must be get. For example,
getSize()is a valid JavaBeans getter name for a property named "size." Keep in mind that
you do not need to have a variable named size. The name of the property is inferred from
the getters and setters, not through any variables in your class. What you return from
getSize() is up to you.
• If the property is a boolean, the getter method's prefix is either get or is. For example,
getStopped() or isStopped() are both valid JavaBeans names for a boolean property.
• The setter method's prefix must be set. For example, setSize() is the valid JavaBean name
for a property named size.
• To complete the name of a getter or setter method, change the first letter of the property
name to uppercase, and then append it to the appropriate prefix (get, is, or set).
• Setter method signatures must be marked public, with a void return type and an argument
that represents the property type.
• Getter method signatures must be marked public, take no arguments, and have a return type
that matches the argument type of the setter method for that property.
• JavaBean Listener Naming Rules
• Listener method names used to "register" a listener with an event source must use the prefix
add, followed by the listener type. For example, addActionListener() is a valid name for a
method that an event source will have to allow others to register for Action events.
• Listener method names used to remove ("unregister") a listener must use the prefix remove,
followed by the listener type (using the same rules as the registration add method).
• The type of listener to be added or removed must be passed as the argument to the method.
• Listener method names must end with the word "Listener".
Remarks
In order for a class to be a Java Bean must follow this standard - in summary:
• All of its properties must be private and only accessible through getters and setters.
• It must have a public no-argument constructor.
• Must implement the java.io.Serializable interface.
https://riptutorial.com/ 619
Examples
Basic Java Bean
public BasicJavaBean(){}
https://riptutorial.com/ 620
Chapter 95: JAXB
Introduction
JAXB or Java Architecture for XML Binding (JAXB) is a software framework that allows Java
developers to map Java classes to XML representations. This Page will introduce readers to JAXB
using detailed examples about its functions provided mainly for marshaling and un-marshaling
Java Objects into xml format and vice-versa.
Syntax
• JAXB.marshall(object, fileObjOfXML);
Parameters
Parameter Details
Remarks
Using the XJC tool available in the JDK, java code for a xml structure described in a xml schema (
.xsd file) can be automatically generated, see XJC topic.
Examples
Writing an XML file (marshalling an object)
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class User {
By using the annotation XMLRootElement, we can mark a class as a root element of an XML file.
https://riptutorial.com/ 621
import java.io.File;
import javax.xml.bind.JAXB;
try {
JAXB.marshal(user, new File("UserDetails.xml"));
} catch (Exception e) {
System.err.println("Exception occurred while writing in XML!");
} finally {
System.out.println("XML created");
}
}
}
marshal() is used to write the object's content into an XML file. Here userobject and a new File
object are passed as arguments to the marshal().
On successful execution, this creates an XML file named UserDetails.xml in the class-path with the
below content.
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class User {
Here we have created the variables and class name according to the XML nodes. To map them,
https://riptutorial.com/ 622
we use the annotation XmlRootElement on the class.
Here unmarshal() method is used to parse the XML file. It takes the XML file name and the class
type as two arguments. Then we can use the getter methods of the object to print the data.
When desired XML format differs from Java object model, an XmlAdapter implementation can be
used to transform model object into xml-format object and vice versa. This example demonstrates
how to put a field's value into an attribute of an element with field's name.
@XmlAccessorType(XmlAccessType.FIELD)
public static class NodeValueElement {
@XmlAttribute(name="attrValue")
String value;
public NodeValueElement() {
}
@Override
public NodeValueElement marshal(String v) throws Exception {
return new NodeValueElement(v);
}
@Override
public String unmarshal(NodeValueElement v) throws Exception {
https://riptutorial.com/ 623
if (v==null) return "";
return v.getValue();
}
}
@XmlRootElement(name="DataObject")
@XmlAccessorType(XmlAccessType.FIELD)
public static class DataObject {
String elementWithValue;
@XmlJavaTypeAdapter(value=ValueAsAttrXmlAdapter.class)
String elementWithAttribute;
}
System.out.println(xmlString);
}
}
@XmlAccessorType(XmlAccessType.FIELD)
static class AccessorExampleField {
public String field="value1";
@XmlAccessorType(XmlAccessType.NONE)
static class AccessorExampleNone {
public String field="value1";
https://riptutorial.com/ 624
@XmlAccessorType(XmlAccessType.PROPERTY)
static class AccessorExampleProperty {
public String field="value1";
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
static class AccessorExamplePublic {
public String field="value1";
Output
Field:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<accessorExampleField>
<field>value1</field>
</accessorExampleField>
None:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<accessorExampleNone/>
Property:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<accessorExampleProperty>
<getter>getter</getter>
</accessorExampleProperty>
Public:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
https://riptutorial.com/ 625
<accessorExamplePublic>
<field>value1</field>
<getter>getter</getter>
</accessorExamplePublic>
@XmlElement
private String field="field value";
@XmlAttribute
private String attribute="attr value";
@XmlAttribute(name="differentAttribute")
private String oneAttribute="other attr value";
@XmlElement(name="different name")
private String oneName="different name value";
@XmlTransient
private String transientField = "will not get serialized ever";
@XmlElement
public String getModifiedTransientValue() {
return transientField.replace(" ever", ", unless in a getter");
}
Sometimes specific instances of data should be used. Recreation is not desired and referencing
static data would have a code smell.
It is possible to specify a XmlAdapter instance the Unmarshaller should use, which allows the user to
use XmlAdapters with no zero-arg constructor and/or pass data to the adapter.
https://riptutorial.com/ 626
Example
User class
import java.awt.image.BufferedImage;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class User {
@XmlAttribute
public String getName() {
return name;
}
@XmlJavaTypeAdapter(value=ImageCacheAdapter.class)
@XmlAttribute
public BufferedImage getImage() {
return image;
}
public User() {
this("", null);
}
Adapter
To avoid creating the same image in memory twice (as well as downloading the data again), the
adapter stores the images in a map.
Java SE 7
https://riptutorial.com/ 627
public BufferedImage getImage(URL url) {
BufferedImage image = imageCache.get(url);
if (image == null) {
try {
image = ImageIO.read(url);
} catch (IOException ex) {
Logger.getLogger(ImageCacheAdapter.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
imageCache.put(url, image);
reverseIndex.put(image, url);
}
return image;
}
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.xml.bind.annotation.adapters.XmlAdapter;
@Override
public BufferedImage unmarshal(String v) throws Exception {
return getImage(new URL(v));
}
@Override
public String marshal(BufferedImage v) throws Exception {
return reverseIndex.get(v).toExternalForm();
}
Example XMLs
https://riptutorial.com/ 628
The following 2 xmls are for Jon Skeet and his earth 2 counterpart, which both look exactly the
same and therefore use the same avatar.
System.out.println(result1.getName());
System.out.println(result2.getName());
This is an example of a package-info.java file that binds an XML namespace to a serializable Java
class. This should be placed in the same package as the Java classes that should be serialized
using the namespace.
/**
* A package containing serializable classes.
*/
@XmlSchema
(
xmlns =
{
@XmlNs(prefix = MySerializableClass.NAMESPACE_PREFIX, namespaceURI =
MySerializableClass.NAMESPACE)
https://riptutorial.com/ 629
},
namespace = MySerializableClass.NAMESPACE,
elementFormDefault = XmlNsForm.QUALIFIED
)
package com.test.jaxb;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
package com.example.xml.adapters;
import javax.xml.bind.annotation.adapters.XmlAdapter;
@Override
public String marshal(String v) throws Exception {
if (v == null)
return null;
return v.trim();
}
}
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
https://riptutorial.com/ 630
Chapter 96: JAX-WS
Examples
Basic Authentication
Here is an example where Service is the service class representation and Port is the service port
you want to access.
port.call();
https://riptutorial.com/ 631
Chapter 97: JMX
Introduction
The JMX technology provides the tools for building distributed, Web-based, modular and dynamic
solutions for managing and monitoring devices, applications, and service-driven networks. By
design, this standard is suitable for adapting legacy systems, implementing new management and
monitoring solutions, and plugging into those of the future.
Examples
Simple example with Platform MBean Server
Let's say we have some server that registers new users and greets them with some message. And
we want to monitor this server and change some of it's parameters.
int getUserCount();
String getGreetingString();
void stop();
}
And some simple implementation that will let us see how it's working and how we affect it
@Override
public long getSleepTime() {
return sleepTime.get();
}
@Override
public void setSleepTime(long sleepTime) {
this.sleepTime.set(sleepTime);
}
https://riptutorial.com/ 632
@Override
public int getUserCount() {
return userCount.get();
}
@Override
public void setUserCount(int userCount) {
this.userCount.set(userCount);
}
@Override
public String getGreetingString() {
return greetingString.get();
}
@Override
public void setGreetingString(String greetingString) {
this.greetingString.set(greetingString);
}
@Override
public void stop() {
this.interrupted.set(true);
}
@Override
public void run() {
while (!interrupted.get()) {
try {
System.out.printf("User %d, %s%n", userCount.incrementAndGet(),
greetingString.get());
Thread.sleep(sleepTime.get());
} catch (InterruptedException ignored) {
}
}
}
}
For simple example with local or remote management, we need to register our MBean:
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
https://riptutorial.com/ 633
thread.join();
}
}
After that we can run our application and connect to it via jConsole, which can be found in your
$JAVA_HOME/bin directory. First, we need to find our local java process with our application
then switch to MBeans tab and find that MBean that we used in our Main class as an ObjectName (in
the example above it's ServerManager). In Attributes section we can see out attributes. If you
specified get method only, attribute will be readable but not writeable. If you specified both get and
set methods, attribute would be readable and writeable.
https://riptutorial.com/ 634
Specified methods can be invoked in Operations section.
If you want to be able to use remote management, you will need additional JVM parameters, like:
https://riptutorial.com/ 635
These parameters can be found in Chapter 2 of JMX guides. After that you will be able to connect
to your application via jConsole remotely with jconsole host:port or with specifying host:port or
service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi in jConsole GUI.
Useful links:
• JMX guides
• JMX Best practices
https://riptutorial.com/ 636
Chapter 98: JNDI
Examples
RMI through JNDI
This example shows how JNDI works in RMI. It has two roles:
To make this simple, we will use java.rmi.registry.CreateRegistry() to create the RMI Registry.
package com.neohope.jndi.test;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.util.Hashtable;
/**
* JNDI Server
* 1.create a registry on port 1234
* 2.bind JNDI
* 3.wait for connection
* 4.clean up and end
*/
public class Server {
private static Registry registry;
private static InitialContext ctx;
https://riptutorial.com/ 637
ctx.bind(name, obj);
}
package com.neohope.jndi.test;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;
/**
* 1.init context
* 2.lookup registry for the service
* 3.use the service
* 4.end
*/
public class Client {
public static void main(String[] args) throws NamingException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.rmi.registry.RegistryContextFactory");
jndiProperties.put(Context.PROVIDER_URL, "rmi://localhost:1234");
package com.neohope.jndi.test;
import java.io.Serializable;
import java.rmi.Remote;
/**
https://riptutorial.com/ 638
* NMessage
* RMI server class
* must implements Remote and Serializable
*/
public class NMessage implements Remote, Serializable {
public String message = "";
Introduce
The Java Naming and Directory Interface (JNDI) is a Java API for a directory service that allows
Java software clients to discover and look up data and objects via a name. It is designed to be
independent of any specific naming or directory service implementation.
The JNDI architecture consists of an API (Application Programming Interface) and an SPI (Service
Provider Interface). Java applications use this API to access a variety of naming and directory
services. The SPI enables a variety of naming and directory services to be plugged in
transparently, allowing the Java application using the API of the JNDI technology to access their
services.
As you can see form the picture above, JNDI supports LDAP, DNS, NIS, NDS, RMI and CORBA.
Of course, you can extend it.
https://riptutorial.com/ 639
How it works
In this example, the Java RMI use the JNDI API to look up objects in a network. If you want to look
up a object, you need at least two pieces of information:
The RMI Registry manages the name bindings, it tells you where to find the object.
What is a object's name? It is usually a string, it can also be a object that implements the Name
interface.
Step by step
1. First you need a registry, which manage the name binding. In this example, we use
java.rmi.registry.LocateRegistry.
2. Both client and server need a Context. Server use the Context to bind the name and object.
Client use the Context to lookup the name and get the object.
ctx.unbind("/neohope/jndi/test01");
ctx.close();
https://riptutorial.com/ 640
Chapter 99: JShell
Introduction
JShell is an interactive REPL for Java added in JDK 9. It allows developers to instantly evaluate
expressions, test classes, and experiment with the Java language. Early access for jdk 9 can be
obtained from: http://jdk.java.net/9/
Syntax
• $ jshell — Start the JShell REPL
• jshell> /<command> — Run a given JShell command
• jshell> /exit — Exit JShell
• jshell> /help — See a list of JShell commands
• jshell> <java_expression> - Evaluate the given Java expression (semicolon optional)
• jshell> /vars OR /methods OR /types — See a list of variables, methods, or classes,
respectively.
• jshell> /open <file> — read a file as input to the shell
• jshell> /edit <identifier> — edit a snippet in the set editor
• jshell> /set editor <command> — set the command to be used to edit snippets using /edit
• jshell> /drop <identifier> — delete a snippet
• jshell> /reset — Reset the JVM and delete all snippets
Remarks
JShell requires the Java 9 JDK, which can currently (March 2017) be downloaded as early access
snapshots from jdk9.java.net. If, when you try to run the jshell command, you get an error
beginning with Unable to locate an executable, make sure JAVA_HOME is set correctly.
Default Imports
The following packages are imported automatically when JShell starts:
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.*
Examples
https://riptutorial.com/ 641
Entering and Exiting JShell
Starting JShell
Before trying to start JShell, make sure your JAVA_HOME environment variable points to a JDK 9
installation. To start JShell, run the following command:
$ jshell
Exiting JShell
To exit JShell, run the following command from the JShell prompt:
jshell> /exit
Expressions
Within JShell, you can evaluate Java expressions, with or without semicolons. These can range
from basic expressions and statements to more complex ones:
jshell> 4+2
jshell> System.out.printf("I am %d years old.\n", 421)
Variables
Keep in mind that variables can be redeclared with different types; this is perfectly valid in JShell:
https://riptutorial.com/ 642
Methods and Classes
No access modifiers are necessary. As with other blocks, semicolons are required inside of
method bodies. Keep in mind that, as with variables, it is possible to redefine methods and
classes. To see a list of methods or classes, enter /methods or /types at the JShell prompt,
respectively.
Editting Snippets
The basic unit of code used by JShell is the snippet, or source entry. Every time you declare a
local variable or define a local method or class, you create a snippet whose name is the identifier
of the variable/method/class. At any time, you can edit a snippet you have created with the /edit
command. For example, let's say I have created the class Foo with a single, method, bar:
Now, I want to fill in the body of my method. Rather than rewrite the entire class, I can edit it:
By default, a swing editor will pop up with the most basic features possible. However you can
change the editor that JShell uses:
Note that if the new version of the snippet contains any syntax errors, it may not be saved.
Likewise, a snippet is only created if the original declaration/definition is syntactically correct; the
following does not work:
https://riptutorial.com/ 643
However, snippets may be compiled and hence editable despite certain compile-time errors, such
as mismatched types—the following works:
jshell> int i = 13
jshell> /drop i
jshell> System.out.println(i)
| Error:
| cannot find symbol
| symbol: variable i
| System.out.println(i)
|
To delete all snippets, thereby reseting the state of the JVM, use \reset:
jshell> int i = 2
jshell> /reset
| Resetting state.
jshell> i
| Error:
| cannot find symbol
| symbol: variable i
| i
| ^
jshell> s
| Error:
| cannot find symbol
| symbol: variable s
| s
| ^
https://riptutorial.com/ 644
Chapter 100: JSON in Java
Introduction
JSON (JavaScript Object Notation) is a lightweight, text-based, language-independent data
exchange format that is easy for humans and machines to read and write. JSON can represent
two structured types: objects and arrays. JSON is often used in Ajax applications, configurations,
databases, and RESTful web services. The Java API for JSON Processing provides portable APIs
to parse, generate, transform, and query JSON.
Remarks
This example focuses on parsing and creating JSON in Java using various libraries such as the
Google Gson library, Jackson Object Mapper, and others..
Examples using other libraries could be found here: How to parse JSON in Java
Examples
Encoding data as JSON
If you need to create a JSONObject and put data in it, consider the following example:
first.put("foo", "bar");
first.put("temperature", 21.5);
first.put("year", 2016);
// Encode
String json = object.toString();
https://riptutorial.com/ 645
"year":2016,
"message":{"Hello":"world"},
"months":["January","February","March",null,"May"]
}
*/
If you need to get data from a JSONObject, consider the following example:
String json =
"{\"foo\":\"bar\",\"temperature\":21.5,\"year\":2016,\"message\":{\"Hello\":\"world\"},\"months\":[\"Ja
// Retrieve an array
JSONArray someMonths = object.getJSONArray("months");
// Get some values from the array
int nMonths = someMonths.length();
String february = someMonths.getString(1);
JSONObject and JSONArray have a few methods that are very useful while dealing with a possibility
that a value your are trying to get does not exist or is of another type.
// However, if a value cannot be coerced to the required type, the behavior differs
obj.getInt("foo"); // throws JSONException
obj.optInt("foo"); // returns 0
obj.optInt("foo", 123); // returns 123
https://riptutorial.com/ 646
Object To JSON (Gson Library)
Lets assume you have a class called Person with just name
Code:
Lets assume you have a class called Person with just name
Code:
System.out.println(jsonObject.get("name").getAsString()); //John
System.out.println(jsonObject.get("age").getAsInt()); //21
https://riptutorial.com/ 647
Using Jackson Object Mapper
Pojo Model
Details
Import statement needed:
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper instance
//creating one
ObjectMapper objectMapper = new ObjectMapper();
• ObjectMapper is threadsafe
• recommended: have a shared, static instance
Deserialization:
https://riptutorial.com/ 648
- in case of a low-level I/O problem
○ JsonParseException - if underlying input contains invalid content
○ JsonMappingException - if the input JSON structure does not match object structure
• Throws
○ JsonProcessingException in case of an error
○ Note: prior to version 2.1, throws clause included IOException; 2.1 removed it.
JSON Iteration
You can use method chaining while working with JSONObject and JSONArray.
JSONObject example
https://riptutorial.com/ 649
JSONArray
JSONObject.NULL
If you need to add a property with a null value, you should use the predefined static final
JSONObject.NULL and not the standard Java null reference.
JSONObject.NULL is a sentinel value used to explicitly define a property with an empty value.
Note
Here is a simple JsonArray which you would like to convert to a Java ArrayList:
{
"list": [
"Test_String_1",
"Test_String_2"
]
}
Now pass the JsonArray 'list' to the following method which returns a corresponding Java ArrayList:
You should add the following maven dependency to your POM.xml file:
https://riptutorial.com/ 650
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
And you want to parse it into a JSON array or a map of Person objects. Due to type erasure you
cannot construct classes of List<Person> and Map<String, Person> at runtime directly (and thus use
them to deserialize JSON). To overcome this limitation jackson provides two approaches -
TypeFactory and TypeReference.
TypeFactory
The approach taken here is to use a factory (and its static utility function) to build your type for
you. The parameters it takes are the collection you want to use (list, set, etc.) and the class you
want to store in that collection.
TypeReference
The type reference approach seems simpler because it saves you a bit of typing and looks
cleaner. TypeReference accepts a type parameter, where you pass the desired type List<Person>.
You simply instantiate this TypeReference object and use it as your type container.
Now let's look at how to actually deserialize your JSON into a Java object. If your JSON is
formatted as an array, you can deserialize it as a List. If there is a more complex nested structure,
you will want to deserialize to a Map. We will look at examples of both.
TypeFactory approach
CollectionType listType =
factory.constructCollectionType(List.class, Person.class);
List<Preson> list = mapper.readValue(jsonString, listType);
https://riptutorial.com/ 651
TypeReference approach
TypeFactory approach
CollectionType mapType =
factory.constructMapLikeType(Map.class, String.class, Person.class);
List<Person> list = mapper.readValue(jsonString, mapType);
TypeReference approach
Details
Import statement used:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
Instances used:
Note
While TypeReference approach may look better it has several drawbacks:
Failing to do so may lead to loss of generic type argument which will lead to deserialization failure.
https://riptutorial.com/ 652
Read JSON in Java online: https://riptutorial.com/java/topic/840/json-in-java
https://riptutorial.com/ 653
Chapter 101: Just in Time (JIT) compiler
Remarks
History
The Symantec JIT compiler was available in the Sun Java from 1.1.5 onwards, but it had
problems.
The Hotspot JIT compiler was added to Sun Java in 1.2.2 as a plugin. In Java 1.3, JIT was
enabled by default.
Examples
Overview
https://riptutorial.com/ 654
The Just-In-Time (JIT) compiler is a component of the Java™ Runtime Environment that improves
the performance of Java applications at run time.
• Java programs consists of classes, which contain platform-neutral bytecodes that can be
interpreted by a JVM on many different computer architectures.
• At run time, the JVM loads the class files, determines the semantics of each individual
bytecode, and performs the appropriate computation.
The additional processor and memory usage during interpretation means that a Java
application performs more slowly than a native application.
The JIT compiler helps improve the performance of Java programs by compiling
bytecodes into native machine code at run time.
The JIT compiler is enabled by default, and is activated when a Java method is called. The JIT
compiler compiles the bytecodes of that method into native machine code, compiling it "just in
time" to run.
https://riptutorial.com/ 655
When a method has been compiled, the JVM calls the compiled code of that method directly
instead of interpreting it. Theoretically, if compilation did not require processor time and memory
usage, compiling every method could allow the speed of the Java program to approach that of a
native application.
JIT compilation does require processor time and memory usage. When the JVM first starts up,
thousands of methods are called. Compiling all of these methods can significantly affect startup
time, even if the program eventually achieves very good peak performance.
• In practice, methods are not compiled the first time they are called. For each method, the
JVM maintains a call count which is incremented every time the method is called.
• The JVM interprets a method until its call count exceeds a JIT compilation threshold.
• Therefore, often-used methods are compiled soon after the JVM has started, and less-used
methods are compiled much later, or not at all.
• The JIT compilation threshold helps the JVM start quickly and still have improved
performance.
• The threshold has been carefully selected to obtain an optimal balance between startup
times and long term performance.
• After a method is compiled, its call count is reset to zero and subsequent calls to the method
continue to increment its count.
• When the call count of a method reaches a JIT recompilation threshold, the JIT compiler
compiles it a second time, applying a larger selection of optimizations than on the previous
compilation.
• This process is repeated until the maximum optimization level is reached.
The busiest methods of a Java program are always optimized most aggressively,
maximizing the performance benefits of using the JIT compiler.
The JIT compiler can also measure operational data at run time, and use that data to improve the
quality of further recompilations.
The JIT compiler can be disabled, in which case the entire Java program will be
interpreted. Disabling the JIT compiler is not recommended except to diagnose or work
around JIT compilation problems.
https://riptutorial.com/ 656
Chapter 102: JVM Flags
Remarks
It is strongly recommended that you use these options only:
Examples
-XXaggressive
-XXaggressive is a collection of configurations that make the JVM perform at a high speed and
reach a stable state as soon as possible. To achieve this goal, the JVM uses more internal
resources at startup; however, it requires less adaptive optimization once the goal is reached. We
recommend that you use this option for long-running, memory-intensive applications that work
alone.
Usage:
-XXaggressive:<param>
<param> Description
-XXallocClearChunks
This option allows you to clear a TLA for references and values at TLA allocation time and pre-
fetch the next chunk. When an integer, a reference, or anything else is declared, it has a default
value of 0 or null (depending upon type). At the appropriate time, you will need to clear these
references and values to free the memory on the heap so Java can use- or reuse- it. You can do
either when the object is allocated or, by using this option, when you request a new TLA.
Usage:
https://riptutorial.com/ 657
-XXallocClearChunks
-XXallocClearChunks=<true | false>
The above is a boolean option and is generally recommended on IA64 systems; ultimately, its use
depends upon the application. If you want to set the size of chunks cleared, combine this option
with -XXallocClearChunkSize. If you use this flag but do not specify a boolean value, the default is
true.
-XXallocClearChunkSize
When used with -XXallocClearChunkSize, this option sets the size of the chunks to be cleared. If this
flag is used but no value is specified, the default is 512 bytes.
Usage:
-XXallocClearChunks -XXallocClearChunkSize=<size>[k|K][m|M][g|G]
-XXcallProfiling
This option enables the use of call profiling for code optimizations. Profiling records useful runtime
statistics specific to the application and can—in many cases—increase performance because JVM
can then act on those statistics.
Note: This option is supported with the JRockit JVM R27.3.0 and later version. It may
become default in future versions.
Usage:
-XXdisableFatSpin
This option disables the fat lock spin code in Java, allowing threads that block trying to acquire a
fat lock go to sleep directly.
Objects in Java become a lock as soon as any thread enters a synchronized block on that object.
All locks are held (that is, stayed locked) until released by the locking thread. If the lock is not
going to be released very fast, it can be inflated to a “fat lock.” “Spinning” occurs when a thread
that wants a specific lock continuously checks that lock to see if it is still taken, spinning in a tight
loop as it makes the check. Spinning against a fat lock is generally beneficial although, in some
instances, it can be expensive and might affect performance. -XXdisableFatSpin allows you to turn
off spinning against a fat lock and eliminate the potential performance hit.
Usage:
https://riptutorial.com/ 658
-XXdisableFatSpin
-XXdisableGCHeuristics
This option disables the garbage collector strategy changes. Compaction heuristics and nursery
size heuristics are not affected by this option. By default, the garbage collection heuristics are
enabled.
Usage:
-XXdisableFatSpin
-XXdumpSize
This option causes a dump file to be generated and allows you to specify the relative size of that
file (that is, small, medium, or large).
Usage:
-XXdumpsize:<size>
<size> Description
On Windows, a small dump file is generated (on Linux a full core dump is
generated). A small dump only include the thread stacks including their traces and
small
very little else. This was the default in the JRockit JVM 8.1 with service packs 1 and
2, as well as 7.0 with service pack 3 and higher).
Causes a normal dump to be generated on all platforms. This dump file includes all
normal memory except the java heap. This is the default value for the JRockit JVM 1.4.2
and later.
Includes everything that is in memory, including the Java heap. This option makes -
large
XXdumpSize equivalent to -XXdumpFullState.
-XXexitOnOutOfMemory
This option makes JRockit JVM exit on the first occurrence of an out of memory error. It can be
used if you prefer restarting an instance of JRockit JVM rather than handling out of memory errors.
Enter this command at startup to force JRockit JVM to exit on the first occurrence of an out of
memory error.
Usage:
-XXexitOnOutOfMemory
https://riptutorial.com/ 659
Read JVM Flags online: https://riptutorial.com/java/topic/2500/jvm-flags
https://riptutorial.com/ 660
Chapter 103: JVM Tool Interface
Remarks
JVM TM Tool Interface
Version 1.2
http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html
Examples
Iterate over objects reachable from object (Heap 1.0)
#include <vector>
#include <string>
#include "agent_util.hpp"
//this file can be found in Java SE Development Kit 8u101 Demos and Samples
//see http://download.oracle.com/otn-pub/java/jdk/8u101-b13-demos/jdk-8u101-windows-x64-
demos.zip
//jdk1.8.0_101.zip!\demo\jvmti\versionCheck\src\agent_util.h
/*
* Struct used for jvmti->SetTag(object, <pointer to tag>);
* http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#SetTag
*
*/
typedef struct Tag
{
jlong referrer_tag;
jlong size;
char* classSignature;
jint hashCode;
} Tag;
/*
* Utility function: jlong -> Tag*
*/
static Tag* pointerToTag(jlong tag_ptr)
{
if (tag_ptr == 0)
{
return new Tag();
}
return (Tag*)(ptrdiff_t)(void*)tag_ptr;
}
/*
* Utility function: Tag* -> jlong
*/
static jlong tagToPointer(Tag* tag)
{
https://riptutorial.com/ 661
return (jlong)(ptrdiff_t)(void*)tag;
}
/*
* Heap 1.0 Callback
* http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#jvmtiObjectReferenceCallback
*/
static jvmtiIterationControl JNICALL heabObjectReferencesCallback(
jvmtiObjectReferenceKind reference_kind,
jlong class_tag,
jlong size,
jlong* tag_ptr,
jlong referrer_tag,
jint referrer_index,
void* user_data)
{
//iterate only over reference field
if (reference_kind != JVMTI_HEAP_REFERENCE_FIELD)
{
return JVMTI_ITERATION_IGNORE;
}
auto tag_ptr_list = (std::vector<jlong>*)(ptrdiff_t)(void*)user_data;
//create and assign tag
auto t = pointerToTag(*tag_ptr);
t->referrer_tag = referrer_tag;
t->size = size;
*tag_ptr = tagToPointer(t);
//collect tag
(*tag_ptr_list).push_back(*tag_ptr);
return JVMTI_ITERATION_CONTINUE;
}
/*
* Main function for demonstration of Iterate Over Objects Reachable From Object
*
http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#IterateOverObjectsReachableFromObject
*
*/
void iterateOverObjectHeapReferences(jvmtiEnv* jvmti, JNIEnv* env, jobject object)
{
std::vector<jlong> tag_ptr_list;
*/
jvmti->IterateOverObjectsReachableFromObject(object, &heabObjectReferencesCallback,
(void*)&tag_ptr_list);
stdout_message("tag list size after call callback: %d\n", tag_ptr_list.size());
if (tag_ptr_list.size() > 0)
{
https://riptutorial.com/ 662
jint found_count = 0;
jlong* tags = &tag_ptr_list[0];
jobject* found_objects;
jlong* found_tags;
/*
* collect all tagged object (via *tag_ptr = pointer to tag )
* see
http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#GetObjectsWithTags
*/
jvmti->GetObjectsWithTags(tag_ptr_list.size(), tags, &found_count, &found_objects,
&found_tags);
stdout_message("found %d objects\n", found_count);
char* classSignature;
jclass found_object_class = env->GetObjectClass(found_object);
/*
* Get string representation of found_object_class
* see
http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#GetClassSignature
*/
jvmti->GetClassSignature(found_object_class, &classSignature, nullptr);
jint hashCode;
/*
* Getting hash code for found_object
* see
http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#GetObjectHashCode
*/
jvmti->GetObjectHashCode(found_object, &hashCode);
if (t->referrer_tag != 0)
{
stdout_message("referrer object %s#%d --> object %s#%d (size: %2d)\n",
rt->classSignature, rt->hashCode, t->classSignature, t->hashCode, t-
>size);
}
}
}
}
https://riptutorial.com/ 663
jvmtiEnv* jvmti;
/* Get JVMTI environment */
vm->GetEnv(reinterpret_cast<void **>(&jvmti), JVMTI_VERSION);
jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, nullptr);
return JNI_OK;
}
https://riptutorial.com/ 664
Chapter 104: Lambda Expressions
Introduction
Lambda expressions provide a clear and concise way of implementing a single-method interface
using an expression. They allow you to reduce the amount of code you have to create and
maintain. While similar to anonymous classes, they have no type information by themselves. Type
inference needs to happen.
Method references implement functional interfaces using existing methods rather than
expressions. They belong to the lambda family as well.
Syntax
• () -> { return expression; } // Zero-arity with function body to return a value.
• () -> expression // Shorthand for the above declaration; there is no semicolon for
expressions.
• () -> { function-body } // Side-effect in the lambda expression to perform operations.
• parameterName -> expression // One-arity lambda expression. In lambda expressions with
only one argument, the parenthesis can be removed.
• (Type parameterName, Type secondParameterName, ...) -> expression // lambda evaluating
an expression with parameters listed to the left
• (parameterName, secondParameterName, ...) -> expression // Shorthand that removes the
parameter types for the parameter names. Can only be used in contexts that can be inferred
by the compiler where the given parameter list size matches one (and only one) of the size
of the functional interfaces expected.
Examples
Using Lambda Expressions to Sort a Collection
Sorting lists
Prior to Java 8, it was necessary to implement the java.util.Comparator interface with an
anonymous (or named) class when sorting a list1:
Java SE 1.2
https://riptutorial.com/ 665
}
);
Starting with Java 8, the anonymous class can be replaced with a lambda expression. Note that
the types for the parameters p1 and p2 can be left out, as the compiler will infer them automatically:
Collections.sort(
people,
(p1, p2) -> p1.getFirstName().compareTo(p2.getFirstName())
);
The example can be simplified by using Comparator.comparing and method references expressed
using the :: (double colon) symbol.
Collections.sort(
people,
Comparator.comparing(Person::getFirstName)
);
A static import allows us to express this more concisely, but it is debatable whether this improves
overall readability:
Comparators built this way can also be chained together. For example, after comparing people by
their first name, if there are people with the same first name, the thenComparing method with also
compare by last name:
sort(people, comparing(Person::getFirstName).thenComparing(Person::getLastName));
1 - Note that Collections.sort(...) only works on collections that are subtypes of List. The Set and Collection APIs
do not imply any ordering of the elements.
Sorting maps
You can sort the entries of a HashMap by value in a similar fashion. (Note that a LinkedHashMap must
be used as the target. The keys in an ordinary HashMap are unordered.)
Map<String, Integer> map = new HashMap(); // ... or any other Map class
// populate the map
map = map.entrySet()
.stream()
.sorted(Map.Entry.<String, Integer>comparingByValue())
.collect(Collectors.toMap(k -> k.getKey(), v -> v.getValue(),
(k, v) -> k, LinkedHashMap::new));
https://riptutorial.com/ 666
Introduction to Java lambdas
Functional Interfaces
Lambdas can only operate on a functional interface, which is an interface with just one abstract
method. Functional interfaces can have any number of default or static methods. (For this
reason, they are sometimes referred to as Single Abstract Method Interfaces, or SAM Interfaces).
interface Foo1 {
void bar();
}
interface Foo2 {
int bar(boolean baz);
}
interface Foo3 {
String bar(Object baz, int mink);
}
interface Foo4 {
default String bar() { // default so not counted
return "baz";
}
void quux();
}
When declaring a functional interface the @FunctionalInterface annotation can be added. This has
no special effect, but a compiler error will be generated if this annotation is applied to an interface
which is not functional, thus acting as a reminder that the interface should not be changed.
@FunctionalInterface
interface Foo5 {
void bar();
}
@FunctionalInterface
interface BlankFoo1 extends Foo3 { // inherits abstract method from Foo3
}
@FunctionalInterface
interface Foo6 {
void bar();
boolean equals(Object obj); // overrides one of Object's method so not counted
}
Conversely, this is not a functional interface, as it has more than one abstract method:
interface BadFoo {
void bar();
void quux(); // <-- Second method prevents lambda: which one should
// be considered as lambda?
}
https://riptutorial.com/ 667
This is also not a functional interface, as it does not have any methods:
interface BlankFoo2 { }
and
Then Child cannot be a functional interface since it has two specified methods.
Java 8 also provides a number of generic templated functional interfaces in the package
java.util.function. For example, the built-in interface Predicate<T> wraps a single method which
inputs a value of type T and returns a boolean.
Lambda Expressions
The basic structure of a Lambda expression is:
fi will then hold a singleton instance of a class, similar to an anonymous class, which implements
FunctionalInterface and where the one method's definition is { System.out.println("Hello"); }. In
other words, the above is mostly equivalent to:
The lambda is only "mostly equivalent" to the anonymous class because in a lambda, the meaning
of expressions like this, super or toString() reference the class within which the assignment takes
place, not the newly created object.
You cannot specify the name of the method when using a lambda—but you shouldn't need to,
because a functional interface must have only one abstract method, so Java overrides that one.
https://riptutorial.com/ 668
In cases where the type of the lambda is not certain, (e.g. overloaded methods) you can add a
cast to the lambda to tell the compiler what its type should be, like so:
If the functional interface's single method takes parameters, the local formal names of these
should appear between the brackets of the lambda. There is no need to declare the type of the
parameter or return as these are taken from the interface (although it is not an error to declare the
parameter types if you want to). Thus, these two examples are equivalent:
The parentheses around the argument can be omitted if the function only has one argument:
Implicit Returns
If the code placed inside a lambda is a Java expression rather than a statement, it is treated as a
method which returns the value of the expression. Thus, the following two are equivalent:
https://riptutorial.com/ 669
If it is necessary to wrap a changing variable in this way, a regular object that keeps a copy of the
variable should be used. Read more in Java Closures with lambda expressions.
Accepting Lambdas
Because a lambda is an implementation of an interface, nothing special needs to be done to make
a method accept a lambda: any function which takes a functional interface can also accept a
lambda.
Until any such assignment to a functional type is made, the lambda does not have a definite type.
To illustrate, consider the lambda expression o -> o.isEmpty(). The same lambda expression can
be assigned to many different functional types:
Now that they are assigned, the examples shown are of completely different types even though
the lambda expressions looked the same, and they cannot be assigned to each other.
Method References
Method references allow predefined static or instance methods that adhere to a compatible
functional interface to be passed as arguments instead of an anonymous lambda expression.
https://riptutorial.com/ 670
class Person {
private final String name;
private final String surname;
people.stream().map(Person::getName)
In this example, a method reference to the instance method getName() of type Person, is being
passed. Since it's known to be of the collection type, the method on the instance (known later) will
be invoked.
people.forEach(System.out::println);
Since System.out is an instance of PrintStream, a method reference to this specific instance is being
passed as an argument.
This example passes a reference to the static valueOf() method on the String type. Therefore, the
https://riptutorial.com/ 671
instance object in the collection is passed as an argument to valueOf().
Reference to a constructor
Read Collect Elements of a Stream into a Collection to see how to collect elements to collection.
The single String argument constructor of the Integer type is being used here, to construct an
integer given the string provided as the argument. In this case, as long as the string represents a
number, the stream will be mapped to Integers. The equivalent lambda:
Cheat-Sheet
**If TypeName is a non-static inner class, constructor reference is only valid within the scope of an
outer class instance
Sometimes you may want to have a lambda expression implementing more than one interface.
https://riptutorial.com/ 672
This is mostly useful with marker interfaces (such as java.io.Serializable) since they don't add
abstract methods.
For example, you want to create a TreeSet with a custom Comparator and then serialize it and send
it over the network. The trivial approach:
doesn't work since the lambda for the comparator does not implement Serializable. You can fix
this by using intersection types and explicitly specifying that this lambda needs to be serializable:
If you're frequently using intersection types (for example, if you're using a framework such as
Apache Spark where almost everything has to be serializable), you can create empty interfaces
and use them in your code instead:
This way you're guaranteed that the passed comparator will be serializable.
There are several good examples of using lambdas as a FunctionalInterface in simple scenarios.
A fairly common use case that can be improved by lambdas is what is called the Execute-Around
pattern. In this pattern, you have a set of standard setup/teardown code that is needed for multiple
scenarios surrounding use case specific code. A few common example of this are file io, database
io, try/catch blocks.
interface DataProcessor {
void process( Connection connection ) throws SQLException;;
}
https://riptutorial.com/ 673
This is not limited to I/O operations. It can apply to any scenario where similar setup/tear down
tasks are applicable with minor variations. The main benefit of this Pattern is code re-use and
enforcing DRY (Don't Repeat Yourself).
Lambdas are meant to provide inline implementation code for single method interfaces and the
ability to pass them around as we have been doing with normal variables. We call them Functional
Interface.
For example, writing a Runnable in anonymous class and starting a Thread looks like:
//Old way
new Thread(
new Runnable(){
public void run(){
System.out.println("run logic...");
}
}
).start();
Now, in line with above, lets say you have some custom interface:
interface TwoArgInterface {
int operate(int a, int b);
}
How do you use lambda to give implementation of this interface in your code? Same as Runnable
example shown above. See the driver program below:
}
}
`return` only returns from the lambda, not the outer method
https://riptutorial.com/ 674
The return method only returns from the lambda, not the outer method.
void threeTimes(IntConsumer r) {
for (int i = 0; i < 3; i++) {
r.accept(i);
}
}
void demo() {
threeTimes(i -> {
System.out.println(i);
return; // Return from lambda to threeTimes only!
});
}
This can lead to unexpected behavior when attempting to write own language constructs, as in
builtin constructs such as for loops return behaves differently:
void demo2() {
for (int i = 0; i < 3; i++) {
System.out.println(i);
return; // Return from 'demo2' entirely
}
}
In Scala and Kotlin, demo and demo2 would both only print 0. But this is not more consistent. The
Java approach is consistent with refactoring and the use of classes - the return in the code at the
top, and the code below behaves the same:
void demo3() {
threeTimes(new MyIntConsumer());
}
Therefore, the Java return is more consistent with class methods and refactoring, but less with the
for and while builtins, these remain special.
IntStream.range(1, 4)
.map(x -> x * x)
.forEach(System.out::println);
IntStream.range(1, 4)
.map(x -> { return x * x; })
.forEach(System.out::println);
https://riptutorial.com/ 675
Furthermore, the use of try-with-resources is safe in Java:
void executeAround(Consumer<Resource> f) {
try (Resource r = new Resource()) {
System.out.print("before ");
f.accept(r);
System.out.print("after ");
}
}
void demo4() {
executeAround(r -> {
System.out.print("accept() ");
return; // Does not return from demo4, but frees the resource.
});
}
will print before accept() after close(). In the Scala and Kotlin semantics, the try-with-resources
would not be closed, but it would print before accept() only.
A lambda closure is created when a lambda expression references the variables of an enclosing
scope (global or local). The rules for doing this are the same as those for inline methods and
anonymous classes.
Local variables from an enclosing scope that are used within a lambda have to be final. With Java
8 (the earliest version that supports lambdas), they don't need to be declared final in the outside
context, but must be treated that way. For example:
This is legal as long as the value of the n variable is not changed. If you try to change the variable,
inside or outside the lambda, you will get the following compilation error:
"local variables referenced from a lambda expression must be final or effectively final".
For example:
int n = 0;
Runnable r = () -> { // Using lambda
int i = n;
// do something
};
n++; // Will generate an error.
https://riptutorial.com/ 676
If it is necessary to use a changing variable within a lambda, the normal approach is to declare a
final copy of the variable and use the copy. For example
int n = 0;
final int k = n; // With Java 8 there is no need to explicit final
Runnable r = () -> { // Using lambda
int i = k;
// do something
};
n++; // Now will not generate an error
r.run(); // Will run with i = 0 because k was 0 when the lambda was created
Naturally, the body of the lambda does not see the changes to the original variable.
Note that Java does not support true closures. A Java lambda cannot be created in a way that
allows it to see changes in the environment in which it was instantiated. If you want to implement a
closure that observes or makes changes to its environment, you should simulate it using a regular
class. For example:
The above example will not compile for reasons discussed previously. We can work around the
compilation error as follows:
The problem is that this breaks the design contract for the IntUnaryOperator interface which states
that instances should be functional and stateless. If such a closure is passed to built-in functions
that accept functional objects, it is liable to cause crashes or erroneous behavior. Closures that
encapsulate mutable state should be implemented as regular classes. For example.
// Correct ...
public class Accumulator {
private int value = 0;
https://riptutorial.com/ 677
Lambda - Listener Example
Before Java 8, it’s very common that an anonymous class is used to handle click event of a
JButton, as shown in the following code. This example shows how to implement an anonymous
listener within the scope of btn.addActionListener.
Lambda listener
Because the ActionListener interface defines only one method actionPerformed(), it is a functional
interface which means there’s a place to use Lambda expressions to replace the boilerplate code.
The above example can be re-written using Lambda expressions as follows:
Traditional way
interface MathOperation{
boolean unaryOperation(int num);
}
System.out.println(isEven.unaryOperation(25));
System.out.println(isEven.unaryOperation(20));
}
}
Lambda style
https://riptutorial.com/ 678
public class LambdaTry {
public static void main(String[] args) {
MathOperation isEven = (int num) -> {
return num%2 == 0;
};
System.out.println(isEven.unaryOperation(25));
System.out.println(isEven.unaryOperation(20));
}
}
Since Java lambdas are closures, they can "capture" the values of variables in the enclosing
lexical scope. While not all lambdas capture anything -- simple lambdas like s -> s.length()
capture nothing and are called stateless -- capturing lambdas require a temporary object to hold
the captured variables. In this code snippet, the lambda () -> j is a capturing lambda, and may
cause an object to be allocated when it is evaluated:
Although it might not be immediately obvious since the new keyword doesn't appear anywhere in
the snippet, this code is liable to create 1,000,000,000 separate objects to represent the instances
of the () -> j lambda expression. However, it should also be noted that future versions of Java1
may be able to optimize this so that at runtime the lambda instances were reused, or were
represented in some other way.
1 - For instance, Java 9 introduces an optional "link" phase to the Java build sequence which will provide the
https://riptutorial.com/ 679
opportunity for doing global optimizations like this.
Using lambda expressions & predicates to get a certain value(s) from a list
Starting with Java 8, you can use lambda expressions & predicates.
Example: Use a lambda expressions & a predicate to get a certain value from a list. In this
example every person will be printed out with the fact if they are 18 and older or not.
Person Class:
Example Usage:
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
The print(personList, p -> p.getAge() >= 18); method takes a lambda expression (because the
Predicate is used a parameter) where you can define the expression that is needed. The checker's
https://riptutorial.com/ 680
test method checks if this expression is correct or not: checker.test(person).
You can easily change this to something else, for example to print(personList, p ->
p.getName().startsWith("J"));. This will check if the person's name starts with a "J".
https://riptutorial.com/ 681
Chapter 105: LinkedHashMap
Introduction
LinkedHashMap class is Hash table and Linked list implementation of the Map interface, with
predictable iteration order. It inherits HashMap class and implements the Map interface.
The important points about Java LinkedHashMap class are: A LinkedHashMap contains values
based on the key. It contains only unique elements. It may have one null key and multiple null
values. It is same as HashMap instead maintains insertion order.
Examples
Java LinkedHashMap class
Key Points:-
• Is Hash table and Linked list implementation of the Map interface, with predictable iteration
order.
Methods :-
• void clear().
• boolean containsKey(Object key).
• Object get(Object key).
• protected boolean removeEldestEntry(Map.Entry eldest)
Example :-
https://riptutorial.com/ 682
Iterator i = set.iterator();
while (i.hasNext()) {
Map.Entry me = (Map.Entry) i.next();
System.out.println(me.getKey() + " : " + me.getValue());
}
https://riptutorial.com/ 683
Chapter 106: List vs SET
Introduction
What are differences between List and Set collection at the top level and How to choose when to
use List in java and when to use Set in Java
Examples
List vs Set
import java.util.ArrayList;
public class SetAndListExample { public static void main( String[] args ) { System.out.println("List
example ....."); List list = new ArrayList(); list.add("1"); list.add("2"); list.add("3"); list.add("4");
list.add("1");
https://riptutorial.com/ 684
Chapter 107: Lists
Introduction
A list is an ordered collection of values. In Java, lists are part of the Java Collections Framework.
Lists implement the java.util.List interface, which extends java.util.Collection.
Syntax
• ls.add(E element); //Adds an element
• ls.remove(E element); //Removes an element
• for(E element : ls){} //Iterates over each element
• ls.toArray(new String[ls.length]); //Converts a List of Strings to an array of Strings
• ls.get(int index); //Returns the element at the specified index.
• ls.set(int index, E element); //Replaces the element at a specified position .
• ls.isEmpty(); //Returns true if the array contains no elements, otherwise it returns false.
• ls.indexOf(Object o); //Returns the index of the first location of the specified element o, or, if
it is not present, returns -1.
• ls.lastIndexOf(Object o); //Returns the index of the last location of the specified element o,
or, if it is not present, returns -1.
• ls.size(); //Returns the number of elements in the List.
Remarks
A list is an object which stores a an ordered collection of values. "Ordered" means the values are
stored in a particular order--one item comes first, one comes second, and so on. The individual
values are commonly called "elements". Java lists typically provide these features:
Adding a value to a list at some point other than the end will move all of the following elements
"down" or "to the right". In other words, adding an element at index n moves the element which
used to be at index n to index n+1, and so on. For example:
https://riptutorial.com/ 685
List<String> list = new ArrayList<>();
list.add("world");
System.out.println(list.indexOf("world")); // Prints "0"
// Inserting a new value at index 0 moves "world" to index 1
list.add(0, "Hello");
System.out.println(list.indexOf("world")); // Prints "1"
System.out.println(list.indexOf("Hello")); // Prints "0"
Examples
Sorting a generic list
The Collections class offers two standard static methods to sort a list:
• sort(List<T> list) applicable to lists where T extends Comparable<? super T>, and
• sort(List<T> list, Comparator<? super T> c) applicable to lists of any type.
Applying the former requires amending the class of list elements being sorted, which is not always
possible. It might also be undesirable as although it provides the default sorting, other sorting
orders may be required in different circumstances, or sorting is just a one off task.
Consider we have a task of sorting objects that are instances of the following class:
@Override
public String toString() {
return String.format("%s:%d", username, id);
}
}
In order to use Collections.sort(List<User> list) we need to modify the User class to implement
the Comparable interface. For example
@Override
public String toString() {
return String.format("%s:%d", username, id);
}
https://riptutorial.com/ 686
@Override
/** The natural ordering for 'User' objects is by the 'id' field. */
public int compareTo(User o) {
return id.compareTo(o.id);
}
}
(Aside: many standard Java classes such as String, Long, Integer implement the Comparable
interface. This makes lists of those elements sortable by default, and simplifies implementation of
compare or compareTo in other classes.)
With the modification above, the we can easily sort a list of User objects based on the classes
natural ordering. (In this case, we have defined that to be ordering based on id values). For
example:
System.out.print(users);
// [B:25, C:28, A:33]
However, suppose that we wanted to sort User objects by name rather than by id. Alternatively,
suppose that we had not been able to change the class to make it implement Comparable.
This is where the sort method with the Comparator argument is useful:
Java SE 8
In Java 8 you can use a lambda instead of an anonymous class. The latter reduces to a one-liner:
Further, there Java 8 adds a default sort method on the List interface, which simplifies sorting
even more.
Creating a List
https://riptutorial.com/ 687
Giving your list a type
To create a list you need a type (any class, e.g. String). This is the type of your List. The List will
only store objects of the specified type. For example:
List<String> strings;
Can store "string1", "hello world!", "goodbye", etc, but it can't store 9.2, however:
List<Double> doubles;
If you try to add something to the lists above you will get a NullPointerException, because strings
and doubles both equal null!
List is an interface, which means that does not have a constructor, rather methods that a class
must override. ArrayList is the most commonly used List, though LinkedList is also common. So
we initialise our list like this:
or
Java SE 7
or
The Collections class provides two useful methods for creating Lists without a List variable:
https://riptutorial.com/ 688
And a method which uses an existing List to fill data in:
• addAll(L, T...): adds all the specified elements to the list passed as the first parameter.
Examples:
import java.util.List;
import java.util.Collections;
List<Integer> l = Collections.emptyList();
List<Integer> l1 = Collections.singletonList(42);
Collections.addAll(l1, 1, 2, 3);
The List API has eight methods for positional access operations:
• add(T type)
• add(int index, T type)
• remove(Object o)
• remove(int index)
• get(int index)
• set(int index, E element)
• int indexOf(Object o)
• int lastIndexOf(Object o)
And we wanted to add the strings "Hello world!" and "Goodbye world!" to it, we would do it as
such:
strings.add("Hello world!");
strings.add("Goodbye world!");
And our list would contain the two elements. Now lets say we wanted to add "Program starting!" at
the front of the list. We would do this like this:
Now, if we wanted to remove the "Goodbye world!" line, we could do it like this:
strings.remove("Goodbye world!");
And if we wanted to remove the first line (which in this case would be "Program starting!", we
could do it like this:
https://riptutorial.com/ 689
strings.remove(0);
Note:
1. Adding and removing list elements modify the list, and this can lead to a
ConcurrentModificationException if the list is being iterated concurrently.
2. Adding and removing elements can be O(1) or O(N) depending on the list class, the method
used, and whether you are adding / removing an element at the start, the end, or in the
middle of the list.
In order to retrieve an element of the list at a specified position you can use the E get(int index);
method of the List API. For example:
strings.get(0);
You can replace any element at a specified position by using the set(int index, E element);. For
example:
strings.set(0,"This is a replacement");
This will set the String "This is a replacement" as the first element of the list.
Note: The set method will overwrite the element at the position 0. It will not add the new String at
the position 0 and push the old one to the position 1.
The int indexOf(Object o); returns the position of the first occurrence of the object passed as
argument. If there are no occurrences of the object in the list then the -1 value is returned. In
continuation of the previous example if you call:
strings.indexOf("This is a replacement")
the 0 is expected to be returned as we set the String "This is a replacement" in the position 0 of
our list. In case where there are more than one occurrence in the list when int indexOf(Object o);
is called then as mentioned the index of the first occurrence will be returned. By calling the int
lastIndexOf(Object o) you can retrieve the index of the last occurrence in the list. So if we add
another "This is a replacement":
strings.add("This is a replacement");
strings.lastIndexOf("This is a replacement");
For the example, lets say that we have a List of type String that contains four elements: "hello, ",
https://riptutorial.com/ 690
"how ", "are ", "you?"
The best way to iterate over each element is by using a for-each loop:
hello,
how
are
you?
To print them all in the same line, you can use a StringBuilder:
Will print:
Alternatively, you can use element indexing ( as described in Accessing element at ith Index from
ArrayList ) to iterate a list. Warning: this approach is inefficient for linked lists.
Lets suppose you have 2 Lists A and B, and you want to remove from B all the elements that you
have in A the method in this case is
List.removeAll(Collection c);
#Example:
numbersB.removeAll(numbersA);
https://riptutorial.com/ 691
System.out.println("B cleared: " + numbersB);
}
A: [1, 3, 4, 7, 5, 2]
Suppose you have two lists: A and B, and you need to find the elements that exist in both lists.
Example:
That is:
https://riptutorial.com/ 692
is one of the inbuilt data structures in Java. It is a dynamic array (where the size of the data
structure not needed to be declared first) for storing elements (Objects).
It extends AbstractList class and implements List interface. An ArrayList can contain duplicate
elements where it maintains insertion order. It should be noted that the class ArrayList is non-
synchronized, so care should be taken when handling concurrency with ArrayList. ArrayList allows
random access because array works at the index basis. Manipulation is slow in ArrayList because
of shifting that often occurs when an element is removed from the array list.
The type of the ArrayList can be any Object. The type can't be a primitive type (use their wrapper
classes instead).
myArrayList.add(element);
myArrayList.remove(element);
This example is about replacing a List element while ensuring that the replacement element is at
the same position as the element that is replaced.
Consider an ArrayList containing the elements "Program starting!", "Hello world!" and "Goodbye
world!"
https://riptutorial.com/ 693
strings.add("Program starting!");
strings.add("Hello world!");
strings.add("Goodbye world!");
If we know the index of the element we want to replace, we can simply use set as follows:
If we don't know the index, we can search for it first. For example:
Notes:
If you want an unmodifiable list with one item you can use:
The Collections class allows for you to move objects around in the list using various methods (ls is
the List):
Reversing a list:
Collections.reverse(ls);
The rotate method requires an integer argument. This is how many spots to move it along the line
by. An example of this is below:
https://riptutorial.com/ 694
ls.add(" you?");
ls.add("hello,");
Collections.rotate(ls, 1);
Using the same list above, we can shuffle the elements in a list:
Collections.shuffle(ls);
We can also give it a java.util.Random object that it uses to randomly place objects in spots:
The List interface is implemented by different classes. Each of them has its own way for
implementing it with different strategies and providing different pros and cons.
1. Abstract Classes:
• AbstractList
• AbstractSequentialList
2. Concrete Classes:
• ArrayList
• AttributeList
• CopyOnWriteArrayList
• LinkedList
• RoleList
• RoleUnresolvedList
• Stack
• Vector
https://riptutorial.com/ 695
ArrayList
ArrayList is a resizable-array implementation of the List interface. Storing the list into an array,
ArrayList provides methods (in addition to the methods implementing the List interface) for
manipulating the size of the array.
- PROS:
The size, isEmpty, get, set, iterator, and listIterator operations run in constant time. So getting and
setting each element of the List has the same time cost:
int e1 = myList.get(0); // \
int e2 = myList.get(10); // | => All the same constant cost => O(1)
myList.set(2,10); // /
- CONS:
Being implemented with an array (static structure) adding elements over the size of the array has
a big cost due to the fact that a new allocation need to be done for all the array. However, from
documentation:
The add operation runs in amortized constant time, that is, adding n elements requires
O(n) time
AttributeList
On coming
CopyOnWriteArrayList
On coming
LinkedList
https://riptutorial.com/ 696
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable
LinkedList is implemented by a doubly-linked list a linked data structure that consists of a set of
sequentially linked records called nodes.
- PROS:
Adding or removing an element to the front of the list or to the end has constant time.
myList.add(10); // \
myList.add(0,2); // | => constant time => O(1)
myList.remove(); // /
Operations that index into the list will traverse the list from the beginning or the end,
whichever is closer to the specified index.
myList.get(10); // \
myList.add(11,25); // | => worst case done in O(n/2)
myList.set(15,35); // /
RoleList
On coming
RoleUnresolvedList
On coming
Stack
On coming
Vector
https://riptutorial.com/ 697
On coming
https://riptutorial.com/ 698
Chapter 108: Literals
Introduction
A Java literal is a syntactic element (i.e. something you find in the source code of a Java program)
that represents a value. Examples are 1, 0.333F, false, 'X' and "Hello world\n".
Examples
Hexadecimal, Octal and Binary literals
A hexadecimal number is a value in base-16. There are 16 digits, 0-9 and the letters A-F (case does
not matter). A-F represent 10-16.
The octal literal can easily be a trap for semantic errors. If you define a leading '0' to your decimal
literals you will get the wrong value:
Since Java 7 it has been possible to use one or more underscores (_) for separating groups of
digits in a primitive number literal to improve their readability.
Java SE 7
int i1 = 123456;
int i2 = 123_456;
System.out.println(i1 == i2); // true
Java SE 7
https://riptutorial.com/ 699
byte color = 1_2_3;
short yearsAnnoDomini= 2_016;
int socialSecurtyNumber = 999_99_9999;
long creditCardNumber = 1234_5678_9012_3456L;
float piFourDecimals = 3.14_15F;
double piTenDecimals = 3.14_15_92_65_35;
This also works using prefixes for binary, octal and hexadecimal bases:
Java SE 7
There are a few rules about underscores which forbid their placement in the following places:
• At the beginning or end of a number (e.g. _123 or 123_ are not valid)
• Adjacent to a decimal point in a floating point literal (e.g. 1._23 or 1_.23 are not valid)
• Prior to an F or L suffix (e.g. 1.23_F or 9999999_L are not valid)
• In positions where a string of digits is expected (e.g. 0_xFFFF is not valid)
String and character literals provide an escape mechanism that allows express character codes
that would otherwise not be allowed in the literal. An escape sequence consists of a backslash
character (\) followed by one ore more other characters. The same sequences are valid in both
character an string literals.
https://riptutorial.com/ 700
The <octal> in the above consists of one, two or three octal digits ('0' through '7') which represent
a number between 0 and 255 (decimal).
Note that a backslash followed by any other character is an invalid escape sequence. Invalid
escape sequences are treated as compilation errors by the JLS.
Reference:
Unicode escapes
In addition to the string and character escape sequences described above, Java has a more
general Unicode escaping mechanism, as defined in JLS 3.3. Unicode Escapes. A Unicode
escape has the following syntax:
where <hex-digit> is one of '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
'A', 'B', 'C', 'D', 'E', 'F'.
A Unicode escape is mapped by the Java compiler to a character (strictly speaking a 16-bit
Unicode code unit), and can be used anywhere in the source code where the mapped character is
valid. It is commonly used in character and string literals when you need to represent a non-ASCII
character in a literal.
Escaping in regexes
TBD
Integer literals provide values that can be used where you need a byte, short, int, long or char
instance. (This example focuses on the simple decimal forms. Other examples explain how to
literals in octal, hexadecimal and binary, and the use of underscores to improve readability.)
You need to be careful with leading zeros. A leading zero causes an integer literal to be
interpreted as octal not decimal.
https://riptutorial.com/ 701
077 // This literal actually means 7 x 8 + 7 ... or 63 decimal!
Integer literals are unsigned. If you see something like -10 or +10, these are actually expressions
using the unary - and unary + operators.
The range of integer literals of this form have an intrinsic type of int, and must fall in the range
zero to 231 or 2,147,483,648.
Note that 231 is 1 greater than Integer.MAX_VALUE. Literals from 0 through to 2147483647 can be used
anywhere, but it is a compilation error to use 2147483648 without a preceding unary - operator. (In
other words, it is reserved for expressing the value of Integer.MIN_VALUE.)
Note that the distinction between int and long literals is significant in other places. For example
int i = 2147483647;
long l = i + 1; // Produces a negative value because the operation is
// performed using 32 bit arithmetic, and the
// addition overflows
long l2 = i + 1L; // Produces the (intuitively) correct value.
Boolean literals
Boolean literals are the simplest of the literals in the Java programming language. The two
possible boolean values are represented by the literals true and false. These are case-sensitive.
For example:
String literals
https://riptutorial.com/ 702
String literals provide the most convenient way to represent string values in Java source code. A
String literal consists of:
For example:
Note that a single string literal may not span multiple source code lines. It is a compilation error for
a line-break (or the end of the source file) to occur before a literal's closing double-quote. For
example:
Long strings
If you need a string that is too long to fit on a line, the conventional way to express it is to split it
into multiple literals and use the concatenation operator (+) to join the pieces. For example
An expression like the above consisting of string literals and + satisfies the requirements to be a
Constant Expression. That means that the expression will be evaluated by the compiler and
represented at runtime by a single String object.
For more information on interning and the string pool, refer to the String pool and heap storage
example in the Strings topic.
The Null literal (written as null) represents the one and only value of the null type. Here are some
https://riptutorial.com/ 703
examples
myMethod(null);
if (objects != null) {
// Do something
}
The null type is rather unusual. It has no name, so you cannot express it in Java source code.
(And it has no runtime representation either.)
The sole purpose of the null type is to be the type of null. It is assignment compatible with all
reference types, and can be type cast to any reference type. (In the latter case, the cast does not
entail a runtime type check.)
Finally, null has the property that null instanceof <SomeReferenceType> will evaluate to false, no
matter what the type is.
Floating-point literals
Floating point literals provide values that can be used where you need a float or double instance.
There are three kinds of floating point literal.
(The JLS syntax rules combine the two decimal forms into a single form. We treat them separately
for ease of explanation.)
There are distinct literal types for float and double literals, expressed using suffixes. The various
forms use letters to express different things. These letters are case insensitive.
For example
https://riptutorial.com/ 704
In fact, decimal digits followed by a suffix is also a floating point literal.
The meaning of a decimal literal is the IEEE floating point number that is closest to the infinite
precision mathematical Real number denoted by the decimal floating point form. This conceptual
value is converted to IEEE binary floating point representation using round to nearest. (The
precise semantics of decimal conversion are specified in the javadocs for Double.valueOf(String)
and Float.valueOf(String), bearing in mind that there are differences in the number syntaxes.)
The size of a literal is limited by the representation (float or double). It is a compilation error if the
scale factor results in a value that is too large or too small.
Hexadecimal forms
Starting with Java 6, it is possible to express floating point literals in hexadecimal. The
hexadecimal form have an analogous syntax to the simple and scaled decimal forms with the
following differences:
1. Every hexadecimal floating point literal starts with a zero (0) and then an x or X.
2. The digits of the number (but not the exponent part!) also include the hexadecimal digits a
through f and their uppercase equivalents.
3. The exponent is mandatory, and is introduced by the letter p (or P) instead of an e or E. The
exponent represents a scaling factor that is a power of 2 instead of a power of 10.
Advice: since hexadecimal floating-point forms are unfamiliar to most Java programmers, it is
advisable to use them sparingly.
Underscores
https://riptutorial.com/ 705
Starting with Java 7, underscores are permitted within the digit strings in all three forms of floating
point literal. This applies to the "exponent" parts as well. See Using underscores to improve
readability.
Special cases
It is a compilation error if a floating point literal denotes a number that is too large or too small to
represent in the selected representation; i.e. if the number would overflow to +INF or -INF, or
underflow to 0.0. However, it is legal for a literal to represent a non-zero denormalized number.
The floating point literal syntax does not provide literal representations for IEEE 754 special values
such as the INF and NaN values. If you need to express them in source code, the recommended
way is to use the constants defined by the java.lang.Float and java.lang.Double; e.g. Float.NaN,
Float.NEGATIVE_INFINITY and Float.POSITIVE_INFINITY.
Character literals
Character literals provide the most convenient way to express char values in Java source code. A
character literal consists of:
For example:
char a = 'a';
char doubleQuote = '"';
char singleQuote = '\'';
https://riptutorial.com/ 706
Chapter 109: Local Inner Class
Introduction
A class i.e. created inside a method is called local inner class in java. If you want to invoke the
methods of local inner class, you must instantiate this class inside the method.
Examples
Local Inner Class
https://riptutorial.com/ 707
Chapter 110: Localization and
Internationalization
Remarks
Java comes with a powerful and flexible mechanism for localizing your applications, but it's also
easy to misuse and wind up with a program that disregards or mangles the user's locale, and
therefore how they expect your program to behave.
Your users will expect to see data localized to the formats they're used to, and attempting to
support this manually is a fools errand. Here is just a small example of the different ways users
expect to see content you might assume is "always" displayed a certain way:
Brazil
China
Egypt
General Resources
• Wikipedia: Internationalization and Localization
Java Resources
• Java Tutorial: Internationalization
• Oracle: Internationalization: Understanding Locale in the Java Platform
• JavaDoc: Locale
Examples
Automatically formatted Dates using "locale"
SimpleDateFormatter is great in a pinch, but like the name suggests it doesn't scale well.
https://riptutorial.com/ 708
If you hard-code "MM/dd/yyyy" all over your application your international users won't be happy.
Where style is one of the formatting constants (FULL, LONG, MEDIUM, SHORT, etc.) specified in
DateFormat.
For a server-side application where the user specifies their locale as part of the request, you
should pass it explicitly to getDateInstance() instead:
String localizedDate =
DateFormat.getDateInstance(style, request.getLocale()).format(date);
String Comparison
"School".equalsIgnoreCase("school"); // true
Don't use
text1.toLowerCase().equals(text2.toLowerCase());
Languages have different rules for converting upper and lower case. A 'I' would be converted to 'i'
in English. But in Turkish a 'I' becomes a 'ı'. If you have to use toLowerCase() use the overload
which expects a Locale: String.toLowerCase(Locale).
Sort Strings respecting natural language order, ignoring case (use collation key to:
Locale
https://riptutorial.com/ 709
The java.util.Locale class is used to represent a "geographical, political or cultural" region to
localize a given text, number, date or operation to. A Locale object may thus contain a country,
region, language, and also a variant of a language, for instance a dialect spoken in a certain
region of a country, or spoken in a different country than the country from which the language
originates.
The Locale instance is handed to components that need to localize their actions, whether it is
converting the input, output, or just need it for internal operations. The Locale class cannot do any
internationalization or localization by itself
Language
The language must be an ISO 639 2 or 3 character language code, or a registered language
subtag of up to 8 characters. In case a language has both a 2 and 3 character language code, use
the 2 character code. A full list of language codes can be found in the IANA Language Subtag
Registry.
Language codes are case insensitive, but the Locale class always use lowercase versions of the
language codes
Creating a Locale
Creating a java.util.Locale instance can be done in four different ways:
Locale constants
Locale constructors
Locale.Builder class
Locale.forLanguageTag factory method
Java ResourceBundle
You create a ResourceBundle instance like this:
message=This is locale
Output:
This is locale
https://riptutorial.com/ 710
Setting Locale
If you want to reproduce the state using other languages, you can use setDefault() method. Its
usage:
https://riptutorial.com/ 711
Chapter 111: LocalTime
Syntax
• LocalTime time = LocalTime.now(); // Initializes with current system clock
• LocalTime time = LocalTime.MIDNIGHT; // 00:00
• LocalTime time = LocalTime.NOON; // 12:00
• LocalTime time = LocalTime.of(12, 12, 45); // 12:12:45
Parameters
Method Output
LocalTime.MIDNIGHT 00:00
LocalTime.NOON 12:00
Remarks
As class name denotes, LocalTime represents a time without a time-zone. It doesn't represent a
date. It's a simple label for a given time.
The class is value-based and the equals method should be used when doing comparisons.
Examples
Time Modification
https://riptutorial.com/ 712
LocalTime addHours = time.plusHours(5); // Add 5 hours
LocaLTime addMinutes = time.plusMinutes(15) // Add 15 minutes
LocalTime addSeconds = time.plusSeconds(30) // Add 30 seconds
LocalTime addNanoseconds = time.plusNanos(150_000_000) // Add 150.000.000ns (150ms)
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
There are two equivalent ways to calculate the amount of time unit between two LocalTime: (1)
through until(Temporal, TemporalUnit) method and through (2) TemporalUnit.between(Temporal,
Temporal).
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
https://riptutorial.com/ 713
long seconds1 = start.until(end, ChronoUnit.SECONDS); // 4220
long seconds2 = ChronoUnit.SECONDS.between(start, end); // 4220
Intro
LocalTime is an immutable class and thread-safe, used to represent time, often viewed as hour-
min-sec. Time is represented to nanosecond precision. For example, the value
"13:45.30.123456789" can be stored in a LocalTime.
This class does not store or represent a date or time-zone. Instead, it is a description of the local
time as seen on a wall clock. It cannot represent an instant on the time-line without additional
information such as an offset or time-zone. This is a value based class, equals method should be
used for comparisons.
Fields
https://riptutorial.com/ 714
You can also add/subtract hours, minutes or seconds from any object of LocalTime.
now.plusHours(1L);
now1.minusMinutes(20L);
https://riptutorial.com/ 715
Chapter 112: log4j / log4j2
Introduction
Apache Log4j is a Java-based logging utility, it is one of several Java logging frameworks. This
topic is to show how to setup and configure Log4j in Java with detailed examples on all of its
possible aspects of usage.
Syntax
• Logger.debug("text to log"); // Logging debugging info
• Logger.info("text to log"); // Logging common info
• Logger.error("text to log"); // Logging error info
• Logger.warn("text to log"); // Logging warnings
• Logger.trace("text to log"); // Logging trace info
• Logger.fatal("text to log"); // Logging fatal errors
• Log4j2 usage with parameter logging:
• Logger.debug("Debug params {} {} {}", param1, param2, param3); // Logging debug with
parameters
• Logger.info("Info params {} {} {}", param1, param2, param3); // Logging info with parameters
• Logger.error("Error params {} {} {}", param1, param2, param3); // Logging error with
parameters
• Logger.warn("Warn params {} {} {}", param1, param2, param3); // Logging warnings with
parameters
• Logger.trace("Trace params {} {} {}", param1, param2, param3); // Logging trace with
parameters
• Logger.fatal("Fatal params {} {} {}", param1, param2, param3); // Logging fatal with
parameters
• Logger.error("Caught Exception: ", ex ); // Logging exception with message and stacktrace
(will automatically be appended)
Remarks
From: http://logging.apache.org/log4j/1.2/
https://riptutorial.com/ 716
Examples
How to get Log4j
Using Maven:
Add the following dependency to your POM.xml file:
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
Using Ivy:
<dependencies>
<dependency org="org.apache.logging.log4j" name="log4j-api" rev="2.6.2" />
<dependency org="org.apache.logging.log4j" name="log4j-core" rev="2.6.2" />
</dependencies>
Using Gradle:
dependencies {
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.6.2'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.6.2'
}
Using Maven:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
https://riptutorial.com/ 717
</dependency>
Using Ivy:
Usign Gradle:
Using Buildr:
'log4j:log4j:jar:1.2.17'
//logs an exception
logger.error("Information about some error: ", exception);
Log4j gives you posibility to log data into console and file at same time. Create a log4j.properties
file and put inside this basic configuration:
https://riptutorial.com/ 718
# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
/ProjectFolder/src/java/resources
This is a basic log4j2.xml configuration which has a console appender and a root logger. The
pattern layout specifies which pattern should be used for logging the statements.
In order to debug the loading of log4j2.xml you can add the attribute status = <WARN | DEBUG |
ERROR | FATAL | TRACE | INFO> in the configuration tag of your log4j2.xml.
You can also add a monitor interval so that it loads the configuration again after the specified
interval period. The monitor interval can be added to the configuration tag as follows:
monitorInterval = 30. It means that the config will be loaded every 30 seconds.
If you want to migrate from existing log4j 1.x in your project to log4j 2.x then remove all existing
log4j 1.x dependencies and add the following dependency:
Maven Build
<dependencies>
https://riptutorial.com/ 719
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
Ivy Build
<dependencies>
<dependency org="org.apache.logging.log4j" name="log4j-1.2-api" rev="2.6.2" />
</dependencies>
Gradle Build
dependencies {
compile group: 'org.apache.logging.log4j', name: 'log4j-1.2-api', version: '2.6.2'
}
Apache Commons Logging Bridge If your project is using Apache Commons Logging which use
log4j 1.x and you want to migrate it to log4j 2.x then add the following dependencies:
Maven Build
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
Ivy Build
<dependencies>
<dependency org="org.apache.logging.log4j" name="log4j-jcl" rev="2.6.2" />
</dependencies>
Gradle Build
dependencies {
compile group: 'org.apache.logging.log4j', name: 'log4j-jcl', version: '2.6.2'
}
Reference: https://logging.apache.org/log4j/2.x/maven-artifacts.html
Properties-File to log to DB
For this example to work you'll need a JDBC driver compatible to the system the database is
https://riptutorial.com/ 720
running on. An opensource one that allows you to connect to DB2 databases on an IBM System i
can be found here: JT400
Even though this example is DB2 specific, it works for almost every other system if you exchange
the driver and adapt the JDBC URL.
You can use a filter to log only messages "lower" than e.g. ERROR level. But the filter is not
supported by PropertyConfigurator. So you must change to XML config to use it. See log4j-
Wiki about filters.
Or "Level range"
https://riptutorial.com/ 721
<param name="ConversionPattern" value="%m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMax" value="info"/>
<param name="LevelMin" value="info"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
</appender>
https://riptutorial.com/ 722
Chapter 113: Logging (java.util.logging)
Examples
Using the default logger
import java.util.logging.Level;
import java.util.logging.Logger;
// logging an exception
try {
// code might throw an exception
} catch (SomeException ex) {
// log a warning printing "Something went wrong"
// together with the exception message and stacktrace
LOG.log(Level.WARNING, "Something went wrong", ex);
}
// logging an object
LOG.log(Level.FINER, "String s: {0}", s);
Logging levels
Java Logging Api has 7 levels. The levels in descending order are:
https://riptutorial.com/ 723
The default level is INFO (but this depends on the system and used a virtual machine).
Note: There are also levels OFF (can be used to turn logging off) and ALL (the oposite of OFF).
import java.util.logging.Logger;
By default running this class will output only messages with level higher then CONFIG:
Let's look at a sample of logging which you can see in many programs:
https://riptutorial.com/ 724
}
The above example looks perfectly fine, but many programmers forgets that Java VM is stack
machine. This means that all method's parameters are calculated before executing the method.
This fact is crucial for logging in Java, especially for logging something in low levels like FINE, FINER
, FINEST which are disabled by default. Let's look at Java bytecode for the takeOrder() method.
Line 39 runs the actual logging. All of the previous work (loading variables, creating new objects,
concatenating Strings in format method) can be for nothing if logging level is set higher then FINE
(and by default it is). Such logging can be very inefficient, consuming unnecessary memory and
processor resources.
That's why you should ask if the level you want to use is enabled.
https://riptutorial.com/ 725
Since Java 8:
The Logger class has additional methods that take a Supplier<String> as parameter, which can
simply be provided by a lambda:
The Suppliers get()method - in this case the lambda - is only called when the corresponding level
is enabled and so the ifconstruction is not needed anymore.
https://riptutorial.com/ 726
Chapter 114: Maps
Introduction
The java.util.Map interface represents a mapping between keys and their values. A map cannot
contain duplicate keys; and each key can map to at most one value.
Since Map is an interface, then you need to instantiate a concrete implementation of that interface
in order to use it; there are several Map implementations, and mostly used are the java.util.HashMap
and java.util.TreeMap
Remarks
A map is an object which store keys with an associated value for each key. A key and its value are
sometimes called a key/value pair or an entry. Maps typically provide these features:
The most commonly used map implementation is HashMap. It works well with keys that are strings
or numbers.
Plain maps such as HashMap are unordered. Iterating through key/value pairs may return
individual entries in any order. If you need to iterate through map entries in a controlled fashion,
you should look at the following:
• Sorted maps such as TreeMap will iterate through keys in their natural order (or in an order
that you can specify, by providing a Comparator). For example, a sorted map using numbers
as keys would be expected to iterate through its entries in numeric order.
• LinkedHashMap permits iterating through entries in the same order that they were inserted
into the map, or by the order of most recently accessed.
Examples
Add an element
1. Addition
https://riptutorial.com/ 727
Output: First element.
2. Override
HashMapis used as an example. Other implementations that implement the Map interface may be
used as well.
Associates the specified value with the specified key in this map (optional operation). If
the map previously contained a mapping for the key, the old value is replaced by the
specified value.
String currentVal;
Map<Integer, String> map = new TreeMap<>();
currentVal = map.put(1, "First element.");
System.out.println(currentVal);// Will print null
currentVal = map.put(2, "Second element.");
System.out.println(currentVal); // Will print null yet again
currentVal = map.put(2, "This will replace 'Second element'");
System.out.println(currentVal); // will print Second element.
System.out.println(map.size()); // Will print 2 as key having
// value 2 was replaced.
map.putAll(map2);
System.out.println(map.size());
Output:
To add many items you can use an inner classes like this:
https://riptutorial.com/ 728
Keep in mind that creating an anonymous inner class is not always efficient and can lead to
memory leaks so when possible, use an initializer block instead:
static {
// Now no inner classes are created so we can avoid memory leaks
put(5, "high");
put(4, "low");
put(1, "too slow");
}
The example above makes the map static. It can also be used in a non-static context by removing
all occurences of static.
In addition to that most implementations support putAll, which can add all entries in one map to
another like this:
another.putAll(one);
1. Using getOrDefault
Returns the value mapped to the key, or if the key is not present, returns the default value
2. Using forEach
Allows to perform the operation specified in the 'action' on each Map Entry
3. Using replaceAll
https://riptutorial.com/ 729
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("john", 20);
map.put("paul", 30);
map.put("peter", 40);
map.replaceAll((key,value)->value+10); //{john=30, paul=40, peter=50}
4. Using putIfAbsent
Key-Value pair is added to the map, if the key is not present or mapped to null
5. Using remove
Removes the key only if its associated with the given value
6. Using replace
If the key is present then the value is replaced by new-value. If the key is not present, does
nothing.
7. Using computeIfAbsent
This method adds an entry in the Map. the key is specified in the function and the value is the
result of the application of the mapping function
8. Using computeIfPresent
https://riptutorial.com/ 730
This method adds an entry or modifies an existing entry in the Map. Does nothing if an entry with
that key is not present
9. Using compute
This method replaces the value of a key by the newly computed value
Adds the key-value pair to the map, if key is not present or value for the key is null Replaces the
value with the newly computed value, if the key is present Key is removed from the map , if new
value computed is null
//Adds the key-value pair to the map, if key is not present or value for the key is null
map.merge("kelly", 50 , (k,v)->map.get("john")+10); // {john=20, paul=30, peter=40,
kelly=50}
//Replaces the value with the newly computed value, if the key is present
map.merge("peter", 50 , (k,v)->map.get("john")+10); //{john=20, paul=30, peter=30,
kelly=50}
map.clear();
https://riptutorial.com/ 731
System.out.println(map.size()); // => 0
Maps provide methods which let you access the keys, values, or key-value pairs of the map as
collections. You can iterate through these collections. Given the following map for example:
Prints:
Darin Dimitrov
Jon Skeet
BalusC
keySet() provides the keys of the map as a Set. Set is used as the keys cannot contain duplicate
values. Iterating through the set yields each key in turn. HashMaps are not ordered, so in this
example the keys may be returned in any order.
Prints:
715567
927654
708826
values() returns the values of the map as a Collection. Iterating through the collection yields each
value in turn. Again, the values may be returned in any order.
Prints:
https://riptutorial.com/ 732
Darin Dimitrov = 715567
Jon Skeet = 927654
BalusC = 708826
entrySet() returns a collection of Map.Entry objects. Map.Entry gives access to the key and value
for each entry.
Use putAll to put every member of one map into another. Keys already present in the map will
have their corresponding values overwritten.
numbers.putAll(other_numbers)
"One" -> 1
"Two" -> 2
"Three" -> 4 //old value 3 was overwritten by new value 4
If you want to combine values instead of overwriting them, you can use Map.merge, added in Java 8,
which uses a user-provided BiFunction to merge values for duplicate keys. merge operates on
individual keys and values, so you'll need to use a loop or Map.forEach. Here we concatenate
strings for duplicate keys:
If you want to enforce the constraint there are no duplicate keys, you can use a merge function
that throws an AssertionError:
mapA.forEach((k, v) ->
mapB.merge(k, v, (v1, v2) ->
{throw new AssertionError("duplicate values for key: "+k);}));
https://riptutorial.com/ 733
map1.put("key1", 1);
map1.put("key2", 2);
map1.put("key3", 3);
if (num.containsKey("one")) {
System.out.println(num.get("one")); // => first
}
This section provides code and benchmarks for ten unique example implementations which iterate
over the entries of a Map<Integer, Integer> and generate the sum of the Integer values. All of the
examples have an algorithmic complexity of Θ(n), however, the benchmarks are still useful for
providing insight on which implementations are more efficient in a "real world" environment.
https://riptutorial.com/ 734
Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, Integer> pair = it.next();
sum += pair.getKey() + pair.getValue();
}
Iterator<Integer> it = map.keySet().iterator();
while (it.hasNext()) {
Integer key = it.next();
sum += key + map.get(key);
}
map.entrySet()
.stream()
.parallel()
.forEach(e -> sum += e.getKey() + e.getValue());
https://riptutorial.com/ 735
MapIterator<Integer, Integer> mit = iterableMap.mapIterator();
while (mit.hasNext()) {
sum += mit.next() + it.getValue();
}
https://riptutorial.com/ 736
4. A Comparison of Performance Variations Respective to Map Size
x: Size of Map
f(x): Benchmark Score (μs/op)
Before using your own object as key you must override hashCode() and equals() method of your
https://riptutorial.com/ 737
object.
class MyKey {
private String name;
MyKey(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof MyKey) {
return this.name.equals(((MyKey)obj).name);
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
}
hashCode will decide which hash bucket the key belongs to and equals will decide which object
inside that hash bucket.
Without these method, the reference of your object will be used for above comparison which will
not work unless you use the same object reference everytime.
Usage of HashMap
HashMap is an implementation of the Map interface that provides a Data Structure to store data in
Key-Value pairs.
1. Declaring HashMap
KeyType and ValueType must be valid types in Java, such as - String, Integer, Float or any
custom class like Employee, Student etc..
To put a value in the HashMap, we have to call put method on the HashMap object by passing the
Key and the Value as parameters.
myMap.put("key1", 1);
myMap.put("key2", 2);
If you call the put method with the Key that already exists in the Map, the method will override its
https://riptutorial.com/ 738
value and return the old value.
For getting the value from a HashMap you have to call the get method, by passing the Key as a
parameter.
If you pass a key that does not exists in the HashMap, this method will return null
myMap.containsKey(varKey);
myMap.containsValue(varValue);
The above methods will return a boolean value true or false if key, value exists in the Map or not.
Introduction
stores key/value pairs, where each key has an associated value. Given a particular key, the
Maps
map can look up the associated value very quickly.
Maps, also known as associate array, is an object that stores the data in form of keys and values. In
Java, maps are represented using Map interface which is not an extension of the collection
interface.
• Way 1 :-
• Way 2 :-
https://riptutorial.com/ 739
• Way 3 :-
• Way 4 :-
• Way 5 :-
//Java 8
final Map<String, String> map =
Arrays.stream(new String[][] {
{ "name", "A" },
{ "address", "Malviya-Nagar" },
{ "city", "jaipur" },
}).collect(Collectors.toMap(m -> m[0], m -> m[1]));
System.out.println(map);
• Way 6 :-
Any attemts to modify the map will result in throwing the UnsupportedOperationException.
https://riptutorial.com/ 740
singletonMap.replace("key", "value", "newValue"); //will throw
UnsupportedOperationException
//and etc
https://riptutorial.com/ 741
Chapter 115: Modules
Syntax
• requires java.xml;
• requires public java.xml; # exposes module to dependents for use
• exports com.example.foo; # dependents can use public types in this package
• exports com.example.foo.impl to com.example.bar; # restrict usage to a module
Remarks
The use of modules is encouraged but not required, this allows existing code to continue working
in Java 9. It also allows for a gradual transition to modular code.
Any non-modular code is put in an unnamed module when it is compiled. This is a special module
that is able to use types from all other modules but only from packages which have an exports
declaration.
Keywords, e.g. module etc..., are restricted in use within the module declaration but can be
continue to be used as identifiers elsewhere.
Examples
Defining a basic module
Modules are defined in a file named module-info.java, named a module descriptor. It should be
placed in the source-code root:
|-- module-info.java
|-- com
|-- example
|-- foo
|-- Foo.java
|-- bar
|-- Bar.java
module com.example {
requires java.httpclient;
exports com.example.foo;
}
The module name should be unique and it is recommended that you use the same Reverse-DNS
naming notation as used by packages to help ensure this.
https://riptutorial.com/ 742
The module java.base, which contains Java's basic classes, is implicitly visible to any module and
does not need to be included.
The requires declaration allows us to use other modules, in the example the module
java.httpclient is imported.
A module can also specify which packages it exports and therefore makes it visible to other
modules.
The package com.example.foo declared in the exports clause will be visible to other modules. Any
sub-packages of com.example.foo will not be exported, they need their own export declarations.
Conversely, com.example.bar which is not listed in exports clauses will not be visible to other
modules.
https://riptutorial.com/ 743
Chapter 116: Multi-Release JAR Files
Introduction
One of the features introduced in Java 9 is the multi-release Jar (MRJAR) which allows bundling
code targeting multiple Java releases within the same Jar file. The feature is specified in JEP 238.
Examples
Example of a multi-release Jar file's contents
By setting Multi-Release: true in the MANIFEST.MF file, the Jar file becomes a multi-release Jar
and the Java runtime (as long as it supports the MRJAR format) will pick the appropriate versions
of classes depending on the current major version.
jar root
- A.class
- B.class
- C.class
- D.class
- META-INF
- versions
- 9
- A.class
- B.class
- 10
- A.class
• On JDKs < 9, only the classes in the root entry are visible to the Java runtime.
• On a JDK 9, the classes A and B will be loaded from the directory root/META-INF/versions/9,
while C and D will be loaded from the base entry.
• On a JDK 10, class A would be loaded from the directory root/META-INF/versions/10.
The jar command can be used to create a multi-release Jar containing two versions of the same
class compiled for both Java 8 and Java 9, albeit with a warning telling that the classes are
identical:
The --release option tells jar to include everything that follows (the demo package inside the
9
sampleproject-9 directory) inside a versioned entry in the MRJAR, namely under root/META-
https://riptutorial.com/ 744
INF/versions/9. The result is the following contents:
jar root
- demo
- SampleClass.class
- META-INF
- versions
- 9
- demo
- SampleClass.class
Let us now create a class called Main that prints the URL of the SampleClass, and add it for the
Java 9 version:
package demo;
import java.net.URL;
If we compile this class and re-run the jar command, we get an error:
The reason is that the jar tool prevents adding public classes to versioned entries if they are not
added to the base entries as well. This is done so that the MRJAR exposes the same public API
for the different Java versions. Note that at runtime, this rule is not required. It may be only applied
by tools like jar. In this particular case, the purpose of Main is to run sample code, so we can
simply add a copy in the base entry. If the class were part of a newer implementation that we only
need for Java 9, it could be made non-public.
To add Main to the root entry, we first need to compile it to target a pre-Java 9 release. This can be
done using the new --release option of javac:
Running the Main class shows that the SampleClass gets loaded from the versioned directory:
https://riptutorial.com/ 745
C:\Users\manouti>java --class-path MR.jar demo.Main
jar:file:/C:/Users/manouti/MR.jar!/META-INF/versions/9/demo/SampleClass.class
jar root
- demo
- SampleClass.class
- META-INF
- versions
- 9
- demo
- SampleClass.class
package demo;
import java.net.URL;
If the class is compiled and added on the versioned entry for Java 9 in the MRJAR, running it
would result in:
https://riptutorial.com/ 746
Chapter 117: Nashorn JavaScript engine
Introduction
Nashorn is a JavaScript engine developed in Java by Oracle, and has been released with Java 8.
Nashorn allows embedding Javascript in Java applications via JSR-223 and allows to develop
standalone Javascript applications, and it provides better runtime performance and better
compliance with the ECMA normalized Javascript specification.
Syntax
• ScriptEngineManager // Provides a discovery and installation mechanism for ScriptEngine
classes; uses a SPI (Service Provider Interface)
• ScriptEngineManager.ScriptEngineManager() // Recommended constructor
• ScriptEngine // Provides the interface to the scripting language
• ScriptEngine ScriptEngineManager.getEngineByName(String shortName) // Factory method
for the given implementation
• Object ScriptEngine.eval(String script) // Executes the specified script
• Object ScriptEngine.eval(Reader reader) // Loads and then executes a script from the
specified source
• ScriptContext ScriptEngine.getContext() // Returns the default bindings, readers and writers
provider
• void ScriptContext.setWriter(Writer writer) // Sets the destination to send script output to
Remarks
Nashorn is a JavaScript engine written in Java and included in Java 8. Everything you need is
bundled in the javax.script package.
Note that the ScriptEngineManager provides a generic API allowing you to obtain script engines for
various scripting languages (i.e. not only Nashorn, not only JavaScript).
Examples
Set global variables
https://riptutorial.com/ 747
} catch (ScriptException ex) {
ex.printStackTrace();
}
// Outcome:
// 'Data defined in Java.' printed on standard output
Hello Nashorn
// Outcome:
// 'Hello Nashorn!' printed on standard output
// Required imports
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.io.FileReader;
import java.io.FileNotFoundException;
// Outcome:
// 'Script from file!' printed on standard output
demo.js:
https://riptutorial.com/ 748
// Obtain an instance of JavaScript engine
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// Outcome:
// Nothing printed on standard output, but
// stringWriter.toString() contains 'Redirected text!'
//String to be evaluated
String str = "3+2*4+5";
//Value after doing Arithmetic operation with operator precedence will be 16
//Outcome:
//Value of the string after arithmetic evaluation is printed on standard output.
//In this case '16.0' will be printed on standard output.
It's possible to pass Java objects to Nashorn engine to be processed in Java code. At the same
time, there are some JavaScript (and Nashorn) specific constructions, and it's not always clear
how they work with java objects.
Below there is a table which describes behaviour of native Java objects inside JavaScript
constructions.
Tested constructions:
https://riptutorial.com/ 749
2. for each statement Nashorn has a special kind of loop - for each - which can iterate over
different JS and Java object.
3. Getting object size. In JS objects have a property length, which returns size of an array or a
string.
Results:
Java string true Iterates over string characters Length of the string
Recommendatons:
• It's advisable to use if (some_string) to check if a string is not null and not empty
• for each can be safely used to iterate over any collection, and it doesn't raise exceptions if
the collection is not iterable, null or undefined
• Before getting length of an object it must be checked for null or undefined (the same is true
for any attempt of calling a method or getting a property of Java object)
import java.io.FileReader;
import java.io.IOException;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
try {
//evaluate a script
https://riptutorial.com/ 750
/* pet.js */
/*
var Pet = Java.type("InterfaceImplementationExample.Pet");
new Pet() {
eat: function() { print("eat"); }
}
*/
pet.eat();
} catch (ScriptException ex) {
ex.printStackTrace();
}
// Outcome:
// 'eat' printed on standard output
}
}
try {
// Set value in the global name space of the engine
engine.put("name","Nashorn");
// Execute an hardcoded script
engine.eval("var value='Hello '+name+'!';");
// Get value
String value=(String)engine.get("value");
System.out.println(value);
} catch (ScriptException ex) {
// This is the generic Exception subclass for the Scripting API
ex.printStackTrace();
}
// Outcome:
// 'Hello Nashorn!' printed on standard output
https://riptutorial.com/ 751
Chapter 118: Nested and Inner Classes
Introduction
Using Java, developers have the ability to define a class within another class. Such a class is
called a Nested Class. Nested Classes are called Inner Classes if they were declared as non-
static, if not, they are simply called Static Nested Classes. This page is to document and provide
details with examples on how to use Java Nested and Inner Classes.
Syntax
• public class OuterClass { public class InnerClass { } } // Inner classes can also be private
• public class OuterClass { public static class StaticNestedClass { } } // Static nested classes
can also be private
• public void method() { private class LocalClass { } } // Local classes are always private
• SomeClass anonymousClassInstance = new SomeClass() { }; // Anonymous inner classes
cannot be named, hence access is moot. If 'SomeClass()' is abstract, the body must
implement all abstract methods.
• SomeInterface anonymousClassInstance = new SomeInterface() { }; // The body must
implement all interface methods.
Remarks
A nested class is any class whose declaration occurs within the body of another class
or interface.
An inner class is a nested class that is not explicitly or implicitly declared static.
In practice programmers refer to a top level class that contains an inner class as the "outer class".
Also, there is a tendency to use "nested class" to refer to only to (explicitly or implicitly) static
nested classes.
Note that there is a close relationship between anonymous inner classes and the lambdas, but
lambdas are classes.
https://riptutorial.com/ 752
Semantic differences
• Top level classes are the "base case". They are visible to other parts of a program subject to
normal visibility rules based on access modifier semantics. If non-abstract, they can be
instantiated by any code that where the relevant constructors are visible based on the
access modifiers.
• Static nested classes follow the same access and instantiation rules as top level classes,
with two exceptions:
○ A nested class may be declared as private, which makes it inaccessible outside of its
enclosing top level class.
○ A nested class has access to the private members of the enclosing top-level class and
all of its tested class.
This makes static nested classes useful when you need to represent multiple "entity types"
within a tight abstraction boundary; e.g. when the nested classes are used to hide
"implementation details".
• Inner classes add the ability to access non-static variables declared in enclosing scopes:
The fact that an inner class instance can refer to variables in a enclosing class instance has
implications for instantiation. Specifically, an enclosing instance must be provided, either
implicitly or explicitly, when an instance of an inner class is created.
Examples
A Simple Stack Using a Nested Class
https://riptutorial.com/ 753
next = n;
}
}
And the use thereof, which (notably) does not at all acknowledge the existence of the nested
class.
//prints: 0, 1, 2, 3, 4,
for(int i = 0; i < 5; i++) {
System.out.print(s.pop() + ", ");
}
}
}
When creating a nested class, you face a choice of having that nested class static:
Or non-static:
At its core, static nested classes do not have a surrounding instance of the outer class, whereas
https://riptutorial.com/ 754
non-static nested classes do. This affects both where/when one is allowed to instantiate a nested
class, and what instances of those nested classes are allowed to access. Adding to the above
example:
private StaticNestedClass() {
innerField = aField; //Illegal, can't access aField from static context
aMethod(); //Illegal, can't call aMethod from static context
}
private NestedClass() {
innerField = aField; //Legal
aMethod(); //Legal
}
}
Thus, your decision of static vs non-static mainly depends on whether or not you need to be able
https://riptutorial.com/ 755
to directly access fields and methods of the outer class, though it also has consequences for when
and where you can construct the nested class.
As a rule of thumb, make your nested classes static unless you need to access fields and methods
of the outer class. Similar to making your fields private unless you need them public, this
decreases the visibility available to the nested class (by not allowing access to an outer instance),
reducing the likelihood of error.
A full explanation of Access Modifiers in Java can be found here. But how do they interact with
Inner classes?
public, as usual, gives unrestricted access to any scope able to access the type.
public int x = 5;
both protected and the default modifier (of nothing) behave as expected as well, the same as they
do for non-nested classes.
private,interestingly enough, does not restrict to the class it belongs to. Rather, it restricts to the
compilation unit - the .java file. This means that Outer classes have full access to Inner class fields
and methods, even if they are marked private.
private int x;
private void anInnerMethod() {}
}
https://riptutorial.com/ 756
return a;
}
}
The Inner Class itself can have a visibility other than public. By marking it private or another
restricted access modifier, other (external) classes will not be allowed to import and assign the
type. They can still get references to objects of that type, however.
An anonymous inner class is a form of inner class that is declared and instantiated with a single
statement. As a consequence, there is no name for the class that can be used elsewhere in the
program; i.e. it is anonymous.
Anonymous classes are typically used in situations where you need to be able to create a light-
weight class to be passed as a parameter. This is typically done with an interface. For example:
This anonymous class defines a Comparator<String> object (CASE_INSENSITIVE) that compares two
strings ignoring differences in case.
Other interfaces that are frequently implemented and instantiated using anonymous classes are
Runnable and Callable. For example:
https://riptutorial.com/ 757
// will run when started.
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello world");
}
});
t.start(); // Prints "Hello world"
Anonymous inner classes can also be based on classes. In this case, the anonymous class
implicitly extends the existing class. If the class being extended is abstract, then the anonymous
class must implement all abstract methods. It may also override non-abstract methods.
Constructors
An anonymous class cannot have an explicit constructor. Instead, an implicit constructor is defined
that uses super(...) to pass any parameters to a constructor in the class that is being extended.
For example:
The implicit constructor for our anonymous subclass of SomeClass will call a constructor of SomeClass
that matches the call signature SomeClass(int, String). If no constructor is available, you will get a
compilation error. Any exceptions that are thrown by the matched constructor are also thrown by
the implicit constructor.
Naturally, this does not work when extending an interface. When you create an anonymous class
from an interface, the classes superclass is java.lang.Object which only has a no-args constructor.
A class written within a method called method local inner class. In that case the scope of the
inner class is restricted within the method.
A method-local inner class can be instantiated only within the method where the inner class is
defined.
https://riptutorial.com/ 758
}
}
// Accessing the inner class
MethodLocalInnerClass inner = new MethodLocalInnerClass();
inner.print();
}
The reference to the outer class uses the class name and this
You can access fields and methods of the outer class directly.
But in case of name collision you can use the outer class reference.
// updating my counter
counter = OuterClass.this.counter;
}
}
}
https://riptutorial.com/ 759
Create instance of non-static inner class from outside
An inner class which is visible to any outside class can be created from this class as well.
The inner class depends on the outside class and requires a reference to an instance of it. To
create an instance of the inner class, the new operator only needs to be called on an instance of
the outer class.
class OuterClass {
class InnerClass {
}
}
class OutsideClass {
OuterClass.InnerClass createInner() {
return outer.new InnerClass();
}
}
https://riptutorial.com/ 760
Chapter 119: Networking
Syntax
• new Socket("localhost", 1234); //Connects to a server at address "localhost" and port 1234
• new SocketServer("localhost", 1234); //Creates a socket server that can listen for new
sockets at address localhost and port 1234
• socketServer.accept(); //Accepts a new Socket object which can be used to communicate
with the client
Examples
Basic Client and Server Communication using a Socket
while (true) {
// Wait for a client connection.
// Once a client connected, we get a "Socket" object
// that can be used to send and receive messages to/from the newly
// connected client
Socket clientSocket = serverSocket.accept();
https://riptutorial.com/ 761
Client: Connect to the server and send a message
// 127.0.0.1 is the address of the server (this is the localhost address; i.e.
// the address of our own machine)
// 1234 is the port that the server will be listening on
Socket socket = new Socket("127.0.0.1", 1234);
1. Just like files and other external resources, it's important we tell the OS when we're done
with them. When we're done with a socket, call socket.close() to properly close it.
2. Sockets handle I/O (Input/Output) operations that depend on a variety of external factors.
For example what if the other side suddenly disconnects? What if there are network error?
These things are beyond our control. This is why many socket operations might throw
exceptions, especially IOException.
A more complete code for the client would therefore be something like this:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
https://riptutorial.com/ 762
public static void main(String args[]) {
try (ServerSocket serverSocket = new ServerSocket(1234)) {
while (true) {
// Wait for a client connection.
Socket clientSocket = serverSocket.accept();
}
}
Client:
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
https://riptutorial.com/ 763
OutputStream outStream = socket.getOutputStream();
PrintWriter writer = new PrintWriter(
new OutputStreamWriter(outStream, StandardCharsets.UTF_8));
writer.println("Hello world!");
writer.flush();
} catch (IOException e) {
// Exception should be handled.
e.printStackTrace();
}
}
}
}
}
Intiating a KeyStore works the same, except replace any word Trust in a object name with Key.
Additionally, the KeyManager[] array must be passed to the the first argument of SSLContext.init.
That is SSLContext.init(keyMangers, trustMangers, null)
https://riptutorial.com/ 764
Socket example - reading a web page using a simple socket
import java.io.*;
import java.net.Socket;
public static void main(String[] args) throws IOException {//We don't handle Exceptions in
this example
//Open a socket to stackoverflow.com, port 80
Socket socket = new Socket("stackoverflow.com",80);
You should get a response that starts with HTTP/1.1 200 OK, which indicates a normal HTTP
response, followed by the rest of the HTTP header, followed by the raw web page in HTML form.
Note the readFully() method is important to prevent a premature EOF exception. The last line of
the web page may be missing a return, to signal the end of line, then readLine() will complain, so
one must read it by hand or use utility methods from Apache commons-io IOUtils
Client.java
https://riptutorial.com/ 765
import java.io.*;
import java.net.*;
In this case, we pass in the address of the server, via an argument (args[0]). The port we are
using is 4160.
Server.java
import java.io.*;
import java.net.*;
On the server-side, declare a DatagramSocket on the same port which we sent our message to
(4160) and wait for a response.
Multicasting
Multicasting is a type of Datagram Socket. Unlike regular Datagrams, Multicasting doesn't handle
each client individually instead it sends it out to one IP Address and all subscribed clients will get
the message.
https://riptutorial.com/ 766
Example code for a server side:
https://riptutorial.com/ 767
// join by ip
socket.joinGroup(InetAddress.getByName(ip));
}
Run the Client First: The Client must subscribe to the IP before it can start receiving any packets.
If you start the server and call the send() method, and then make a client (& call printMessage()).
Nothing will happen because the client connected after the message was sent.
Sometimes in a development or testing environment, the SSL certificate chain might not have
been fully established (yet).
https://riptutorial.com/ 768
To continue developing and testing, you can turn off SSL verification programmatically by installing
an "all-trusting" trust manager:
try {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
https://riptutorial.com/ 769
Notes
• Don't leave the catch blocks empty!
• In case of error, check if the remote file exists
• This is a blocking operation, can take long time with large files
https://riptutorial.com/ 770
Chapter 120: New File I/O
Syntax
• Paths.get(String first, String... more) // Creates a Path instance by its String elements
• Paths.get(URI uri) // Creates a Path instance by a URI
Examples
Creating paths
The Path class is used to programmaticaly represent a path in the file system (and can therefore
point to files as well as directories, even to non-existent ones)
Path p1 = Paths.get("/var/www");
Path p2 = Paths.get(URI.create("file:///home/testuser/File.txt"));
Path p3 = Paths.get("C:\\Users\\DentAr\\Documents\\HHGTDG.odt");
Path p4 = Paths.get("/home", "arthur", "files", "diary.tex");
Information about a path can be get using the methods of a Path object:
• getFileName() returns the file name (or, more specifically, the last element of the path
https://riptutorial.com/ 771
Path p1 = Paths.get("/var/www"); // p1.getParent().toString() returns "/var"
Manipulating paths
Path p5 = Paths.get("/home/");
Path p6 = Paths.get("arthur/files");
Path joined = p5.resolve(p6);
Path otherJoined = p5.resolve("ford/files");
joined.toString() == "/home/arthur/files"
otherJoined.toString() == "/home/ford/files"
Normalizing a path
Paths may contain the elements . (which points to the directory you're currently in) and ..(which
points to the parent directory).
When used in a path, . can be removed at any time without changing the path's destination, and
.. can be removed together with the preceding element.
With the Paths API, this is done using the .normalize() method:
Path p7 = Paths.get("/home/./arthur/../ford/files");
Path p8 = Paths.get("C:\\Users\\.\\..\\Program Files");
p7.normalize().toString() == "/home/ford/files"
p8.normalize().toString() == "C:\\Program Files"
To interact with the filesystem you use the methods of the class Files.
Checking existence
https://riptutorial.com/ 772
To check the existence of the file or directory a path points to, you use the following methods:
Files.exists(Path path)
and
Files.notExists(Path path)
• A file's or directory's existence is verified (exists returns true and notExists returns false in
this case)
• A file's or directory's nonexistence is verfied (exists returns false and notExists returns true)
• Neither the existence nor the nonexistence of a file or a directory can be verified (for
example due to access restrictions): Both exists and nonExists return false.
Path p1 = Paths.get("/var/www");
Path p2 = Paths.get("/home/testuser/File.txt");
Files.isDirectory(p1) == true
Files.isRegularFile(p1) == false
Files.isDirectory(p2) == false
Files.isRegularFile(p2) == true
Getting properties
This can be done using the following methods:
Files.isReadable(Path path)
Files.isWritable(Path path)
Files.isExecutable(Path path)
Files.isHidden(Path path)
Files.isSymbolicLink(Path path)
https://riptutorial.com/ 773
Files.probeContentType(Path path)
This tries to get the MIME type of a file. It returns a MIME type String, like this:
Reading files
Files can be read byte- and line-wise using the Files class.
Path p2 = Paths.get(URI.create("file:///home/testuser/File.txt"));
byte[] content = Files.readAllBytes(p2);
List<String> linesOfContent = Files.readAllLines(p2);
Writing files
Files can be written bite- and line-wise using the Files class
Path p2 = Paths.get("/home/testuser/File.txt");
List<String> lines = Arrays.asList(
new String[]{"First line", "Second line", "Third line"});
Files.write(p2, lines);
https://riptutorial.com/ 774
Chapter 121: NIO - Networking
Remarks
SelectionKey defines the different selectable operations and information between its Selector and
Channel. In particular, the attachment can be used to store connection-related information.
Handling OP_READ is pretty straight-forward. However, care should be taken when dealing with
OP_WRITE: most of the time, data can be written to sockets so the event will keep firing. Make sure
to register OP_WRITE only before you want to write data (see that answer).
Also, OP_CONNECT should be cancelled once the Channel has connected (because, well, it is
connected. See this and that answers on SO). Hence the OP_CONNECT removal after finishConnect()
succeeded.
Examples
Using Selector to wait for events (example with OP_CONNECT)
NIO appeared in Java 1.4 and introduced the concept of "Channels", which are supposed to be
faster than regular I/O. Network-wise, the SelectableChannel is the most interesting as it allows to
monitor different states of the Channel. It works in a similar manner as the C select() system call:
we get woken-up when certain types of events occur:
It allows for separation between detecting socket I/O (something can be read/written/...) and
performing the I/O (read/write/...). Especially, all I/O detection can be done in a single thread for
multiple sockets (clients), while performing I/O can be handled in a thread pool or anywhere else.
That allows for an application to scale easily to the number of connected clients.
1. Create a Selector
2. Create a SocketChannel
3. Register the SocketChannelto the Selector
4. Loop with the Selector to detect events
// Register the Channel to the Selector for wake-up on CONNECT event and use some description
https://riptutorial.com/ 775
as an attachement
sc.register(sel, SelectionKey.OP_CONNECT, "Connection to google.com"); // Returns a
SelectionKey: the association between the SocketChannel and the Selector
System.out.println("Initiating connection");
if (sc.connect(new InetSocketAddress("www.google.com", 80)))
System.out.println("Connected"); // Connected right-away: nothing else to do
else {
boolean exit = false;
while (!exit) {
if (sel.select(100) == 0) // Did something happen on some registered Channels during
the last 100ms?
continue; // No, wait some more
// Something happened...
Set<SelectionKey> keys = sel.selectedKeys(); // List of SelectionKeys on which some
registered operation was triggered
for (SelectionKey k : keys) {
System.out.println("Checking "+k.attachment());
if (k.isConnectable()) { // CONNECT event
System.out.print("Connected through select() on "+k.channel()+" -> ");
if (sc.finishConnect()) { // Finish connection process
System.out.println("done!");
k.interestOps(k.interestOps() & ~SelectionKey.OP_CONNECT); // We are
already connected: remove interest in CONNECT event
exit = true;
} else
System.out.println("unfinished...");
}
// TODO: else if (k.isReadable()) { ...
}
keys.clear(); // Have to clear the selected keys set once processed!
}
}
System.out.print("Disconnecting ... ");
sc.shutdownOutput(); // Initiate graceful disconnection
// TODO: emtpy receive buffer
sc.close();
System.out.println("done");
Initiating connection
Checking Connection to google.com
Connected through 'select()' on java.nio.channels.SocketChannel[connection-pending
remote=www.google.com/216.58.208.228:80] -> done!
Disconnecting ... done
https://riptutorial.com/ 776
Chapter 122: Non-Access Modifiers
Introduction
Non-Access Modifiers do not change the accessibility of variables and methods, but they do
provide them special properties.
Examples
final
final in Java can refer to variables, methods and classes. There are three simple rules:
Usages
Some developer consider it good practice to mark a variable final when you can. If you have a
variable that should not be changed, you should mark it final.
An important use of final keyword if for method parameters. If you want to emphasize that a
method doesn't change its input parameters, mark the properties as final.
This emphasizes that the sumup method is not going to change the ints.
If your anonymous inner class wants to access a variable, the variable should be marked final
Java SE 8
https://riptutorial.com/ 777
Effectively final variables are an exception. These are local variables that are written to only once
and could therefore be made final. Effectively final variables can be accessed from anonymus
classes too.
Even though the code below is completely legal when final variable foo is not static, in case of
static it will not compile:
class TestFinal {
private final static List foo;
public Test() {
foo = new ArrayList();
}
}
The reason is, let's repeat again, final variable cannot be reassigned. Since foo is static, it is
shared among all instances of class TestFinal. When a new instance of a class TestFinal is
created, its constructor is invoked and therefore foo gets reassigned which compiler does not
allow. A correct way to initialize variable foo in this case is either:
class TestFinal {
private static final List foo = new ArrayList();
//..
}
class TestFinal {
private static final List foo;
static {
foo = new ArrayList();
}
//..
}
final methods are useful when base class implements some important functionality that derived
class is not supposed to change it. They are also faster than non-final methods, because there is
no concept of virtual table involved.
All wrapper classes in Java are final, such as Integer, Long etc. Creators of these classes didn't
want that anyone can e.g. extend Integer into his own class and change the basic behavior of
Integer class. One of the requirements to make a class immutable is that subclasses may not
override methods. The simplest way to do this is to declare the class as final.
volatile
The volatile modifier is used in multi threaded programming. If you declare a field as volatile it is
a signal to threads that they must read the most recent value, not a locally cached one.
Furthermore, volatile reads and writes are guaranteed to be atomic (access to a non-volatile
https://riptutorial.com/ 778
long or double is not atomic), thus avoiding certain read/write errors between multiple threads.
static
The static keyword is used on a class, method, or field to make them work independently of any
instance of the class.
• Static fields are common to all instances of a class. They do not need an instance to access
them.
• Static methods can be run without an instance of the class they are in. However, they can
only access static fields of that class.
• Static classes can be declared inside of other classes. They do not need an instance of the
class they are in to be instantiated.
static {
// This block of code is run when the class first loads
staticVariable = 11;
}
int nonStaticVariable = 5;
void add() {
// We can access both static and non-static variables from non-static methods
nonStaticVariable += staticVariable;
}
https://riptutorial.com/ 779
void doSomething() {
// We can access number and staticVariable, but not nonStaticVariable
number += staticVariable;
}
int getNumber() {
return number;
}
}
}
System.out.println(object1.staticVariable); // 11
System.out.println(TestStatic.staticVariable); // 11
TestStatic.doSomething();
System.out.println(object1.staticVariable); // 10
System.out.println(object2.staticVariable); // 10
System.out.println(TestStatic.staticVariable); // 10
object1.add();
System.out.println(object1.nonStaticVariable); // 15
System.out.println(object2.nonStaticVariable); // 10
System.out.println(object3.getNumber()); // 100
System.out.println(object4.getNumber()); // 200
object3.doSomething();
System.out.println(object3.getNumber()); // 110
System.out.println(object4.getNumber()); // 200
abstract
Abstraction is a process of hiding the implementation details and showing only functionality to the
user. An abstract class can never be instantiated. If a class is declared as abstract then the sole
purpose is for the class to be extended.
https://riptutorial.com/ 780
{
System.out.println("Start Something Special");
}
}
synchronized
Synchronized modifier is used to control the access of a particular method or a block by multiple
threads. Only one thread can enter into a method or a block which is declared as synchronized.
synchronized keyword works on intrinsic lock of an object, in case of a synchronized method
current objects lock and static method uses class object. Any thread trying to execute a
synchronized block must acquire the object lock first.
class Shared
{
int i;
void SharedMethod2()
{
synchronized (this)
{
System.out.println("Thais access to currect object is synchronize "+this);
}
}
}
https://riptutorial.com/ 781
Thread t2 = new Thread("Thread - 2")
{
@Override
public void run()
{
s1.SharedMethod();
}
};
t1.start();
t2.start();
}
}
transient
A variable which is declared as transient will not be serialized during object serialization.
strictfp
Java SE 1.2
strictfp modifier is used for floating-point calculations. This modifier makes floating point variable
more consistent across multiple platforms and ensure all the floating point calculations are done
according to IEEE 754 standards to avoid errors of calculation (round-off errors), overflows and
underflows on both 32bit and 64bit architecture. This cannot be applied on abstract methods,
variables or constructors.
class A{
strictfp void m(){}
}
https://riptutorial.com/ 782
Chapter 123: NumberFormat
Examples
NumberFormat
Different countries have different number formats and considering this we can have different
formats using Locale of java. Using locale can help in formatting
1. Format Number
numberFormat.format(10000000.99);
2. Format Currency
3. Format Percentage
numberFormat.setMinimumIntegerDigits(int digits)
numberFormat.setMaximumIntegerDigits(int digits)
numberFormat.setMinimumFractionDigits(int digits)
numberFormat.setMaximumFractionDigits(int digits)
https://riptutorial.com/ 783
Chapter 124: Object Class Methods and
Constructor
Introduction
This documentation page is for showing details with example about java class constructors and
about Object Class Methods which are automatically inherited from the superclass Object of any
newly created class.
Syntax
• public final native Class<?> getClass()
• public final native void notify()
• public final native void notifyAll()
• public final native void wait(long timeout) throws InterruptedException
• public final void wait() throws InterruptedException
• public final void wait(long timeout, int nanos) throws InterruptedException
• public native int hashCode()
• public boolean equals(Object obj)
• public String toString()
• protected native Object clone() throws CloneNotSupportedException
• protected void finalize() throws Throwable
Examples
toString() method
The toString() method is used to create a String representation of an object by using the object´s
content. This method should be overridden when writing your class. toString() is called implicitly
when an object is concatenated to a string as in "hello " + anObject.
@Override
public String toString() {
return firstName + " " + lastName;
}
https://riptutorial.com/ 784
public static void main(String[] args) {
User user = new User("John", "Doe");
System.out.println(user.toString()); // Prints "John Doe"
}
}
Here toString() from Object class is overridden in the User class to provide meaningful data
regarding the object when printing it.
When using println(), the object's toString() method is implicitly called. Therefore, these
statements do the same thing:
If the toString() is not overridden in the above mentioned User class, System.out.println(user) may
return User@659e0bfd or a similar String with almost no useful information except the class name.
This will be because the call will use the toString() implementation of the base Java Object class
which does not know anything about the User class's structure or business rules. If you want to
change this functionality in your class, simply override the method.
equals() method
TL;DR
== tests for reference equality (whether they are the same object)
.equals() tests for value equality (whether they are logically "equal")
equals() is a method used to compare two objects for equality. The default implementation of the
equals() method in the Object class returns true if and only if both references are pointing to the
same instance. It therefore behaves the same as comparison by ==.
https://riptutorial.com/ 785
Even though foo1 and foo2 are created with the same fields, they are pointing to two different
objects in memory. The default equals() implementation therefore evaluates to false.
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
@Override
public int hashCode() {
int hash = 1;
hash = 31 * hash + this.field1;
hash = 31 * hash + this.field2;
hash = 31 * hash + (field3 == null ? 0 : field3.hashCode());
return hash;
}
Here the overridden equals() method decides that the objects are equal if their fields are the same.
Notice that the hashCode() method was also overwritten. The contract for that method states that
when two objects are equal, their hash values must also be the same. That's why one must almost
always override hashCode() and equals() together.
Pay special attention to the argument type of the equals method. It is Object obj, not Foo obj. If you
put the latter in your method, that is not an override of the equals method.
When writing your own class, you will have to write similar logic when overriding equals() and
hashCode()
https://riptutorial.com/ 786
. Most IDEs can automatically generate this for you.
An example of an equals() implementation can be found in the String class, which is part of the
core Java API. Rather than comparing pointers, the String class compares the content of the
String.
Java SE 7
Java 1.7 introduced the java.util.Objects class which provides a convenience method, equals,
that compares two potentially null references, so it can be used to simplify implementations of the
equals method.
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Class Comparison
Since the equals method can run against any object, one of the first things the method often does
(after checking for null) is to check if the class of the object being compared matches the current
class.
@Override
public boolean equals(Object obj) {
//...check for null
if (getClass() != obj.getClass()) {
return false;
}
//...compare fields
}
This is typically done as above by comparing the class objects. However, that can fail in a few
special cases which may not be obvious. For example, some frameworks generate dynamic
proxies of classes and these dynamic proxies are actually a different class. Here is an example
using JPA.
https://riptutorial.com/ 787
One mechanism to work around that limitation is to compare classes using instanceof
@Override
public final boolean equals(Object obj) {
if (!(obj instanceof Foo)) {
return false;
}
//...compare fields
}
However, there are a few pitfalls that must be avoided when using instanceof. Since Foo could
potentially have other subclasses and those subclasses might override equals() you could get into
a case where a Foo is equal to a FooSubclass but the FooSubclass is not equal to Foo.
This violates the properties of symmetry and transitivity and thus is an invalid implementation of
the equals() method. As a result, when using instanceof, a good practice is to make the equals()
method final (as in the above example). This will ensure that no subclass overrides equals() and
violates key assumptions.
hashCode() method
When a Java class overrides the equals method, it should override the hashCode method as well. As
defined in the method's contract:
• Whenever it is invoked on the same object more than once during an execution
of a Java application, the hashCode method must consistently return the same
integer, provided no information used in equals comparisons on the object is
modified. This integer need not remain consistent from one execution of an
application to another execution of the same application.
• If two objects are equal according to the equals(Object) method, then calling the
hashCode method on each of the two objects must produce the same integer
result.
• It is not required that if two objects are unequal according to the equals(Object)
method, then calling the hashCode method on each of the two objects must
produce distinct integer results. However, the programmer should be aware that
producing distinct integer results for unequal objects may improve the
performance of hash tables.
Hash codes are used in hash implementations such as HashMap, HashTable, and HashSet. The result
of the hashCode function determines the bucket in which an object will be put. These hash
implementations are more efficient if the provided hashCode implementation is good. An important
property of good hashCode implementation is that the distribution of the hashCode values is uniform.
In other words, there is a small probability that numerous instances will be stored in the same
bucket.
https://riptutorial.com/ 788
An algorithm for computing a hash code value may be similar to the following:
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
@Override
public int hashCode() {
int hash = 1;
hash = 31 * hash + field1;
hash = 31 * hash + field2;
hash = 31 * hash + (field3 == null ? 0 : field3.hashCode());
return hash;
}
}
In Java 1.2 and above, instead of developing an algorithm to compute a hash code, one can be
generated using java.util.Arrays#hashCode by supplying an Object or primitives array containing
the field values:
@Override
public int hashCode() {
return Arrays.hashCode(new Object[] {field1, field2, field3});
}
Java SE 7
Java 1.7 introduced the java.util.Objects class which provides a convenience method,
hash(Object... objects), that computes a hash code based on the values of the objects supplied to
it. This method works just like java.util.Arrays#hashCode.
https://riptutorial.com/ 789
@Override
public int hashCode() {
return Objects.hash(field1, field2, field3);
}
Note: this approach is inefficient, and produces garbage objects each time your custom hashCode()
method is called:
• A temporary Object[] is created. (In the Objects.hash() version, the array is created by the
"varargs" mechanism.)
• If any of the fields are primitive types, they must be boxed and that may create more
temporary objects.
• The array must be populated.
• The array must iterated by the Arrays.hashCode or Objects.hash method.
• The calls to Object.hashCode() that Arrays.hashCode or Objects.hash has to make (probably)
cannot be inlined.
// Other methods
@Override
public boolean equals(Object obj) {
// ...
}
@Override
public int hashCode() {
int h = hash;
if (h == 0) {
h = Arrays.hashCode(array);
hash = h;
}
return h;
}
}
This approach trades off the cost of (repeatedly) calculating the hash code against the overhead of
an extra field to cache the hash code. Whether this pays off as a performance optimization will
depend on how often a given object is hashed (looked up) and other factors.
You will also notice that if the true hashcode of an ImmutableArray happens to be zero (one chance
https://riptutorial.com/ 790
in 232), the cache is ineffective.
Finally, this approach is much harder to implement correctly if the object we are hashing is
mutable. However, there are bigger concerns if hash codes change; see the contract above.
wait() and notify() work in tandem – when one thread calls wait() on an object, that thread will
block until another thread calls notify() or notifyAll() on that same object.
package com.example.examples.object;
import java.util.concurrent.atomic.AtomicBoolean;
while (!aHasFinishedWaiting.get()) {
https://riptutorial.com/ 791
synchronized (obj) {
// notify ONE thread which has called obj.wait()
obj.notify();
}
}
}
};
threadA.start();
threadB.start();
threadA.join();
threadB.join();
System.out.println("Finished!");
}
}
getClass() method
The getClass() method can be used to find the runtime class type of an object. See the example
below:
https://riptutorial.com/ 792
}
}
The getClass() method will return the most specific class type, which is why when getClass() is
called on anotherSpecificUser, the return value is class SpecificUser because that is lower down
the inheritance tree than User.
The actual static type returned by a call to getClass is Class<? extends T> where T is the static type
of the object on which getClass is called.
clone() method
The clone() method is used to create and return a copy of an object. This method arguable should
be avoided as it is problematic and a copy constructor or some other approach for copying should
be used in favour of clone().
For the method to be used all classes calling the method must implement the Cloneable interface.
The Cloneable interface itself is just a tag interface used to change the behaviour of the native
clone() method which checks if the calling objects class implements Cloneable. If the caller does
not implement this interface a CloneNotSupportedException will be thrown.
The Object class itself does not implement this interface so a CloneNotSupportedException will be
thrown if the calling object is of class Object.
https://riptutorial.com/ 793
For a clone to be correct it should be independent of the object it is being cloned from, therefore it
may be necessary to modify the object before it gets returned. This means to essentially create a
"deep copy" by also copying any of the mutable objects that make up the internal structure of the
object being cloned. If this is not implemented correctly the cloned object will not be independent
and have the same references to the mutable objects as the object that it was cloned from. This
would result in inconsistent behaviour as any changes to those in one would affect the other.
} catch (CloneNotSupportedException e) {
// in case any of the cloned mutable fields do not implement Cloneable
throw new AssertionError(e);
}
}
}
finalize() method
This is a protected and non-static method of the Object class. This method is used to perform
some final operations or clean up operations on an object before it gets removed from the
memory.
According to the doc, this method gets called by the garbage collector on an object
when garbage collection determines that there are no more references to the object.
But there are no guarantees that finalize() method would gets called if the object is still reachable
or no Garbage Collectors run when the object become eligible. That's why it's better not rely on
this method.
In Java core libraries some usage examples could be found, for instance in FileInputStream.java:
https://riptutorial.com/ 794
protected void finalize() throws IOException {
if ((fd != null) && (fd != FileDescriptor.in)) {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
In this case it's the last chance to close the resource if that resource has not been closed before.
Generally it's considered bad practice to use finalize() method in applications of any kind and
should be avoided.
Finalizers are not meant for freeing resources (e.g., closing files). The garbage collector gets
called when (if!) the system runs low on heap space. You can't rely on it to be called when the
system is running low on file handles or, for any other reason.
The intended use-case for finalizers is for an object that is about to be reclaimed to notify some
other object about its impending doom. A better mechanism now exists for that purpose---the
java.lang.ref.WeakReference<T> class. If you think you need write a finalize() method, then you
should look into whether you can solve the same problem using WeakReference instead. If that won't
solve your problem, then you may need to re-think your design on a deeper level.
For further reading here is an Item about finalize() method from "Effective Java" book by Joshua
Bloch.
Object constructor
All constructors in Java must make a call to the Object constructor. This is done with the call
super(). This has to be the first line in a constructor. The reason for this is so that the object can
actually be created on the heap before any additional initialization is performed.
If you do not specify the call to super() in a constructor the compiler will put it in for you.
public MyClass() {
super();
}
}
https://riptutorial.com/ 795
public MyClass() {
// empty
}
}
It is possible to call other constructors as the first instruction of a constructor. As both the explicit
call to a super constructor and the call to another constructor have to be both first instructions,
they are mutually exclusive.
doSomethingWith(size);
this(initialValues.size());
addInitialValues(initialValues);
}
}
Calling new MyClass(Arrays.asList("a", "b", "c")) will call the second constructor with the List-
argument, which will in turn delegate to the first constructor (which will delegate implicitly to
super()) and then call addInitialValues(int size) with the second size of the list. This is used to
reduce code duplication where multiple constructors need to do the same work.
Given the example above, one can either call new MyClass("argument") or new MyClass("argument",
0). In other words, much like method overloading, you just call the constructor with the parameters
that are necessary for your chosen constructor.
Nothing more than would happen in a sub-class that has a default empty constructor (minus the
call to super()).
The default empty constructor can be explicitly defined but if not the compiler will put it in for you
as long as no other constructors are already defined.
https://riptutorial.com/ 796
The actual creation of objects is down to the JVM. Every constructor in Java appears as a special
method named <init> which is responsible for instance initializing. This <init> method is supplied
by the compiler and because <init> is not a valid identifier in Java, it cannot be used directly in the
language.
The JVM will invoke the <init> method using the invokespecial instruction and can only be invoked
on uninitialized class instances.
For more information take a look at the JVM specification and the Java Language Specification:
https://riptutorial.com/ 797
Chapter 125: Object Cloning
Remarks
Cloning can be tricky, especially when the object's fields hold other objects. There are situations
where you want to perform a deep copy, instead of only copying the field values (i.e. references to
the other objects).
The bottom line is clone is broken, and you should think twice before implementing the Cloneable
interface and overriding the clone method. The clone method is declared in the Object class and
not in the Cloneable interface, so Cloneable fails to function as an interface because it lacks a public
clone method. The result is the contract for using clone is thinly documented and weakly enforced.
For example, a class that overrides clone sometimes relies on all its parent classes also overriding
clone. They are not enforced to do so, and if they do not your code may throw exceptions.
A much better solution for providing cloning functionality is to provide a copy constructor or copy
factory. Refer to Joshua Bloch's Effective Java Item 11: Override clone judiciously.
Examples
Cloning using a copy constructor
// copy constructor
// copies the fields of other into the new object
public Sheep(Sheep other) {
this.name = other.name;
this.weight = other.weight;
}
// create a sheep
Sheep sheep = new Sheep("Dolly", 20);
// clone the sheep
Sheep dolly = new Sheep(sheep); // dolly.name is "Dolly" and dolly.weight is 20
https://riptutorial.com/ 798
Cloning an object by implementing the Cloneable interface.
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
// create a sheep
Sheep sheep = new Sheep("Dolly", 20);
// clone the sheep
Sheep dolly = (Sheep) sheep.clone(); // dolly.name is "Dolly" and dolly.weight is 20
Default behavior when cloning an object is to perform a shallow copy of the object's fields. In that
case, both the original object and the cloned object, hold references to the same objects.
import java.util.List;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
https://riptutorial.com/ 799
}
import java.util.Arrays;
import java.util.List;
// create a sheep
Sheep sheep = new Sheep("Dolly", 20);
// create children
Sheep child1 = new Sheep("Child1", 4);
Sheep child2 = new Sheep("Child2", 5);
sheep.setChildren(Arrays.asList(child1, child2));
To copy nested objects, a deep copy must be performed, as shown in this example.
import java.util.ArrayList;
import java.util.List;
@Override
public Object clone() throws CloneNotSupportedException {
Sheep clone = (Sheep) super.clone();
if (children != null) {
// make a deep copy of the children
List<Sheep> cloneChildren = new ArrayList<>(children.size());
for (Sheep child : children) {
cloneChildren.add((Sheep) child.clone());
}
clone.setChildren(cloneChildren);
}
return clone;
}
https://riptutorial.com/ 800
public List<Sheep> getChildren() {
return children;
}
import java.util.Arrays;
import java.util.List;
// create a sheep
Sheep sheep = new Sheep("Dolly", 20);
// create children
Sheep child1 = new Sheep("Child1", 4);
Sheep child2 = new Sheep("Child2", 5);
sheep.setChildren(Arrays.asList(child1, child2));
https://riptutorial.com/ 801
Chapter 126: Object References
Remarks
This should help you understand a "Null Pointer Exception" -- one gets one of those because an
object reference is null, but the program code expects the program to use something in that object
reference. However, that deserves its own topic...
Examples
Object References as method parameters
This topic explains the concept of an object reference; it is targeted at people who are new to
programming in Java. You should already be familiar with some terms and meanings: class
definition, main method, object instance, and the calling of methods "on" an object, and passing
parameters to methods.
int i = 5;
setPersonName(person, i);
To be fully competent in Java programming, you should be able to explain this example to
someone else off the top of your head. Its concepts are fundamental to understanding how Java
works.
As you can see, we have a main that instantiates an object to the variable person, and calls a
method to set the name field in that object to "Bob". Then it calls another method, and passes person
as one of two parameters; the other parameter is an integer variable, set to 5.
The method called sets the name value on the passed object to "Linda', and sets the integer
https://riptutorial.com/ 802
variable passed to 99, then returns.
Linda 5
So why does the change made to person take effect in main, but the change made to the integer
does not?
When the call is made, the main method passes an object reference for person to the setPersonName
method; any change that setAnotherName makes to that object is part of that object, and so those
changes are still part of that object when the method returns.
Another way of saying the same thing: person points to an object (stored on the heap, if you're
interested). Any change the method makes to that object are made "on that object", and are not
affected by whether the method making the change is still active or has returned. When the
method returns, any changes made to the object are still stored on that object.
Contrast this with the integer that is passed. Since this is a primitive int (and not an Integer object
instance), it is passed "by value", meaning its value is provided to the method, not a pointer to the
original integer passed in. The method can change it for the method's own purposes, but that does
not affect the variable used when the method call is made.
In Java, all primitives are passed by value. Objects are passed by reference, which means that a
pointer to the object is passed as the parameter to any methods that take them.
One less-obvious thing this means: it is not possible for a called method to create a new object
and return it as one of the parameters. The only way for a method to return an object that is
created, directly or indirectly, by the method call, is as a return value from the method. Let's first
see how that would not work, and then how it would work.
And, back in the main, below the call to setAnotherName, let's put a call to this method and another
println call:
getAnotherObjectNot(person);
System.out.println(person.getName());
Linda 5
Linda
https://riptutorial.com/ 803
What happened to the object that had George? Well, the parameter that was passed in was a
pointer to Linda; when the getAnotherObjectNot method created a new object, it replaced the
reference to the Linda object with a reference to the George object. The Linda object still exists
(on the heap), the main method can still access it, but the getAnotherObjectNot method wouldn't be
able to do anything with it after that, because it has no reference to it. It would appear that the
writer of the code intended for the method to create a new object and pass it back, but if so, it
didn't work.
If that is what the writer wanted to do, he would need to return the newly created object from the
method, something like this:
Person mary;
mary = getAnotherObject();
System.out.println(mary.getName());
Linda 5
Linda
Mary
int i = 5;
setPersonName(person, i);
System.out.println(person.getName() + " " + i);
getAnotherObjectNot(person);
System.out.println(person.getName());
Person person;
person = getAnotherObject();
System.out.println(person.getName());
}
https://riptutorial.com/ 804
person.setName("Linda");
num = 99;
}
https://riptutorial.com/ 805
Chapter 127: Operators
Introduction
Operators in Java programming language are special symbols that perform specific operations on
one, two, or three operands, and then return a result.
Remarks
An operator is a symbol (or symbols) that tells a Java program to perform an operation on one,
two or three operands. An operator and its operands form an expression (see the Expressions
topic). The operands of an operator are themselves expressions.
This topic describes the 40 or so distinct operators defined by Java. The separate Expressions
topic explains:
• how operators, operands and other things are combined into expressions,
• how the expressions are evaluated, and
• how expression typing, conversions, and expression evaluation work.
Examples
The String Concatenation Operator (+)
In the simple case, the Concatenation operator joins two strings to give a third string. For example:
When one of the two operands is not a string, it is converted to a String as follows:
• An operand whose type is a reference type is converted by calling the operand's toString()
method. If the operand is null, or if the toString() method returns null, then the string literal
"null" is used instead.
For example:
https://riptutorial.com/ 806
int one = 1;
String s3 = "One is " + one; // s3 contains "One is 1"
String s4 = null + " is null"; // s4 contains "null is null"
String s5 = "{1} is " + new int[]{1}; // s5 contains something like
// "{} is [I@xxxxxxxx"
The explanation for the s5 example is that the toString() method on array types is inherited from
java.lang.Object, and the behavior is to produce a string that consists of the type name, and the
object's identity hashcode.
The Concatenation operator is specified to create a new String object, except in the case where
the expression is a Constant Expression. In the latter case, the expression is evaluated at compile
type, and its runtime value is equivalent to a string literal. This means that there is no runtime
overhead in splitting a long string literal like this:
In the method above, each iteration of the loop will create a new String that is one character
longer than the previous iteration. Each concatenation copies all of the characters in the operand
strings to form the new String. Thus, stars(N) will:
• create N new String objects, and throw away all but the last one,
• copy N * (N + 1) / 2 characters, and
• generate O(N^2) bytes of garbage.
This is very expensive for large N. Indeed, any code that concatenates strings in a loop is liable to
have this problem. A better way to write this would be as follows:
https://riptutorial.com/ 807
Ideally, you should set the capacity of the StringBuilder, but if this is not practical, the class will
automatically grow the backing array that the builder uses to hold characters. (Note: the
implementation expands the backing array exponentially. This strategy keeps that amount of
character copying to a O(N) rather than O(N^2).)
Some people apply this pattern to all string concatenations. However, this is unnecessary because
the JLS allows a Java compiler to optimize string concatenations within a single expression. For
example:
String s1 = ...;
String s2 = ...;
String test = "Hello " + s1 + ". Welcome to " + s2 + "\n";
(The JIT compiler may optimize that further if it can deduce that s1 or s2 cannot be null.) But note
that this optimization is only permitted within a single expression.
The Java language provides 7 operators that perform arithmetic on integer and floating point
values.
below)
• There are two - operators:
The binary subtraction operator subtracts one number from another one.
○
The unary minus operator is equivalent to subtracting its operand from zero.
○
https://riptutorial.com/ 808
"Modulus" and "remainder" are not the same thing.
The result type is determined base on the types of the operand or operands, as follows:
• If either of the operands is a double or Double, then the result type is double.
• Otherwise, if either of the operands is a float or Float, then the result type is float.
• Otherwise, if either of the operands is a long or Long, then the result type is long.
• Otherwise, the result type is int. This covers byte, short and char operands as well as `int.
The result type of the operation determines how the arithmetic operation is performed, and how
the operands are handled
• If the result type is double, the operands are promoted to double, and the operation is
performed using 64-bit (double precision binary) IEE 754 floating point arithmetic.
• If the result type is float, the operands are promoted to float, and the operation is performed
using 32-bit (single precision binary) IEE 754 floating point arithmetic.
• If the result type is long, the operands are promoted to long, and the operation is performed
using 64-bit signed twos-complement binary integer arithmetic.
• If the result type is int, the operands are promoted to int, and the operation is performed
using 32-bit signed twos-complement binary integer arithmetic.
• If the operand type is a wrapper type, the operand value is unboxed to a value of the
corresponding primitive type.
• If necessary, the primitive type is promoted to the required type:
○ Promotion of integers to int or long is loss-less.
○ Promotion of float to double is loss-less.
○ Promotion of an integer to a floating point value can lead to loss of precision. The
conversion is performed using IEE 768 "round-to-nearest" semantics.
Java integer division rounds towards zero. The JLS Section 15.17.2 specifies the behavior of Java
integer division as follows:
The quotient produced for operands n and d is an integer value q whose magnitude is
as large as possible while satisfying |d ⋅ q| ≤ |n|. Moreover, q is positive when |n| ≥
|d| and n and d have the same sign, but q is negative when |n| ≥ |d| and n and d have
https://riptutorial.com/ 809
opposite signs.
• If the n is MIN_VALUE, and the divisor is -1, then integer overflow occurs and the result is
MIN_VALUE. No exception is thrown in this case.
• If d is 0, then `ArithmeticException is thrown.
Java floating point division has more edge cases to consider. However the basic idea is that the
result q is the value that is closest to satisfying d . q = n.
Floating point division will never result in an exception. Instead, operations that divide by zero
result in an INF and NaN values; see below.
For integer cases, the result of a % b is defined to be the number r such that (a / b) * b + r is
equal to a, where /, * and + are the appropriate Java integer operators. This applies in all cases
except when b is zero. That case, remainder results in an ArithmeticException.
It follows from the above definition that a % b can be negative only if a is negative, and it be
positive only if a is positive. Moreover, the magnitude of a % b is always less than the magnitude of
b.
Floating point remainder operation is a generalization of the integer case. The result of a % b is the
remainder r is defined by the mathematical relation r = a - (b ⋅ q) where:
• q is an integer,
• it is negative only if a / b is negative an positive only if a / b is positive, and
• its magnitude is as large as possible without exceeding the magnitude of the true
mathematical quotient of a and b.
Floating point remainder can produce INF and NaN values in edge-cases such as when b is zero;
see below. It will not throw an exception.
Important note:
Integer Overflow
Java 32 and 64 bit integer values are signed and use twos-complement binary representation. For
example, the range of numbers representable as (32 bit) int -231 through +231 - 1.
https://riptutorial.com/ 810
When you add, subtract or multiple two N bit integers (N == 32 or 64), the result of the operation
may be too large to represent as an N bit integer. In this case, the operation leads to integer
overflow, and the result can be computed as follows:
It should be noted that integer overflow does not result in exceptions under any circumstances.
• The "infinite" or INF values denote numbers that are too large. The +INF value denote
numbers that are too large and positive. The -INF value denote numbers that are too large
and negative.
• The "indefinite" / "not a number" or NaN denote values resulting from meaningless
operations.
The INF values are produced by floating operations that cause overflow, or by division by zero.
The NaN values are produced by dividing zero by zero, or computing zero remainder zero.
Surprisingly, it is possible perform arithmetic using INF and NaN operands without triggering
exceptions. For example:
For full details, please refer to the relevant subsections of JLS 15. Note that this is largely
"academic". For typical calculations, an INF or NaN means that something has gone wrong; e.g. you
have incomplete or incorrect input data, or the calculation has been programmed incorrectly.
The == and != operators are binary operators that evaluate to true or false depending on whether
the operands are equal. The == operator gives true if the operands are equal and false otherwise.
The != operator gives false if the operands are equal and true otherwise.
These operators can be used operands with primitive and reference types, but the behavior is
significantly different. According to the JLS, there are actually three distinct sets of these
operators:
https://riptutorial.com/ 811
• The Boolean == and != operators.
• The Numeric == and != operators.
• The Reference == and != operators.
However, in all cases, the result type of the == and != operators is boolean.
Note: you need to be careful when using == and != to compare floating point values.
A B A == B A != B
https://riptutorial.com/ 812
There are two "pitfalls" that make it advisable to use == and != sparingly with truth values:
• If you use == or != to compare two Boolean objects, then the Reference operators are used.
This may give an unexpected result; see Pitfall: using == to compare primitive wrappers
objects such as Integer
• The == operator can easily be mistyped as =. For most operand types, this mistake leads to a
compilation error. However, for boolean and Boolean operands the mistake leads to incorrect
runtime behavior; see Pitfall - Using '==' to test a boolean
s1.equals(s2); // true
Warning: using == and != to compare String values is incorrect in most cases; see
http://www.riptutorial.com/java/example/16290/pitfall--using----to-compare-strings . A similar
problem applies to primitive wrapper types; see
http://www.riptutorial.com/java/example/8996/pitfall--using----to-compare-primitive-wrappers-
objects-such-as-integer .
If either operand is NaN, then the result of == is false but the result of != is true. Indeed,
the test x != x is true if and only if the value of x is NaN.
This behavior is (to most programmers) unexpected. If you test if a NaN value is equal to itself, the
answer is "No it isn't!". In other words, == is not reflexive for NaN values.
However, this is not a Java "oddity", this behavior is specified in the IEEE 754 floating-point
standards, and you will find that it is implemented by most modern programming languages. (For
more information, see http://stackoverflow.com/a/1573715/139985 ... noting that this is written by
someone who was "in the room when the decisions were made"!)
https://riptutorial.com/ 813
When the ++ and -- operators follow variables, they are called post-increment and post-
decrement respectively.
int a = 10;
a++; // a now equals 11
a--; // a now equals 10 again
When the ++ and -- operators precede the variables the operations are called pre-increment and
pre-decrement respectively.
int x = 10;
--x; // x now equals 9
++x; // x now equals 10
If the operator precedes the variable, the value of the expression is the value of the variable after
being incremented or decremented. If the operator follows the variable, the value of the expression
is the value of the variable prior to being incremented or decremented.
int x=10;
System.out.println("x=" + x + " x=" + x++ + " x=" + x); // outputs x=10 x=10 x=11
System.out.println("x=" + x + " x=" + ++x + " x=" + x); // outputs x=11 x=12 x=12
System.out.println("x=" + x + " x=" + x-- + " x=" + x); // outputs x=12 x=12 x=11
System.out.println("x=" + x + " x=" + --x + " x=" + x); // outputs x=11 x=10 x=10
Be careful not to overwrite post-increments or decrements. This happens if you use a post-
in/decrement operator at the end of an expression which is reassigned to the in/decremented
variable itself. The in/decrement will not have an effect. Even though the variable on the left hand
side is incremented correctly, its value will be immediately overwritten with the previously
evaluated result from the right hand side of the expression:
int x = 0;
x = x++ + 1 + x++; // x = 0 + 1 + 1
// do not do this - the last increment has no effect (bug!)
System.out.println(x); // prints 2 (not 3!)
Correct:
int x = 0;
x = x++ + 1 + x; // evaluates to x = 0 + 1 + 1
x++; // adds 1
System.out.println(x); // prints 3
Syntax
{condition-to-evaluate} ? {statement-executed-on-true} : {statement-executed-on-false}
https://riptutorial.com/ 814
As shown in the syntax, the Conditional Operator (also known as the Ternary Operator1) uses the
? (question mark) and : (colon) characters to enable a conditional expression of two possible
outcomes. It can be used to replace longer if-else blocks to return one of two values based on
condition.
Is equivalent to
if (testCondition) {
result = value1;
} else {
result = value2;
}
It can be read as “If testCondition is true, set result to value1; otherwise, set result to
value2”.
For example:
Is equivalent to
Common Usage
You can use the conditional operator for conditional assignments (like null checking).
String x = "";
if (y != null) {
x = y.toString();
https://riptutorial.com/ 815
}
Since the Conditional Operator has the second-lowest precedence, above the Assignment
Operators, there is rarely a need for use parenthesis around the condition, but parenthesis is
required around the entire Conditional Operator construct when combined with other operators:
// parenthesis required
7 * (a > 0 ? 2 : 5)
Conditional operators nesting can also be done in the third part, where it works more like chaining
or like a switch statement.
a ? "a is true" :
b ? "a is false, b is true" :
c ? "a and b are false, c is true" :
"a, b, and c are false"
a ? x : (b ? y : (c ? z : w))
Footnote:
1 - Both the Java Language Specification and the Java Tutorial call the (? :) operator the Conditional Operator. The
Tutorial says that it is "also known as the Ternary Operator" as it is (currently) the only ternary operator defined by
Java. The "Conditional Operator" terminology is consistent with C and C++ and other languages with an equivalent
operator.
The Java language provides 4 operators that perform bitwise or logical operations on integer or
boolean operands.
• The complement (~) operator is a unary operator that performs a bitwise or logical inversion
of the bits of one operand; see JLS 15.15.5..
• The AND (&) operator is a binary operator that performs a bitwise or logical "and" of two
operands; see JLS 15.22.2..
• The OR (|) operator is a binary operator that performs a bitwise or logical "inclusive or" of
two operands; see JLS 15.22.2..
• The XOR (^) operator is a binary operator that performs a bitwise or logical "exclusive or" of
two operands; see JLS 15.22.2..
The logical operations performed by these operators when the operands are booleans can be
summarized as follows:
https://riptutorial.com/ 816
A B ~A A&B A|B A^B
0 0 1 0 0 0
0 1 1 0 1 1
1 0 0 0 1 1
1 1 0 1 1 0
Note that for integer operands, the above table describes what happens for individual bits. The
operators actually operate on all 32 or 64 bits of the operand or operands in parallel.
The ~ operator is used to reverse a boolean value, or change all the bits in an integer operand.
The & operator is used for "masking out" some of the bits in an integer operand. For example:
The | operator is used to combine the truth values of two operands. For example:
For more examples of the use of the bitwise operators, see Bit Manipulation
This operator checks whether the object is of a particular class/interface type. instanceof operator
is written as:
https://riptutorial.com/ 817
Example:
true
This operator will still return true if the object being compared is the assignment compatible with
the type on the right.
Example:
class Vehicle {}
true
The Assignment Operators (=, +=, -=, *=, /=, %=, <<=, >>= , >>>=, &=, |= and ^=)
The left hand operand for these operators must be a either a non-final variable or an element of an
array. The right hand operand must be assignment compatible with the left hand operand. This
means that either the types must be the same, or the right operand type must be convertible to the
left operands type by a combination of boxing, unboxing or widening. (For complete details refer to
JLS 5.2.)
The precise meaning of the "operation and assign" operators is specified by JLS 15.26.2 as:
1. =
https://riptutorial.com/ 818
The simple assignment operator: assigns the value of the right hand operand to the left hand
operand.
2. +=
The "add and assign" operator: adds the value of right hand operand to the value of the left hand
operand and assigns the result to left hand operand. If the left hand operand has type String, then
this a "concatenate and assign" operator.
3. -=
The "subtract and assign" operator: subtracts the value of the right operand from the value of the
left hand operand and assign the result to left hand operand.
4. *=
The "multiply and assign" operator: multiplies the value of the right hand operand by the value of
the left hand operand and assign the result to left hand operand. .
5. /=
The "divide and assign" operator: divides the value of the right hand operand by the value of the
left hand operand and assign the result to left hand operand.
6. %=
The "modulus and assign" operator: calculates the modulus of the value of the right hand operand
by the value of the left hand operand and assign the result to left hand operand.
7. <<=
8. >>=
https://riptutorial.com/ 819
9. >>>=
10. &=
11. |=
12. ^=
Java provides a conditional-and and a conditional-or operator, that both take one or two operands
of type boolean and produce a boolean result. These are:
{
boolean L = evaluate(<left-expr>);
if (L) {
return evaluate(<right-expr>);
} else {
// short-circuit the evaluation of the 2nd operand expression
return false;
}
}
{
boolean L = evaluate(<left-expr>);
if (!L) {
return evaluate(<right-expr>);
} else {
// short-circuit the evaluation of the 2nd operand expression
return true;
https://riptutorial.com/ 820
}
}
As the pseudo-code above illustrates, the behavior of the short-circuit operators are equivalent to
using if / else statements.
The first version works in most cases, but if the value argument is null, then a NullPointerException
will be thrown.
In the second version we have added a "guard" test. The value != null && value == 0 expression
is evaluated by first performing the value != null test. If the null test succeeds (i.e. it evaluates to
true) then the value == 0 expression is evaluated. If the null test fails, then the evaluation of value
== 0 is skipped (short-circuited), and we don't get a NullPointerException.
In the first version, both operands of the | will always be evaluated, so the (expensive) isPrime
method will be called unnecessarily. The second version avoids the unnecessary call by using ||
instead of |.
The Java language provides three operator for performing bitwise shifting on 32 and 64 bit integer
values. These are all binary operators with the first operand being the value to be shifted, and the
second operand saying how far to shift.
https://riptutorial.com/ 821
• The << or left shift operator shifts the value given by the first operand leftwards by the
number of bit positions given by the second operand. The empty positions at the right end
are filled with zeros.
• The '>>' or arithmetic shift operator shifts the value given by the first operand rightwards by
the number of bit positions given by the second operand. The empty positions at the left end
are filled by copying the left-most bit. This process is known as sign extension.
• The '>>>' or logical right shift operator shifts the value given by the first operand rightwards
by the number of bit positions given by the second operand. The empty positions at the left
end are filled with zeros.
Notes:
1. These operators require an int or long value as the first operand, and produce a value with
the same type as the first operand. (You will need to use an explicit type cast when
assigning the result of a shift to a byte, short or char variable.)
2. If you use a shift operator with a first operand that is a byte, char or short, it is promoted to an
int and the operation produces an int.)
3. The second operand is reduced modulo the number of bits of the operation to give the
amount of the shift. For more about the mod mathematical concept, see Modulus
examples.
4. The bits that are shifted off the left or right end by the operation are discarded. (Java does
not provide a primitive "rotate" operator.)
5. The arithmetic shift operator is equivalent dividing a (two's complement) number by a power
of 2.
6. The left shift operator is equivalent multiplying a (two's complement) number by a power of
2.
The following table will help you see the effects of the three shift operators. (The numbers have
been expressed in binary notation to aid vizualization.)
https://riptutorial.com/ 822
Operand1 Operand2 << >> >>>
From Java 8 onwards, the Lambda operator ( -> ) is the operator used to introduce a Lambda
Expression. There are two common syntaxes, as illustrated by these examples:
Java SE 8
(This example is included here for completeness. Refer to the Lambda Expressions topic for the
full treatment.)
The operators <, <=, > and >= are binary operators for comparing numeric types. The meaning of
the operators is as you would expect. For example, if a and b are declared as any of byte, short,
char, int, long, float, double or the corresponding boxed types:
- `a < b` tests if the value of `a` is less than the value of `b`.
- `a <= b` tests if the value of `a` is less than or equal to the value of `b`.
- `a > b` tests if the value of `a` is greater than the value of `b`.
- `a >= b` tests if the value of `a` is greater than or equal to the value of `b`.
Relational operators can be used to compare numbers with different types. For example:
int i = 1;
long l = 2;
if (i < l) {
System.out.println("i is smaller");
}
Relational operators can be used when either or both numbers are instances of boxed numeric
types. For example:
https://riptutorial.com/ 823
Integer i = 1; // 1 is autoboxed to an Integer
Integer j = 2; // 2 is autoboxed to an Integer
if (i < j) {
System.out.println("i is smaller");
}
You need to be careful with relational comparisons that involve floating point numbers:
• Expressions that compute floating point numbers often incur rounding errors due to the fact
that the computer floating-point representations have limited precision.
• When comparing an integer type and a floating point type, the conversion of the integer to
floating point can also lead to rounding errors.
Finally, Java does bit support the use of relational operators with any types other than the ones
listed above. For example, you cannot use these operators to compare strings, arrays of numbers,
and so on.
https://riptutorial.com/ 824
Chapter 128: Optional
Introduction
Optional is a container object which may or may not contain a non-null value. If a value is present,
isPresent() will return true and get() will return the value.
Additional methods that depend on the presence of the contained value are provided, such as
orElse(), which returns a default value if value not present, and ifPresent() which executes a
block of code if the value is present.
Syntax
• Optional.empty() // Creates an empty Optional instance.
• Optional.of(value) // Returns an Optional with the specified non-null value. A
NullPointerException will be thrown if the passed value is null.
• Optional.ofNullable(value) // Returns an Optional with the specified value that may be null.
Examples
Return default value if Optional is empty
Don't just use Optional.get() since that may throw NoSuchElementException. The Optional.orElse(T)
and Optional.orElseGet(Supplier<? extends T>) methods provide a way to supply a default value in
case the Optional is empty.
return Optional.ofNullable(value).orElse("defaultValue");
// returns "something"
return Optional.ofNullable(value).orElse("defaultValue");
// returns "defaultValue"
The crucial difference between the orElse and orElseGet is that the latter is only evaluated when
the Optional is empty while the argument supplied to the former one is evaluated even if the
Optional is not empty. The orElse should therefore only be used for constants and never for
supplying value based on any sort of computation.
https://riptutorial.com/ 825
Map
Use the map() method of Optional to work with values that might be null without doing explicit null
checks:
(Note that the map() and filter() operations are evaluated immediately, unlike their Stream
counterparts which are only evaluated upon a terminal operation.)
Syntax:
Code examples:
return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "NONE"
return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "SOMETHING"
Because Optional.map() returns an empty optional when its mapping function returns null, you can
chain several map() operations as a form of null-safe dereferencing. This is also known as Null-
safe chaining.
Here is an alternative way to get the value from toString() using Optional:
This will return an empty string if any of the mapping functions returned null.
Below is an another example, but slightly different. It will print the value only if none of the
mapping functions returned null.
Optional.ofNullable(foo)
.map(Foo::getBar)
.map(Bar::getBaz)
https://riptutorial.com/ 826
.map(Baz::toString)
.ifPresent(System.out::println);
Use the orElseThrow() method of Optional to get the contained value or throw an exception, if it
hasn't been set. This is similar to calling get(), except that it allows for arbitrary exception types.
The method takes a supplier that must return the exception to be thrown.
In the first example, the method simply returns the contained value:
return optional.orElseThrow(IllegalArgumentException::new);
// returns "something" string
In the second example, the method throws an exception because a value hasn't been set:
return optional.orElseThrow(IllegalArgumentException::new);
// throws IllegalArgumentException
You can also use the lambda syntax if throwing an exception with message is needed:
Filter
filter() is used to indicate that you would like the value only if it matches your predicate.
Code examples:
https://riptutorial.com/ 827
Using Optional containers for primitive number types
OptionalDouble, OptionalInt and OptionalLong work like Optional, but are specifically designed to
wrap primitive types:
Because numeric types do have a value, there is no special handling for null. Empty containers
can be checked with:
presentInt.isPresent(); // Is true.
absentInt.isPresent(); // Is false.
The normal orElse method takes an Object, so you might wonder why there is an option to provide
a Supplier here (the orElseGet method).
Consider:
It would still call getValueThatIsHardToCalculate() even though it's result is not used as the optional
is not empty.
https://riptutorial.com/ 828
return Optional.ofNullable(value)
.orElseGet(() -> getValueThatIsHardToCalculate()); // returns "something"
FlatMap
This method is similar to map(Function), but the provided mapper is one whose result is
already an Optional, and if invoked, flatMap does not wrap it with an additional Optional.
In other words, when you chain a method call that returns an Optional, using Optional.flatMap
avoids creating nested Optionals.
If you use Optional.map, you will get a nested Optional; i.e. Optional<Optional<Bar>>.
Optional<Optional<Bar>> nestedOptionalBar =
Optional.of(new Foo())
.map(Foo::getBar);
However, if you use Optional.flatMap, you will get a simple Optional; i.e. Optional<Bar>.
Optional<Bar> optionalBar =
Optional.of(new Foo())
.flatMap(Foo::getBar);
https://riptutorial.com/ 829
Chapter 129: Oracle Official Code Standard
Introduction
Oracle official style guide for the Java Programming Language is a standard followed by
developers at Oracle and recommended to be followed by any other Java developer. It covers
filenames, file organization, indentation, comments, declarations, statements, white space, naming
conventions, programming practices and includes a code example.
Remarks
• The examples above strictly follow the new official style guide from Oracle. They are in other
words not subjectively made up by the authors of this page.
• The official style guide has been carefully written to be backward compatible with the original
style guide and the majority of code out in the wild.
• The official style guide has been peer reviewed by among others, Brian Goetz (Java
Language Architect) and Mark Reinhold (Chief Architect of the Java Platform).
• The examples are non-normative; While they intend to illustrate correct way of formatting the
code, there may be other ways to correctly format the code. This is a general principle:
There may be several ways to format the code, all adhering to the official guidelines.
Examples
Naming Conventions
Package names
• Package names should be all lower case without underscores or other special characters.
• Package names begin with the reversed authority part of the web address of the company of
the developer. This part can be followed a by project/program structure dependent package
substructure.
• Don’t use plural form. Follow the convention of the standard API which uses for instance
java.lang.annotation and not java.lang.annotations.
• Examples: com.yourcompany.widget.button, com.yourcompany.core.api
https://riptutorial.com/ 830
• Use mixed case with the first letter in each word in upper case (i.e. CamelCase).
• Match the regular expression ^[A-Z][a-zA-Z0-9]*$.
• Use whole words and avoid using abbreviations unless the abbreviation is more widely used
than the long form.
• Format an abbreviation as a word if the it is part of a longer class name.
• Examples: ArrayList, BigInteger, ArrayIndexOutOfBoundsException, Iterable.
Method Names
Method names should typically be verbs or other descriptions of actions
Variables
Variable names should be in mixed case with the first letter in lower case
Type Variables
For simple cases where there are few type variables involved use a single upper case letter.
Constants
Constants (static final fields whose content is immutable, by language rules or by convention)
should be named with all capital letters and underscore (_) to separate words.
https://riptutorial.com/ 831
Other guidelines on naming
• Avoid hiding/shadowing methods, variables and type variables in outer scopes.
• Let the verbosity of the name correlate to the size of the scope. (For instance, use
descriptive names for fields of large classes and brief names for local short-lived variables.)
• When naming public static members, let the identifier be self descriptive if you believe they
will be statically imported.
• Further reading: Naming Section (in the official Java Style Guide)
• All lines must be terminated with a line feed character (LF, ASCII value 10) and not for
instance CR or CR+LF.
• The name of a source file must equal the name of the class it contains followed by the .java
extension, even for files that only contain a package private class. This does not apply to
files that do not contain any class declarations, such as package-info.java.
Special Characters
• Apart from LF the only allowed white space character is Space (ASCII value 32). Note that
this implies that other white space characters (in, for instance, string and character literals)
must be written in escaped form.
• Should there be a need to go against the above rules for the sake of testing, the test should
generate the required input programatically.
Package declaration
package com.example.my.package;
The package declaration should not be line wrapped, regardless of whether it exceeds the
recommended maximum length of a line.
Import statements
https://riptutorial.com/ 832
// Then third party libraries
import com.fasterxml.jackson.annotation.JsonProperty;
• Import statements should not be line wrapped, regardless of whether it exceeds the
recommended maximum length of a line.
Wildcard imports
• Wildcard imports should in general not be used.
• When importing a large number of closely-related classes (such as implementing a visitor
over a tree with dozens of distinct “node” classes), a wildcard import may be used.
• In any case, no more than one wildcard import per file should be used.
Class Structure
Ordering fields and methods primarily by their access modifiers or identifier is not required.
class Example {
https://riptutorial.com/ 833
private int i;
Example(int i) {
this.i = i;
}
@Override
public String toString() {
return "An example [" + i + "]";
}
Modifiers
class ExampleClass {
// Access modifiers first (don't do for instance "static public")
public static void main(String[] args) {
System.out.println("Hello World");
}
}
interface ExampleInterface {
// Avoid 'public' and 'abstract' since they are implicit
void sayHello();
}
https://riptutorial.com/ 834
○ synchronized
○ native
○ strictfp
• Modifiers should not be written out when they are implicit. For example, interface methods
should neither be declared public nor abstract, and nested enums and interfaces should not
be declared static.
• Method parameters and local variables should not be declared final unless it improves
readability or documents an actual design decision.
• Fields should be declared final unless there is a compelling reason to make them mutable.
Indentation
switch (var) {
case TWO:
setChoice("two");
break;
case THREE:
setChoice("three");
break;
default:
throw new IllegalArgumentException();
}
Wrapping statements
• Source code and comments should generally not exceed 80 characters per line and rarely if
ever exceed 100 characters per line, including indentation.
The character limit must be judged on a case by case basis. What really matters is the
semantical “density” and readability of the line. Making lines gratuitously long makes them
hard to read; similarly, making “heroic attempts” to fit them into 80 columns can also make
them hard to read. The flexibility outlined here aims to enable developers to avoid these
extremes, not to maximize use of monitor real-estate.
https://riptutorial.com/ 835
// Wrapping preferable
String pretty = Stream.of(args)
.map(Argument::prettyPrint)
.collectors(joining(", "));
• Wrapping at a higher syntactical level is preferred over wrapping at a lower syntactical level.
○ Variant 1: With 8 extra spaces relative to the indentation of the previous line.
○ Variant 2: With 8 extra spaces relative to the starting column of the wrapped
expression.
○ Variant 3: Aligned with previous sibling expression (as long as it is clear that it’s a
continuation line)
○ Variant 4: Aligned with previous method call in a chained expression.
https://riptutorial.com/ 836
throws IllegalArgumentException {
…
}
• Method declarations can be formatted by listing the arguments vertically, or by a new line
and +8 extra spaces
• If a throws clause needs to be wrapped, put the line break in front of the throws clause and
make sure it stands out from the argument list, either by indenting +8 relative to the function
declaration, or +8 relative to the previous line.
Wrapping Expressions
• If a line approaches the maximum character limit, always consider breaking it down into
multiple statements / expressions instead of wrapping the line.
• Break before operators.
• Break before the . in chained method calls.
Whitespace
Vertical Whitespace
• A single blank line should be used to separate…
○ Package declaration
○ Class declarations
○ Constructors
○ Methods
○ Static initializers
○ Instance initializers
○ import statements
○ fields
○ statements
• Multiple consecutive blank lines should only be used to separate groups of related members
and not as the standard inter-member spacing.
https://riptutorial.com/ 837
Horizontal Whitespace
• A single space should be used…
Variable Declarations
• One variable per declaration (and at most one declaration per line)
• Square brackets of arrays should be at the type (String[] args) and not on the variable (
String args[]).
• Declare a local variable right before it is first used, and initialize it as close to the declaration
as possible.
Annotations
Declaration annotations should be put on a separate line from the declaration being annotated.
@SuppressWarnings("unchecked")
public T[] toArray(T[] typeHolder) {
...
}
However, few or short annotations annotating a single-line method may be put on the same line as
the method if it improves readability. For example, one may write:
For a matter of consistency and readability, either all annotations should be put on the same line
or each annotation should be put on a separate line.
// Bad.
@Deprecated @SafeVarargs
@CustomAnnotation
public final Tuple<T> extend(T... elements) {
...
}
// Even worse.
@Deprecated @SafeVarargs
@CustomAnnotation public final Tuple<T> extend(T... elements) {
https://riptutorial.com/ 838
...
}
// Good.
@Deprecated
@SafeVarargs
@CustomAnnotation
public final Tuple<T> extend(T... elements) {
...
}
// Good.
@Deprecated @SafeVarargs @CustomAnnotation
public final Tuple<T> extend(T... elements) {
...
}
Lambda Expressions
Redundant Parentheses
// Don't do this
return (flag ? "yes" : "no");
• Redundant grouping parentheses (i.e. parentheses that does not affect evaluation) may be
used if they improve readability.
• Redundant grouping parentheses should typically be left out in shorter expressions involving
common operators but included in longer expressions or expressions involving operators
whose precedence and associativity is unclear without parentheses. Ternary expressions
with non-trivial conditions belong to the latter.
https://riptutorial.com/ 839
• The entire expression following a return keyword must not be surrounded by parentheses.
Literals
long l = 5432L;
int i = 0x123 + 0xABC;
byte b = 0b1010;
float f1 = 1 / 5432f;
float f2 = 0.123e4f;
double d1 = 1 / 5432d; // or 1 / 5432.0
double d2 = 0x1.3p2;
Braces
class Example {
void method(boolean error) {
if (error) {
Log.error("Error occurred!");
System.out.println("Error!");
} else { // Use braces since the other block uses braces.
System.out.println("No error");
}
}
}
• Opening braces should be put on the end of the current line rather than on a line by its own.
• There should be a new line in front of a closing brace unless the block is empty (see Short
Forms below)
• Braces are recommended even where the language makes them optional, such as single-
line if and loop bodies.
○ If a block spans more than one line (including comments) it must have braces.
○ If one of the blocks in a if / else statement has braces, the other block must too.
○ If the block comes last in an enclosing block, it must have braces.
• The else, catch and the while keyword in do…while loops go on the same line as the closing
brace of the preceding block.
Short forms
enum Response { YES, NO, MAYBE }
public boolean isReference() { return true; }
The above recommendations are intended to improve uniformity (and thus increase familiarity /
https://riptutorial.com/ 840
readability). In some cases “short forms” that deviate from the above guidelines are just as
readable and may be used instead. These cases include for instance simple enum declarations
and trivial methods and lambda expressions.
https://riptutorial.com/ 841
Chapter 130: Packages
Introduction
package in java is used to group class and interfaces. This helps developer to avoid conflict when
there are huge numbers of classes. If we use this package the classes we can create a
class/interface with same name in different packages. By using packages we can import the piece
of again in another class. There many built in packages in java like > 1.java.util > 2.java.lang >
3.java.io We can define our own user defined packages.
Remarks
Packages provide access protection.
package statement must be first line of source code. There can only be one package in
one source file.
Examples
Using Packages to create classes with the same name
First Test.class:
package foo.bar
package foo.bar.baz
The above is fine because the two classes exist in different packages.
In Java if you don't provide an access modifier the default scope for variables is package-
protected level. This means that classes can access the variables of other classes within the same
package as if those variables were publicly available.
https://riptutorial.com/ 842
package foo.bar
public ExampleClass() {
exampleNumber = 3;
exampleString = "Test String";
}
//No getters or setters
}
package foo.bar
package baz.foo
https://riptutorial.com/ 843
Chapter 131: Parallel programming with
Fork/Join framework
Examples
Fork/Join Tasks in Java
The fork/join framework in Java is ideal for a problem that can be divided into smaller pieces and
solved in parallel. The fundamental steps of a fork/join problem are:
A ForkJoinTask is the interface that defines such a problem. It is generally expected that you will
subclass one of its abstract implementations (usually the RecursiveTask) rather than implement
the interface directly.
In this example, we are going to sum a collection of integers, dividing until we get to batch sizes of
no more than ten.
import java.util.List;
import java.util.concurrent.RecursiveTask;
@Override
public Integer compute() {
if (maxExclusive - minInclusive > MAX_BATCH_SIZE) {
// This is too big for a single batch, so we shall divide into two tasks
int mid = (minInclusive + maxExclusive) / 2;
SummingTask leftTask = new SummingTask(numbers, minInclusive, mid);
SummingTask rightTask = new SummingTask(numbers, mid, maxExclusive);
// Submit the left hand task as a new task to the same ForkJoinPool
leftTask.fork();
https://riptutorial.com/ 844
// Run the right hand task on the same thread and get the result
int rightResult = rightTask.compute();
// Wait for the left hand task to complete and get its result
int leftResult = leftTask.join();
// Submit the task to the pool, and get what is effectively the Future
ForkJoinTask<Integer> task = pool.submit(new SummingTask(numbers));
https://riptutorial.com/ 845
Chapter 132: Polymorphism
Introduction
Polymorphism is one of main OOP(object oriented programming) concepts. Polymorphism word
was derived from the greek words "poly" and "morphs". Poly means "many" and morphs means
"forms" (many forms).
There are two ways to perform polymorphism. Method Overloading and Method Overriding.
Remarks
Interfaces are another way to achieve polymorphism in Java, apart from class based inheritance.
Interfaces define a list of methods which form the API of the program. Classes must implement an
interface by overriding all its methods.
Examples
Method Overloading
Method overloading, also known as function overloading, is the ability of a class to have
multiple methods with the same name, granted that they differ in either number or type of
arguments.
1. Method name
2. Number of parameters
3. Types of parameters
If these three are same for any two methods in a class, then compiler throws duplicate method
error.
This type of polymorphism is called static or compile time polymorphism because the appropriate
method to be called is decided by the compiler during the compile time based on the argument list.
class Polymorph {
https://riptutorial.com/ 846
public float add(float a, float b){
return a + b;
}
System.out.println(poly.add(a, b));
System.out.println(poly.add(a, b, c));
System.out.println(poly.add(d, e));
}
2
6
4.000000
Overloaded methods may be static or non-static. This also does not effect method overloading.
Also if you change the return type of method, we are unable to get it as method overloading.
void methodOverloaded(){
//No argument and No return type
}
https://riptutorial.com/ 847
int methodOverloaded(){
//No argument and int return type
return 0;
}
Method Overriding
Method overriding is the ability of subtypes to redefine (override) the behavior of their supertypes.
In Java, this translates to subclasses overriding the methods defined in the super class. In Java,
all non-primitive variables are actually references, which are akin to pointers to the location of the
actual object in memory. The references only have one type, which is the type they were declared
with. However, they can point to an object of either their declared type or any of its subtypes.
When a method is called on a reference, the corresponding method of the actual object being
pointed to is invoked.
class SuperType {
public void sayHello(){
System.out.println("Hello from SuperType");
}
class Test {
public static void main(String... args){
SuperType superType = new SuperType();
superType.sayHello(); // -> Hello from SuperType
To override a method in the subclass, the overriding method (i.e. the one in the subclass) MUST
HAVE:
https://riptutorial.com/ 848
• same name
• same return type in case of primitives (a subclass is allowed for classes, this is also known
as covariant return types).
• same type and order of parameters
• it may throw only those exceptions that are declared in the throws clause of the superclass's
method or exceptions that are subclasses of the declared exceptions. It may also choose
NOT to throw any exception. The names of the parameter types do not matter. For example,
void methodX(int i) is same as void methodX(int k)
• We are unable to Override final or Static methods. Only thing that we can do change only
method body.
import java.util.ArrayList;
import java.util.List;
new MakeThingsFly().letTheMachinesFly(machines);
}
}
class MakeThingsFly {
public void letTheMachinesFly(List<FlyingMachine> flyingMachines) {
for (FlyingMachine flyingMachine : flyingMachines) {
flyingMachine.fly();
}
}
}
class FlyingMachine {
public void fly() {
out.println("No implementation");
}
}
https://riptutorial.com/ 849
@Override
public void fly() {
out.println("Start vertically, hover, fly");
}
}
Explanation
a) The MakeThingsFly class can work with everything that is of type FlyingMachine.
b) The method letTheMachinesFly also works without any change (!) when you add a new class, for
example PropellerPlane:
That's the power of polymorphism. You can implement the open-closed-principle with it.
Virtual functions
Virtual Methods are methods in Java that are non-static and without the keyword Final in front. All
methods by default are virtual in Java. Virtual Methods play important roles in Polymorphism
because children classes in Java can override their parent classes' methods if the function being
overriden is non-static and has the same method signature.
There are, however, some methods that are not virtual. For example, if the method is declared
private or with the keyword final, then the method is not Virtual.
Consider the following modified example of inheritance with Virtual Methods from this
StackOverflow post How do virtual functions work in C# and Java? :
public class A{
public void hello(){
System.out.println("Hello");
}
}
}
https://riptutorial.com/ 850
}
}
If we invoke class B and call hello() and boo(), we would get "No" and "Say haha" as the resulting
output because B overrides the same methods from A. Even though the example above is almost
exactly the same as method overriding, it is important to understand that the methods in class A
are all, by default, Virtual.
Additionally, we can implement Virtual methods using the abstract keyword. Methods declared
with the keyword "abstract" does not have a method definition, meaning the method's body is not
yet implemented. Consider the example from above again, except the boo() method is declared
abstract:
public class A{
public void hello(){
System.out.println("Hello");
}
}
}
If we invoke boo() from B, the output will still be "Say haha" since B inherits the abstract method
boo() and makes boo () output "Say haha".
Check out this great answer that gives a much more complete information about Virtual functions:
https://riptutorial.com/ 851
Have a look at this example to understand different types of overriding.
1. Base class provides no implementation and sub-class has to override complete method -
(abstract)
2. Base class provides default implementation and sub-class can change the behaviour
3. Sub-class adds extension to base class implementation by calling super.methodName() as first
statement
4. Base class defines structure of the algorithm (Template method) and sub-class will override
a part of algorithm
code snippet:
import java.util.HashMap;
public Game(){
player1 = new Player("Player 1");
player2 = new Player("Player 2");
currentPlayer = player1;
initializeGame();
}
/* Type 1: Let subclass define own implementation. Base class defines abstract method to
force
sub-classes to define implementation
*/
/* Type 2: Sub-class can change the behaviour. If not, base class behaviour is applicable
*/
protected void logTimeBetweenMoves(Player player){
System.out.println("Base class: Move Duration: player.PlayerActTime -
player.MoveShownTime");
}
/* Type 3: Base class provides implementation. Sub-class can enhance base class
implementation by calling
super.methodName() in first line of the child class method and specific implementation
later */
protected void logGameStatistics(){
System.out.println("Base class: logGameStatistics:");
}
/* Type 4: Template method: Structure of base class can't be changed but sub-class can
some part of behaviour */
protected void runGame() throws Exception{
System.out.println("Base class: Defining the flow for Game:");
while (runGame) {
/*
1. Set current player
2. Get Player Move
*/
https://riptutorial.com/ 852
validatePlayerMove(currentPlayer);
logTimeBetweenMoves(currentPlayer);
Thread.sleep(500);
setNextPlayer();
}
logGameStatistics();
}
/* sub-part of the template method, which define child class behaviour */
protected abstract void validatePlayerMove(Player p);
class Player{
String name;
Player(String name){
this.name = name;
}
public String getName(){
return name;
}
}
https://riptutorial.com/ 853
}
public void initializeGame(){
System.out.println("Child class: Initialized TicTacToe game");
}
protected void validatePlayerMove(Player p){
System.out.println("Child class: Validate TicTacToe move:" + p.getName());
}
}
}catch(Exception err){
err.printStackTrace();
}
}
}
output:
https://riptutorial.com/ 854
Chapter 133: Preferences
Examples
Adding event listeners
There are two types of events emitted by a Preferences object: PreferenceChangeEvent and
NodeChangeEvent.
PreferenceChangeEvent
A PreferenceChangeEvent gets emitted by a Properties object every time one of the node's key-
value-pairs changes. PreferenceChangeEvents can be listened for with a PreferenceChangeListener:
Java SE 8
preferences.addPreferenceChangeListener(evt -> {
String newValue = evt.getNewValue();
String changedPreferenceKey = evt.getKey();
Preferences changedNode = evt.getNode();
});
Java SE 8
preferences.addPreferenceChangeListener(new PreferenceChangeListener() {
@Override
public void preferenceChange(PreferenceChangeEvent evt) {
String newValue = evt.getNewValue();
String changedPreferenceKey = evt.getKey();
Preferences changedNode = evt.getNode();
}
});
This listener will not listen to changed key-value pairs of child nodes.
NodeChangeEvent
This event will be fired whenever a child node of a Properties node is added or removed.
preferences.addNodeChangeListener(new NodeChangeListener() {
@Override
public void childAdded(NodeChangeEvent evt) {
Preferences addedChild = evt.getChild();
Preferences parentOfAddedChild = evt.getParent();
}
@Override
public void childRemoved(NodeChangeEvent evt) {
Preferences removedChild = evt.getChild();
Preferences parentOfRemovedChild = evt.getParent();
}
https://riptutorial.com/ 855
});
Preferences objects always represent a specific node in a whole Preferences tree, kind of like this:
/userRoot
├── com
│ └── mycompany
│ └── myapp
│ ├── darkApplicationMode=true
│ ├── showExitConfirmation=false
│ └── windowMaximized=true
└── org
└── myorganization
└── anotherapp
├── defaultFont=Helvetica
├── defaultSavePath=/home/matt/Documents
└── exporting
├── defaultFormat=pdf
└── openInBrowserAfterExport=false
package com.mycompany.myapp;
// ...
2. By relative path:
Using a relative path (a path not starting with a /) will cause the path to be resolved relative
to the parent node it is resolved on. For example, the following example will return the node
of the path /one/two/three/com/mycompany/myapp:
3. By absolute path:
Using an absolute path on the root node will not be different from using a relative path. The
https://riptutorial.com/ 856
difference is that, if called on a sub-node, the path will be resolved relative to the root node.
All instances of Preferences are always thread-safe across the threads of a single Java Virtual
Machine (JVM). Because Preferences can be shared across multiple JVMs, there are special
methods that deal with synchronizing changes across virtual machines.
If you have an application which is supposed to run in a single instance only, then no external
synchronization is required.
If you have an application which runs in multiple instances on a single system and therefore
Preferences access needs to be coordinated between the JVMs on the system, then the sync()
method of any Preferences node may be used to ensure changes to the Preferences node are
visible to other JVMs on the system:
Exporting preferences
Preferences nodes can be exported into a XML document representing that node. The resulting
XML tree can be imported again. The resulting XML document will remember whether it was
exported from the user or system Preferences.
Java SE 7
Java SE 7
https://riptutorial.com/ 857
OutputStream os = null;
try {
os = ...;
preferences.exportSubtree(os);
} catch (IOException ioe) {
// Exception whilst writing data to the OutputStream
ioe.printStackTrace();
} catch (BackingStoreException bse) {
// Exception whilst reading from the backing preferences store
bse.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException ignored) {}
}
}
Java SE 7
Java SE 7
OutputStream os = null;
try {
os = ...;
preferences.exportSubtree(os);
} catch (IOException ioe) {
// Exception whilst writing data to the OutputStream
ioe.printStackTrace();
} catch (BackingStoreException bse) {
// Exception whilst reading from the backing preferences store
bse.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException ignored) {}
}
}
Importing preferences
Preferences nodes can be imported from a XML document. Importing is meant to be used in
conjunction with the exporting functionality of Preferences, since it creates the correct
corresponding XML documents.
https://riptutorial.com/ 858
The XML documents will remember whether they were exported from the user or system
Preferences. Therefore, they can be imported into their respective Preferences trees again, without
you having to figure out or know where they came from. The static function will automatically find
out whether the XML document was exported from the user or system Preferences and will
automatically import them into the tree they were exported from.
Java SE 7
Java SE 7
InputStream is = null;
try {
is = ...;
// This is a static call on the Preferences class
Preferences.importPreferences(is);
} catch (IOException ioe) {
// Exception whilst reading data from the InputStream
ioe.printStackTrace();
} catch (InvalidPreferencesFormatException ipfe) {
// Exception whilst parsing the XML document tree
ipfe.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignored) {}
}
}
Event listeners can be removed again from any Properties node, but the instance of the listener
has to be kept around for that.
Java SE 8
//
// later...
https://riptutorial.com/ 859
//
preferences.removePreferenceChangeListener(listener);
Java SE 8
//
// later...
//
preferences.removePreferenceChangeListener(listener);
A value of a Preferences node can be of the type String, boolean, byte[], double, float, int or long.
All invocations must provide a default value, in case the specified value is not present in the
Preferences node.
To store a value into the Preferences node, one of the putXXX() methods is used. A value of a
Preferences node can be of the type String, boolean, byte[], double, float, int or long.
https://riptutorial.com/ 860
Using preferences
Preferences can be used to store user settings that reflect a user's personal application settings,
e.g. their editor font, whether they prefer the application to be started in full-screen mode, whether
they checked a "don't show this again" checkbox and things like that.
if (!doShowDialog) {
return true;
}
//
// Show a dialog here...
//
boolean exitWasConfirmed = ...; // whether the user clicked OK or Cancel
boolean doNotShowAgain = ...; // get value from "Do not show again" checkbox
return exitWasConfirmed;
}
https://riptutorial.com/ 861
Chapter 134: Primitive Data Types
Introduction
The 8 primitive data types byte, short, int, long, char, boolean, float, and double are the types that
store most raw numerical data in Java programs.
Syntax
• int aInt = 8; // The defining (number) part of this int declaration is called a literal.
• int hexInt = 0x1a; // = 26; You can define literals with hex values prefixed with 0x.
• int binInt = 0b11010; // = 26; You can also define binary literals; prefixed with 0b.
• long goodLong = 10000000000L; // By default, integer literals are of type int. By adding the L
at the end of the literal you are telling the compiler that the literal is a long. Without this the
compiler would throw an "Integer number too large" error.
• float aFloat = 3.14F; // By default this literal would have been a double (and caused an
"Incompatible Types" error), but by adding an F we tell the compiler it is a float.
Remarks
Java has 8 primitive data types, namely boolean, byte, short, char, int, long, float and double. (All
other types are reference types. This includes all array types, and built-in object types / classes
that have special significance in the Java language; e.g. String, Class and Throwable and its
subclasses.)
The result of all operations (addition, subtraction, multiplication, etc) on a primitive type is at least
an int, thus adding a short to a short produces an int, as does adding a byte to a byte, or a char to
a char. If you want to assign the result of that back to a value of the same type, you must cast it.
e.g.
byte a = 1;
byte b = 2;
byte c = (byte) (a + b);
This is due to the following part of the Java Language Spec, §2.11.1:
A compiler encodes loads of literal values of types byte and short using Java Virtual
Machine instructions that sign-extend those values to values of type int at compile-
https://riptutorial.com/ 862
time or run-time. Loads of literal values of types boolean and char are encoded using
instructions that zero-extend the literal to a value of type int at compile-time or run-
time. [..]. Thus, most operations on values of actual types boolean, byte, char, and short
are correctly performed by instructions operating on values of computational type int.
Given the Java Virtual Machine's one-byte opcode size, encoding types into opcodes
places pressure on the design of its instruction set. If each typed instruction supported
all of the Java Virtual Machine's run-time data types, there would be more instructions
than could be represented in a byte. [...] Separate instructions can be used to convert
between unsupported and supported data types as necessary.
Examples
The int primitive
A primitive data type such as int holds values directly into the variable that is using it, meanwhile
a variable that was declared using Integer holds a reference to the value.
According to java API: "The Integer class wraps a value of the primitive type int in an object. An
object of type Integer contains a single field whose type is int."
By default, int is a 32-bit signed integer. It can store a minimum value of -231, and a maximum
value of 231 - 1.
If you need to store a number outside of this range, long should be used instead. Exceeding the
value range of int leads to an integer overflow, causing the value exceeding the range to be
added to the opposite site of the range (positive becomes negative and vise versa). The value is
((value - MIN_VALUE) % RANGE) + MIN_VALUE, or ((value + 2147483648) % 4294967296) - 2147483648
https://riptutorial.com/ 863
int defaultInt; // defaultInt == 0
A short is a 16-bit signed integer. It has a minimum value of -215 (-32,768), and a maximum value
of 215 ‑1 (32,767)
By default, long is a 64-bit signed integer (in Java 8, it can be either signed or unsigned). Signed, it
can store a minimum value of -263, and a maximum value of 263 - 1, and unsigned it can store a
minimum value of 0 and a maximum value of 264 - 1
//an "L" must be appended to the end of the number, because by default,
//numbers are assumed to be the int type. Appending an "L" makes it a long
//as 549755813888 (2 ^ 39) is larger than the maximum value of an int (2^31 - 1),
//"L" must be appended
long bigNumber = 549755813888L;
https://riptutorial.com/ 864
Note: letter "L" appended at the end of long literal is case insensitive, however it is good practice
to use capital as it is easier to distinct from digit one:
2L == 2l; // true
Warning: Java caches Integer objects instances from the range -128 to 127. The reasoning is
explained here: https://blogs.oracle.com/darcy/entry/boxing_and_caches_integer_valueof
To properly compare 2 Object Long values, use the following code(From Java 1.7 onward):
Comparing a primitive long to an Object long will not result in a false negative like comparing 2
objects with == does.
https://riptutorial.com/ 865
boolean defaultBoolean; // defaultBoolean == false
A byte is a 8-bit signed integer. It can store a minimum value of -27 (-128), and a maximum value
of 27 - 1 (127)
A float is a single-precision 32-bit IEEE 754 floating point number. By default, decimals are
interpreted as doubles. To create a float, simply append an f to the decimal literal.
Floats handle the five common arithmetical operations: addition, subtraction, multiplication,
division, and modulus.
Note: The following may vary slightly as a result of floating point errors. Some results have been
rounded for clarity and readability purposes (i.e. the printed result of the addition example was
actually 34.600002).
// addition
float result = 37.2f + -2.6f; // result: 34.6
// subtraction
float result = 45.1f - 10.3f; // result: 34.8
// multiplication
https://riptutorial.com/ 866
float result = 26.3f * 1.7f; // result: 44.71
// division
float result = 37.1f / 4.8f; // result: 7.729166
// modulus
float result = 37.1f % 4.8f; // result: 3.4999971
Because of the way floating point numbers are stored (i.e. in binary form), many numbers don't
have an exact representation.
While using float is fine for most applications, neither float nor double should be used to store
exact representations of decimal numbers (like monetary amounts), or numbers where higher
precision is required. Instead, the BigDecimal class should be used.
Note: Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NaN are float values. NaN stands for
results of operations that cannot be determined, such as dividing 2 infinite values. Furthermore 0f
and -0f are different, but == yields true:
float f1 = 0f;
float f2 = -0f;
System.out.println(f1 == f2); // true
System.out.println(1f / f1); // Infinity
System.out.println(1f / f2); // -Infinity
System.out.println(Float.POSITIVE_INFINITY / Float.POSITIVE_INFINITY); // NaN
Because of the way floating point numbers are stored, many numbers don't have an exact
representation.
https://riptutorial.com/ 867
double notExact = 1.32 - 0.42; // result should be 0.9
System.out.println(notExact); // 0.9000000000000001
While using double is fine for most applications, neither float nor double should be used to store
precise numbers such as currency. Instead, the BigDecimal class should be used
double d1 = 0d;
double d2 = -0d;
System.out.println(d1 == d2); // true
System.out.println(1d / d1); // Infinity
System.out.println(1d / d2); // -Infinity
System.out.println(Double.POSITIVE_INFINITY / Double.POSITIVE_INFINITY); // NaN
A char can store a single 16-bit Unicode character. A character literal is enclosed in single quotes
It has a minimum value of \u0000 (0 in the decimal representation, also called the null character)
and a maximum value of \uffff (65,535).
In order to define a char of ' value an escape sequence (character preceded by a backslash) has
to be used:
https://riptutorial.com/ 868
allowed
char backslash = '\\';
char unicodeChar = '\uXXXX' // XXXX represents the Unicode-value of the character you want to
display
It is also possible to add to a char. e.g. to iterate through every lower-case letter, you could do to
the following:
Java and most other languages store negative integral numbers in a representation called 2's
complement notation.
For a unique binary representation of a data type using n bits, values are encoded like this:
The least significant n-1 bits store a positive integral number x in integral representation. Most
significant value stores a bit vith value s. The value repesented by those bits is
x - s * 2n-1
i.e. if the most significant bit is 1, then a value that is just by 1 larger than the number you could
represent with the other bits (2n-2 + 2n-3 + ... + 21 + 20 = 2n-1 - 1) is subtracted allowing a unique
binary representation for each value from - 2n-1 (s = 1; x = 0) to 2n-1 - 1 (s = 0; x = 2n-1 - 1).
This also has the nice side effect, that you can add the binary representations as if they were
positive binary numbers:
v1 = x1 - s1 * 2n-1
v2 = x2 - s2 * 2n-1
x1 + x2
s1 s2 addition result
overflow
0 0 No x1 + x2 = v1 + v2
x1 + x2 - 2n-1 = x1 + x2 - s2 * 2n-1
0 1 No = v1 + v2
https://riptutorial.com/ 869
x1 + x2
s1 s2 addition result
overflow
Note that this fact makes finding binary representation of the additive inverse (i.e. the negative
value) easy:
Observe that adding the bitwise complement to the number results in all bits being 1. Now add 1 to
make value overflow and you get the neutral element 0 (all bits 0).
So the negative value of a number i can be calculated using (ignoring possible promotion to int
here)
(~i) + 1
The result of negating 0, is 11111111. Adding 1 gives a value of 100000000 (9 bits). Because a byte
can only store 8 bits, the leftmost value is truncated, and the result is 00000000
https://riptutorial.com/ 870
Primitive Boxed Type Memory Size of primitive / boxed
Boxed objects always require 8 bytes for type and memory management, and because the size of
objects is always a multiple of 8, boxed types all require 16 bytes total. In addition, each usage of
a boxed object entails storing a reference which accounts for another 4 or 8 bytes, depending on
the JVM and JVM options.
If you create an instance of a boxed type either by autoboxing or by calling the static
valueOf(primitive) method, the runtime system will attempt to use a cached value. If your
application uses a lot of values in the range that is cached, then this can substantially reduce the
memory penalty of using boxed types. Certainly, if you are creating boxed value instances "by
hand", it is better to use valueOf rather than new. (The new operation always creates a new
instance.) If, however, the majority of your values are not in the cached range, it can be faster to
call new and save the cache lookup.
Converting Primitives
In Java, we can convert between integer values and floating-point values. Also, since every
character corresponds to a number in the Unicode encoding, char types can be converted to and
from the integer and floating-point types. boolean is the only primitive datatype that cannot be
converted to or from any other primitive datatype.
https://riptutorial.com/ 871
There are two types of conversions: widening conversion and narrowing conversion.
A widening conversion is when a value of one datatype is converted to a value of another datatype
that occupies more bits than the former. There is no issue of data loss in this case.
Java performs widening conversions automatically. But if you want to perform a narrowing
conversion (if you are sure that no data loss will occur), then you can force Java to perform the
conversion using a language construct known as a cast.
Widening Conversion:
int a = 1;
double d = a; // valid conversion to double, no cast needed (widening)
Narrowing Conversion:
double d = 18.96
int b = d; // invalid conversion to int, will throw a compile-time error
int b = (int) d; // valid conversion to int, but result is truncated (gets rounded down)
// This is type-casting
// Now, b = 18
-128 to +127
-32,768 to +32,767
-2,147,483,648 to +2,147,483,647
-9,223,372,036,854,775,808 to
9,223,372,036,854,775,807
https://riptutorial.com/ 872
data numeric default
range of values
type representation value
4.94065645841246544e-324d to
64-bit floating
double 1.79769313486231570e+308d (positive or 0.0D
point
negative)
0 to 65,535
Notes:
1. The Java Language Specification mandates that signed integral types (byte through long)
use binary twos-complement representation, and the floating point types use standard IEE
754 binary floating point representations.
2. Java 8 and later provide methods to perform unsigned arithmetic operations on int and long.
While these methods allow a program to treat values of the respective types as unsigned,
the types remain signed types.
3. The smallest floating point shown above are subnormal; i.e. they have less precision than a
normal value. The smallest normal numbers are 1.175494351e−38 and
2.2250738585072014e−308
4. A char conventionally represents a Unicode / UTF-16 code unit.
5. Although a boolean contains just one bit of information, its size in memory varies depending
on the Java Virtual Machine implementation (see boolean type).
https://riptutorial.com/ 873
Chapter 135: Process
Remarks
Notice that the API recommends that, as of version 1.5, the preferred way to create a Process is
using ProcessBuilder.start().
Another important remark is that the exit value produced by waitFor is dependent from the
program/script being executed. For instance, the exit codes produced by calc.exe are different
from notepad.exe.
Examples
Simple example (Java version < 1.5)
This example will call the windows calculator. It's important to notice that the exit code will vary
accordingly to the program/script that is being called.
package process.example;
import java.io.IOException;
System.out.println(exitCode);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The ProcessBuilder class makes it easy to send a command through the command line. All it
requires is a List of Strings that make up the commands to be entered. You simply call the start()
method on your ProcessBuilder instance to execute the command.
If you have a program called Add.exe which takes two arguments and adds them, the code would
look something like this:
https://riptutorial.com/ 874
List<String> cmds = new ArrayList<>();
cmds.add("Add.exe"); //the name of the application to be run
cmds.add("1"); //the first argument
cmds.add("5"); //the second argument
//Set the working directory of the ProcessBuilder so it can find the .exe
//Alternatively you can just pass in the absolute file path of the .exe
File myWorkingDirectory = new File(yourFilePathNameGoesHere);
pb.workingDirectory(myWorkingDirectory);
try {
Process p = pb.start();
} catch (IOException e) {
e.printStackTrace();
}
In general when making a call to the command line, the program will send the command and then
continue its execution.
However you may want to wait for the called program to finish before continuing your own
execution (ex. The called program will write data to a file and your program needs that to access
that data.)
This can easily be done by calling the waitFor() method from the returned Process instance.
Usage example:
try {
Process p = pb.start();
p.waitFor();
} catch (IOException e) {
e.printStackTrack();
} catch (InterruptedException e) {
e.printStackTrace();
}
https://riptutorial.com/ 875
ch.vorburger.exec
Launching external processes from Java using the raw java.lang.ProcessBuilder API directly can
be a little cumbersome. The Apache Commons Exec library makes it a little easier. The
ch.vorburger.exec library further extends upon Commons Exec to make it truly convenient:
proc.start();
int status = proc.waitForExit();
int status = proc.waitForExitMaxMsOrDestroy(3000);
String output = proc.getConsole();
proc.startAndWaitForConsoleMessageMaxMs("started!", 7000);
// use service offered by external process...
proc.destroy();
The Runtime.exec(String ...) and Runtime.exec(String) methods allow you to execute a command
as an external process1. In the first version, you supply the command name and the command
arguments as separate elements of the string array, and the Java runtime requests the OS
runtime system to start the external command. The second version is deceptively easy to use, but
it has some pitfalls.
Spaces in pathnames
Suppose that we generalize the example above so that we can create an arbitrary directory:
This will typically work, but it will fail if dirPath is (for example) "/home/user/My Documents". The
problem is that exec(String) splits the string into a command and arguments by simply looking for
whitespace. The command string:
https://riptutorial.com/ 876
"mkdir /home/user/My Documents"
and this will cause the "mkdir" command to fail because it expects one argument, not two.
Faced with this, some programmers try to add quotes around the pathname. This doesn't work
either:
The extra double-quote characters that were added in attempt to "quote" the spaces are treated
like any other non-whitespace characters. Indeed, anything we do quote or escape the spaces is
going to fail.
The way to deal with this particular problems is to use the exec(String ...) overload.
This will work if dirpath includes whitespace characters because this overload of exec does not
attempt to split the arguments. The strings are passed through to the OS exec system call as-is.
or
(The first example lists the names of all Java files in the file system, and the second one prints the
package statements2 in the Java files in the "source" tree.)
These are not going to work as expected. In the first case, the "find" command will be run with
"2>/dev/null" as a command argument. It will not be interpreted as a redirection. In the second
example, the pipe character ("|") and the works following it will be given to the "find" command.
https://riptutorial.com/ 877
The problem here is that the exec methods and ProcessBuilder do not understand any shell syntax.
This includes redirections, pipelines, variable expansion, globbing, and so on.
In a few cases (for example, simple redirection) you can easily achieve the desired effect using
ProcessBuilder. However, this is not true in general. An alternative approach is to run the command
line in a shell; for example:
or
But note that in the second example, we needed to escape the wildcard character ("*") because
we want the wildcard to be interpreted by "find" rather than the shell.
or
1. On "cd" and "export" commands are shell builtin commands. They don't exist as distinct
executables.
2. For shell builtins to do what they are supposed to do (e.g. change the working directory,
update the environment), they need to change the place where that state resides. For a
normal application (including a Java application) the state is associated with the application
process. So for example, the child process that would run the "cd" command could not
change the working directory of its parent "java" process. Similarly, one exec'd process
cannot change the working directory for a process that follows it.
1 - You can use ProcessBuilder as well, but that is not relevant to the point of this example.
2 - This is a bit rough and ready ... but once again, the failings of this approach are not relevant to the example.
https://riptutorial.com/ 878
Chapter 136: Properties Class
Introduction
The properties object contains key and value pair both as a string. The java.util.Properties class is
the subclass of Hashtable.
It can be used to get property value based on the property key. The Properties class provides
methods to get data from properties file and store data into properties file. Moreover, it can be
used to get properties of system.
Recompilation is not required, if information is changed from properties file: If any information is
changed from
Syntax
• In a properties file:
• key=value
• #comment
Remarks
A Properties object is a Map whose keys and values are Strings by convention. Although the
methods of Map can be used to access the data, the more type-safe methods getProperty,
setProperty, and stringPropertyNames are usually used instead.
Properties are frequently stored in Java property files, which are simple text files. Their format is
documented thoroughly in the Properties.load method. In summary:
• Each key/value pair is a line of text with whitespace, equals (=), or colon (:) between the key
and the value. The equals or colon may have any amount of whitespace before and after it,
which is ignored.
• Leading whitespace is always ignored, trailing whitespace is always included.
• A backslash can be used to escape any character (except lowercase u).
• A backslash at the end of the line indicates the next line is a continuation of the current line.
However, as with all lines, leading whitespace in the continuation line is ignored.
• Just like in Java source code, \u followed by four hexadecimal digits represents a UTF-16
character.
Most frameworks, including Java SE’s own facilities like java.util.ResourceBundle, load property
files as InputStreams. When loading a property file from an InputStream, that file is may only
contain ISO 8859-1 characters (that is, characters in the 0–255 range). Any other characters must
be represented as \u escapes. However, you can write a text file in any encoding and use the
https://riptutorial.com/ 879
native2ascii tool (which comes with every JDK) to do that escaping for you.
If you are loading a property file with your own code, it can be in any encoding, as long as you
create a Reader (such as an InputStreamReader) based on the corresponding Charset. You can
then load the file using load(Reader) instead of the legacy load(InputStream) method.
You can also store properties in a simple XML file, which allows the file itself to define the
encoding. Such a file can be loaded with the loadFromXML method. The DTD describing the
structure of such XML files is located at http://java.sun.com/dtd/properties.dtd .
Examples
Loading properties
Take a close look at these two property files which are seemingly completely identical:
https://riptutorial.com/ 880
(screenshots are from Notepad++)
Since trailing whitespace is preserved the value of lastName would be "Smith" in the first case and
"Smith " in the second case.
Very rarely this is what users expect and one and can only speculate why this is the default
behavior of Properties class. It is however easy to create an enhanced version of Properties that
fixes this problem. The following class, TrimmedProperties, does just that. It is a drop-in
replacement for standard Properties class.
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Map.Entry;
import java.util.Properties;
/**
* Properties class where values are trimmed for trailing whitespace if the
* properties are loaded from a file.
*
* <p>
* In the standard {@link java.util.Properties Properties} class trailing
* whitespace is always preserved. When loading properties from a file such
* trailing whitespace is almost always <i>unintentional</i>. This class fixes
* this problem. The trimming of trailing whitespace only takes place if the
* source of input is a file and only where the input is line oriented (meaning
* that for example loading from XML file is <i>not</i> changed by this class).
* For this reason this class is almost in all cases a safe drop-in replacement
* for the standard <tt>Properties</tt>
* class.
*
* <p>
* Whitespace is defined here as any of space (U+0020) or tab (U+0009).
* *
*/
public class TrimmedProperties extends Properties {
/**
* Reads a property list (key and element pairs) from the input byte stream.
*
* <p>Behaves exactly as {@link java.util.Properties#load(java.io.InputStream) }
* with the exception that trailing whitespace is trimmed from property values
* if <tt>inStream</tt> is an instance of <tt>FileInputStream</tt>.
*
* @see java.util.Properties#load(java.io.InputStream)
* @param inStream the input stream.
* @throws IOException if an error occurred when reading from the input stream.
*/
@Override
public void load(InputStream inStream) throws IOException {
if (inStream instanceof FileInputStream) {
// First read into temporary props using the standard way
Properties tempProps = new Properties();
tempProps.load(inStream);
// Now trim and put into target
trimAndLoad(tempProps);
} else {
https://riptutorial.com/ 881
super.load(inStream);
}
}
/**
* Reads a property list (key and element pairs) from the input character stream in a
simple line-oriented format.
*
* <p>Behaves exactly as {@link java.util.Properties#load(java.io.Reader)}
* with the exception that trailing whitespace is trimmed on property values
* if <tt>reader</tt> is an instance of <tt>FileReader</tt>.
*
* @see java.util.Properties#load(java.io.Reader) }
* @param reader the input character stream.
* @throws IOException if an error occurred when reading from the input stream.
*/
@Override
public void load(Reader reader) throws IOException {
if (reader instanceof FileReader) {
// First read into temporary props using the standard way
Properties tempProps = new Properties();
tempProps.load(reader);
// Now trim and put into target
trimAndLoad(tempProps);
} else {
super.load(reader);
}
}
/**
* Trims trailing space or tabs from a string.
*
* @param str
* @return
*/
public static String trimTrailing(String str) {
if (str != null) {
// read str from tail until char is no longer whitespace
for (int i = str.length() - 1; i >= 0; i--) {
if ((str.charAt(i) != ' ') && (str.charAt(i) != '\t')) {
return str.substring(0, i + 1);
}
}
}
return str;
}
}
https://riptutorial.com/ 882
Storing Properties in a XML File
The way you store properties files as XML files is very similar to the way you would store them as
.properties files. Just instead of using the store() you would use storeToXML().
Now to load this file as a properties you need to call the loadFromXML() instead of the load() that
you would use with regular .propeties files.
https://riptutorial.com/ 883
System.out.println(name + "=" + prop.getProperty(name));
}
} else {
System.err.println("Error: No file found at: " + location);
}
}
When you run this code you will get the following in the console:
age=23
color=green
name=Steve
https://riptutorial.com/ 884
Chapter 137: Queues and Deques
Examples
The usage of the PriorityQueue
PriorityQueue is a data structure. Like SortedSet, PriorityQueue sorts also its elements based on
their priorities. The elements, which have a higher priority, comes first. The type of the
PriorityQueue should implement comparable or comparator interface, whose methods decides the
priorities of the elements of the data structure.
//The PriorityQueue sorts the elements by using compareTo method of the Integer Class
//The head of this queue is the least element with respect to the specified ordering
System.out.println( queue ); //The Output: [1, 2, 3, 9, 3, 8]
queue.remove();
System.out.println( queue ); //The Output: [2, 3, 3, 9, 8]
queue.remove();
System.out.println( queue ); //The Output: [3, 8, 3, 9]
queue.remove();
System.out.println( queue ); //The Output: [3, 8, 9]
queue.remove();
System.out.println( queue ); //The Output: [8, 9]
queue.remove();
System.out.println( queue ); //The Output: [9]
queue.remove();
System.out.println( queue ); //The Output: []
In the example below, with offer() method, the elements are inserted into the LinkedList. This
insertion operation is called enqueue. In the while loop below, the elements are removed from the
Queue based on FIFO. This operation is called dequeue.
while ( !queue.isEmpty() ) {
System.out.println( queue.poll() );
https://riptutorial.com/ 885
}
first element
second element
third element
fourth element
fifth element
As seen in the output, the first inserted element "first element" is removed firstly, "second element"
is removed in the second place etc.
Stacks
What is a Stack?
In Java, Stacks are a LIFO (Last In, First Out) Data structure for objects.
Stack API
Java contains a Stack API with the following methods
Example
import java.util.*;
st.push(10);
System.out.println("10 was pushed to the stack");
System.out.println("stack: " + st);
st.push(15);
System.out.println("15 was pushed to the stack");
System.out.println("stack: " + st);
st.push(80);
System.out.println("80 was pushed to the stack");
https://riptutorial.com/ 886
System.out.println("stack: " + st);
st.pop();
System.out.println("80 was popped from the stack");
System.out.println("stack: " + st);
st.pop();
System.out.println("15 was popped from the stack");
System.out.println("stack: " + st);
st.pop();
System.out.println("10 was popped from the stack");
System.out.println("stack: " + st);
if(st.isEmpty())
{
System.out.println("empty stack");
}
}
}
This Returns:
stack: []
10 was pushed to the stack
stack: [10]
15 was pushed to the stack
stack: [10, 15]
80 was pushed to the stack
stack: [10, 15, 80]
80 was popped from the stack
stack: [10, 15]
15 was popped from the stack
stack: [10]
10 was popped from the stack
stack: []
empty stack
BlockingQueue
A BlockingQueue is an interface, which is a queue that blocks when you try to dequeue from it and
the queue is empty, or if you try to enqueue items to it and the queue is already full. A thread
trying to dequeue from an empty queue is blocked until some other thread inserts an item into the
queue. A thread trying to enqueue an item in a full queue is blocked until some other thread
makes space in the queue, either by dequeuing one or more items or clearing the queue
completely.
BlockingQueue methods come in four forms, with different ways of handling operations that cannot
be satisfied immediately, but may be satisfied at some point in the future: one throws an
exception, the second returns a special value (either null or false, depending on the operation), the
third blocks the current thread indefinitely until the operation can succeed, and the fourth blocks
for only a given maximum time limit before giving up.
https://riptutorial.com/ 887
Operation Throws Exception Special Value Blocks Times out
BlockingQueue<String> bQueue = new ArrayBlockingQueue<String>(2);
Any calls to a put() method will be blocked if the size of the queue is equal to the initial capacity
defined.
An unbounded Queue is one which is initialized without capacity, actually by default it initialized
with Integer.MAX_VALUE.
1. ArrayBlockingQueue
2. LinkedBlockingQueue
3. PriorityBlockingQueue
Queue Interface
Basics
A Queue is a collection for holding elements prior to processing. Queues typically, but not
necessarily, order elements in a FIFO (first-in-first-out) manner.
https://riptutorial.com/ 888
Head of the queue is the element that would be removed by a call to remove or poll. In a FIFO
queue, all new elements are inserted at the tail of the queue.
E remove();
E poll();
E element();
E peek();
}
Deque
A Deque is a "double ended queue" which means that a elements can be added at the front or the
tail of the queue. The queue only can add elements to the tail of a queue.
The Deque inherits the Queue interface which means the regular methods remain, however the
Deque interface offers additional methods to be more flexible with a queue. The additional
methods really speak for them self if you know how a queue works, since those methods are
intended to add more flexibility:
getFirst() Gets the first item of the head of the queue without removing it.
getLast() Gets the first item of the tail of the queue without removing it.
https://riptutorial.com/ 889
Method Brief description
Of course the same options for offer, poll and peek are available, however they do not work with
exceptions but rather with special values. There is no point in showing what they do here.
You can peek at the element at the head of the queue without taking the element out of the queue.
This is done via the element() method. You can also use the getFirst() and getLast() methods,
which return the first and last element in the Deque. Here is how that looks:
Removing Elements
To remove elements from a deque, you call the remove(), removeFirst() and removeLast() methods.
Here are a few examples:
https://riptutorial.com/ 890
Chapter 138: Random Number Generation
Remarks
Nothing is really random and thus the javadoc calls those numbers pseudorandom. Those
numbers are created with a pseudorandom number generator.
Examples
Pseudo Random Numbers
Java provides, as part of the utils package, a basic pseudo-random number generator,
appropriately named Random. This object can be used to generate a pseudo-random value as any
of the built-in numerical datatypes (int, float, etc). You can also use it to generate a random
Boolean value, or a random array of bytes. An example usage is as follows:
import java.util.Random;
...
double randDouble = random.nextDouble(); //This returns a value between 0.0 and 1.0
float randFloat = random.nextFloat(); //Same as nextDouble
NOTE: This class only produces fairly low-quality pseudo-random numbers, and should never be
used to generate random numbers for cryptographic operations or other situations where higher-
quality randomness is critical (For that, you would want to use the SecureRandom class, as noted
below). An explanation for the distinction between "secure" and "insecure" randomness is beyond
the scope of this example.
The method nextInt(int bound) of Random accepts an upper exclusive boundary, i.e. a number that
the returned random value must be less than. However, only the nextInt method accepts a bound;
nextLong, nextDouble etc. do not.
https://riptutorial.com/ 891
Starting in Java 1.7, you may also use ThreadLocalRandom (source). This class provides a thread-
safe PRNG (pseudo-random number generator). Note that the nextInt method of this class
accepts both an upper and lower bound.
import java.util.concurrent.ThreadLocalRandom;
Note that the official documentation states that nextInt(int bound) can do weird things when bound
is near 230+1 (emphasis added):
The algorithm is slightly tricky. It rejects values that would result in an uneven
distribution (due to the fact that 2^31 is not divisible by n). The probability of a value
being rejected depends on n. The worst case is n=2^30+1, for which the probability
of a reject is 1/2, and the expected number of iterations before the loop
terminates is 2.
In other words, specifying a bound will (slightly) decrease the performance of the nextInt method,
and this performance decrease will become more pronounced as the bound approaches half the
max int value.
Random and ThreadLocalRandom are good enough for everyday use, but they have a big problem:
They are based on a linear congruential generator, an algorithm whose output can be predicted
rather easily. Thus, these two classes are not suitable for cryptographic uses (such as key
generation).
One can use java.security.SecureRandom in situations where a PRNG with an output that is very
hard to predict is required. Predicting the random numbers created by instances of this class is
hard enough to label the class as cryptographically secure.
import java.security.SecureRandom;
import java.util.Arrays;
Besides being cryptographically secure, SecureRandom has a gigantic period of 2160, compared to
Randoms period of 248. It has one drawback of being considerably slower than Random and other
linear PRNGs such as Mersenne Twister and Xorshift, however.
https://riptutorial.com/ 892
Note that SecureRandom implementation is both platform and provider dependent. The default
SecureRandom (given by SUN provider in sun.security.provider.SecureRandom):
/**
* returns a array of random numbers with no duplicates
* @param range the range of possible numbers for ex. if 100 then it can be anywhere from 1-
100
* @param length the length of the array of random numbers
* @return array of random numbers with no duplicates.
*/
public static int[] getRandomNumbersWithNoDuplicates(int range, int length){
if (length<range){
// this is where all the random numbers
int[] randomNumbers = new int[length];
newRandSpot++;
// if we have gone though all the spots then set the value
if (newRandSpot==0){
randomNumbers[q] = t;
}
}
}
}
return randomNumbers;
} else {
// invalid can't have a length larger then the range of possible numbers
}
return null;
https://riptutorial.com/ 893
}
The method works by looping though an array that has the size of the requested length and finds
the remaining length of possible numbers. It sets a random number of those possible numbers
newRandSpot and finds that number within the non taken number left. It does this by looping through
the range and checking to see if that number has already been taken.
For example if the range is 5 and the length is 3 and we have already chosen the number 2. Then
we have 4 remaining numbers so we get a random number between 1 and 4 and we loop through
the range(5) skipping over any numbers that we have already used(2).
Now let's say the next number chosen between 1 & 4 is 3. On the first loop we get 1 which has not
yet been taken so we can remove 1 from 3 making it 2. Now on the second loop we get 2 which
has been taken so we do nothing. We follow this pattern until we get to 4 where once we remove 1
it becomes 0 so we set the new randomNumber to 4.
Using the same seed to generate random numbers will return the same numbers every time, so
setting a different seed for every Random instance is a good idea if you don't want to end up with
duplicate numbers.
A good method to get a Long that is different for every call is System.currentTimeMillis():
Apart from int, we can generate random long, double, float and bytes using this class.
https://riptutorial.com/ 894
static byte[] nextBytes(int count) //Creates an array of random bytes.
static double nextDouble() //Returns a random double within 0 - Double.MAX_VALUE
static double nextDouble(double startInclusive, double endInclusive) //Returns a random double
within the specified range.
static float nextFloat() //Returns a random float within 0 - Float.MAX_VALUE
static float nextFloat(float startInclusive, float endInclusive) //Returns a random float
within the specified range.
static int nextInt() //Returns a random int within 0 - Integer.MAX_VALUE
static int nextInt(int startInclusive, int endExclusive) //Returns a random integer within the
specified range.
static long nextLong() //Returns a random long within 0 - Long.MAX_VALUE
static long nextLong(long startInclusive, long endExclusive) //Returns a random long within
the specified range.
https://riptutorial.com/ 895
Chapter 139: Readers and Writers
Introduction
Readers and Writers and their respective subclasses provide simple I/O for text / character-based
data.
Examples
BufferedReader
Introduction
The BufferedReader class is a wrapper for other Reader classes that serves two main purposes:
1. A BufferedReader provides buffering for the wrapped Reader. This allows an application to read
characters one at a time without undue I/O overheads.
Notes:
1. We have used Java 7 (or later) try-with-resources to ensure that the underlying reader is
https://riptutorial.com/ 896
always closed. This avoids a potential resource leak. In earlier versions of Java, you would
explicitly close the BufferedReader in a finally block.
2. The code inside the try block is virtually identical to what we would use if we read directly
from the FileReader. In fact, a BufferedReader functions exactly like the Reader that it wraps
would behave. The difference is that this version is a lot more efficient.
Java 8 provides a more concise way to do this using the lines() method:
StringWriter Example
Java StringWriter class is a character stream that collects output from string buffer, which can be
used to construct a string.
In StringWriter class, system resources like network sockets and files are not used, therefore
closing the StringWriter is not necessary.
import java.io.*;
https://riptutorial.com/ 897
public class StringWriterDemo {
public static void main(String[] args) throws IOException {
char[] ary = new char[1024];
StringWriter writer = new StringWriter();
FileInputStream input = null;
BufferedReader buffer = null;
input = new FileInputStream("c://stringwriter.txt");
buffer = new BufferedReader(new InputStreamReader(input, "UTF-8"));
int x;
while ((x = buffer.read(ary)) != -1) {
writer.write(ary, 0, x);
}
System.out.println(writer.toString());
writer.close();
buffer.close();
}
}
The above example helps us to know simple example of StringWriter using BufferedReader to
read file data from the stream.
https://riptutorial.com/ 898
Chapter 140: Recursion
Introduction
Recursion occurs when a method calls itself. Such a method is called recursive. A recursive
method may be more concise than an equivalent non-recursive approach. However, for deep
recursion, sometimes an iterative solution can consume less of a thread's finite stack space.
Remarks
• Base Case. This will define when your recursion will stop and output the result. The base
case in the factorial example is:
if (n <= 1) {
return 1;
}
• Recursive Call. In this statement you re-call the method with a changed parameter. The
recursive call in the factorial example above is:
else {
return n * factorial(n - 1);
}
Output
In this example you compute the n-th factorial number. The first factorials are:
0! = 1
1! = 1
2! = 1 x 2 = 2
3! = 1 x 2 x 3 = 6
4! = 1 x 2 x 3 x 4 = 24
...
https://riptutorial.com/ 899
Java and Tail-call elimination
Current Java compilers (up to and including Java 9) do not perform tail-call elimination. This can
impact the performance of recursive algorithms, and if the recursion is deep enough, it can lead to
StackOverflowError crashes; see Deep recursion is problematic in Java
Examples
The basic idea of recursion
What is recursion:
In general, recursion is when a function invokes itself, either directly or indirectly. For example:
There are two preconditions for using recursive functions to solving a specific problem:
1. There must be a base condition for the problem, which will be the endpoint for the recursion.
When a recursive function reaches the base condition, it makes no further (deeper) recursive
calls.
2. Each level of recursion should be attempting a smaller problem. The recursive function thus
divides the problem into smaller and smaller parts. Assuming that the problem is finite, this
will ensure that the recursion terminates.
In Java there is a third precondition: it should not be necessary to recurse too deeply to solve the
problem; see Deep recursion is problematic in Java
Example
The following function calculates factorials using recursion. Notice how the method factorial calls
itself within the function. Each time it calls itself, it reduces the parameter n by 1. When n reaches
1 (the base condition) the function will recurse no deeper.
This is not a practical way of computing factorials in Java, since it does not take account of integer overflow, or call
https://riptutorial.com/ 900
stack overflow (i.e. StackOverflowError exceptions) for large values of n.
The following method computes the Nth Fibonacci number using recursion.
The method implements a base case (n <= 2) and a recursive case (n>2). This illustrates the use
of recursion to compute a recursive relation.
However, while this example is illustrative, it is also inefficient: each single instance of the method
will call the function itself twice, leading to an exponential growth in the number of times the
function is called as N increases. The above function is O(2N), but an equivalent iterative solution
has complexity O(N). In addition, there is a "closed form" expression that can be evaluated in O(N)
floating-point multiplications.
The following method computes the sum of integers from 0 to N using recursion.
This method is O(N) and can be reduced to a simple loop using tail-call optimization. In fact there
is a closed form expression that computes the sum in O(1) operations.
The following method computes the value of num raised to the power of exp using recursion:
This illustrates the principles mentioned above: the recursive method implements a base case
https://riptutorial.com/ 901
(two cases, n = 0 and n = 1) that terminates the recursion, and a recursive case that calls the
method again. This method is O(N) and can be reduced to a simple loop using tail-call
optimization.
/**
* Just a snippet to explain the idea of recursion
*
**/
Consider the Node class having 3 members data, left child pointer and right child pointer like
below.
We can traverse the tree constructed by connecting multiple Node class's object like below, the
traversal is called in-order traversal of tree.
https://riptutorial.com/ 902
As demonstrated above, using recursion we can traverse the tree data structure without using
any other data structure which is not possible with the iterative approach.
Types of Recursion
Recursion can be categorized as either Head Recursion or Tail Recursion, depending on where
the recursive method call is placed.
In head recursion, the recursive call, when it happens, comes before other processing in the
function (think of it happening at the top, or head, of the function).
In tail recursion, it’s the opposite—the processing occurs before the recursive call. Choosing
between the two recursive styles may seem arbitrary, but the choice can make all the difference.
A function with a path with a single recursive call at the beginning of the path uses what is called
head recursion. The factorial function of a previous exhibit uses head recursion. The first thing it
does once it determines that recursion is needed is to call itself with the decremented parameter.
A function with a single recursive call at the end of a path is using tail recursion.
tail(n-1); System.out.println(n);
} }
If the recursive call occurs at the end of a method, it is called a tail recursion. The tail recursion is
similar to a loop. The method executes all the statements before jumping into the next recursive
call.
If the recursive call occurs at the beginning of a method, it is called a head recursion. The method
saves the state before jumping into the next recursive call.
If a recursive call goes "too deep", this results in a StackOverflowError. Java allocates a new frame
for every method call on its thread's stack. However, the space of each thread's stack is limited.
Too many frames on the stack leads to the Stack Overflow (SO).
Example
https://riptutorial.com/ 903
}
Calling this method with large parameters (e.g. recursion(50000) probably will result in a stack
overflow. The exact value depends on the thread stack size, which in turn depends on the thread
construction, command-line parameters such as -Xss, or the default size for the JVM.
Workaround
A recursion can be converted to a loop by storing the data for each recursive call in a data
structure. This data structure can be stored on the heap rather than on the thread stack.
In general the data required to restore the state of a method invocation can be stored in a stack
and a while loop can be used to "simulate" the recursive calls. Data that may be required include:
• the object the method was called for (instance methods only)
• the method parameters
• local variables
• the current position in the execution or the method
Example
The following class allows recursive of a tree structure printing up to a specified depth.
https://riptutorial.com/ 904
}
e.g.
Node n = new Node(10, new Node(20, new Node(50), new Node(1)), new Node(30, new Node(42),
null));
n.print(2);
System.out.println();
Prints
(((...)20(...))10((...)30))
while (!stack.isEmpty()) {
// get topmost stack element
int index = stack.size() - 1;
Frame frame = stack.get(index); // get topmost frame
if (frame.maxDepth <= 0) {
// termial case (too deep)
System.out.print("(...)");
stack.remove(index); // drop frame
} else {
switch (frame.state) {
case 0:
frame.state++;
https://riptutorial.com/ 905
case 1:
frame.state++;
Note: This is just an example of the general approach. Often you can come up with a much better
way to represent a frame and/or store the frame data.
Consider the following naive method for adding two positive numbers using recursion:
This is algorithmically correct, but it has a major problem. If you call add with a large a, it will crash
with a StackOverflowError, on any version of Java up to (at least) Java 9.
In a typical functional programming language (and many other languages) the compiler optimizes
tail recursion. The compiler would notice that the call to add (at the tagged line) is a tail call, and
would effectively rewrite the recursion as a loop. This transformation is called tail-call elimination.
However, current generation Java compilers do not perform tail call elimination. (This is not a
simple oversight. There are substantial technical reasons for this; see below.) Instead, each
recursive call of add causes a new frame to be allocated on the thread's stack. For example, if you
call add(1000, 1), it will take 1000 recursive calls to arrive at the answer 1001.
The problem is that the size of Java thread stack is fixed when the thread is created. (This
includes the "main" thread in a single-threaded program.) If too many stack frames are allocated
the stack will overflow. The JVM will detect this and throw a StackOverflowError.
One approach to dealing with this is to simply use a bigger stack. There are JVM options that
control the default size of a stack, and you can also specify the stack size as a Thread constructor
parameter. Unfortunately, this only "puts off" the stack overflow. If you need to do a computation
https://riptutorial.com/ 906
that requires an even larger stack, then the StackOverflowError comes back.
The real solution is to identify recursive algorithms where deep recursion is likely, and manually
perform the tail-call optimization at the source code level. For example, our add method can be
rewritten as follows:
(Obviously, there are better ways to add two integers. The above is simply to illustrate the effect of
manual tail-call elimination.)
• Some code could rely on StackOverflowError to (for example) place a bound on the size of a
computational problem.
• Sandbox security managers often rely on analyzing the call stack when deciding whether to
allow non-privileged code to perform a privileged action.
"The effects of removing the caller’s stack frame are visible to some APIs, notably
access control checks and stack tracing. It is as if the caller’s caller had directly called
the callee. Any privileges possessed by the caller are discarded after control is
transferred to the callee. However, the linkage and accessibility of the callee method
are computed before the transfer of control, and take into account the tail-calling
caller."
In other words, tail-call elimination could cause an access control method to mistakenly think that
a security sensitive API was was being called by trusted code.
https://riptutorial.com/ 907
Chapter 141: Reference Data Types
Examples
Instantiating a reference type
Where:
What happens:
int i = 10;
Dereferencing
Dereferencing follows the memory address stored in a reference, to the place in memory where
the actual object resides. When an object has been found, the requested method is called (
toString in this case).
null indicates the absence of a value, i.e. following the memory address leads nowhere. So there
is no object on which the requested method can be called.
https://riptutorial.com/ 908
Read Reference Data Types online: https://riptutorial.com/java/topic/1046/reference-data-types
https://riptutorial.com/ 909
Chapter 142: Reference Types
Examples
Different Reference Types
• Strong Reference
• Weak Reference
• Soft Reference
• Phantom Reference
1. Strong Reference
The variable holder is holding a strong reference to the object created. As long as this variable is
live and holds this value, the MyObject instance will not be collected by the garbage collector.
2. Weak Reference
When you do not want to keep an object longer, and you need to clear/free the memory allocated
for an object as soon as possible, this is the way to do so.
Simply, a weak reference is a reference that isn't strong enough to force an object to remain in
memory. Weak references allow you to leverage the garbage collector's ability to determine
reachability for you, so you don't have to do it yourself.
When you need the object you created, just use .get() method:
myObjectRef.get();
https://riptutorial.com/ 910
3. Soft Reference
Soft references are slightly stronger than weak references. You can create a soft referenced
object as following:
They can hold onto the memory more strongly than the weak reference. If you have enough
memory supply/resources, garbage collector will not clean the soft references as enthusiastically
as weak references.
Soft references are handy to use in caching. You can create soft referenced objects as a cache,
where they kept until your memory runs out. When your memory can't supply enough resources,
garbage collector will remove soft references.
4. Phantom Reference
This is the weakest referencing type. If you created an object reference using Phantom Reference,
the get() method will always return null!
The use of this referencing is that "Phantom reference objects, which are enqueued after the
collector determines that their referents may otherwise be reclaimed. Phantom references are
most often used for scheduling pre-mortem cleanup actions in a more flexible way than is possible
with the Java finalization mechanism." - From Phantom Reference Javadoc from Oracle.
https://riptutorial.com/ 911
Chapter 143: Reflection API
Introduction
Reflection is commonly used by programs which require the ability to examine or modify the
runtime behavior of applications running in the JVM. Java Reflection API is used for that purpose
where it makes it possible to inspect classes, interfaces, fields and methods at runtime, without
knowing their names at compile time. And It also makes it possible to instantiate new objects, and
to invoke methods using reflection.
Remarks
Performance
Keep in mind that reflection might decrease performance, only use it when your task cannot be
completed without reflection.
Because reflection involves types that are dynamically resolved, certain Java virtual
machine optimizations can not be performed. Consequently, reflective operations have
slower performance than their non-reflective counterparts, and should be avoided in
sections of code which are called frequently in performance-sensitive applications.
Examples
Introduction
Basics
The Reflection API allows one to check the class structure of the code at runtime and invoke code
dynamically. This is very powerful, but it is also dangerous since the compiler is not able to
statically determine whether dynamic invocations are valid.
A simple example would be to get the public constructors and methods of a given class:
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
https://riptutorial.com/ 912
With this information it is possible to instance the object and call different methods dynamically.
The following example shows how to extract the generic type information in all three cases:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
System.out.println("Method parameter:");
final Type parameterType = method.getGenericParameterTypes()[0];
displayGenericType(parameterType, "\t");
System.out.println("Field type:");
final Type fieldType = field.getGenericType();
displayGenericType(fieldType, "\t");
https://riptutorial.com/ 913
Method parameter:
java.util.Map<java.lang.String, java.lang.Double>
java.lang.String
java.lang.Double
Method return type:
java.util.List<java.lang.Number>
java.lang.Number
Field type:
java.util.Map<java.lang.String, java.util.Map<java.lang.Integer,
java.util.List<java.lang.String>>>
java.lang.String
java.util.Map<java.lang.Integer, java.util.List<java.lang.String>>
java.lang.Integer
java.util.List<java.lang.String>
java.lang.String
Invoking a method
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Using the Reflection API, it is possible to change or get the value of a field at runtime. For
example, you could use it in an API to retrieve different fields based on a factor, like the OS. You
can also remove modifiers like final to allow modifing fields that are final.
To do so, you will need to use the method Class#getField() in a way such as the one shown
below:
// Get the field in class Field "modifiers". Note that it does not
// need to be static
Field modifiersField = Field.class.getDeclaredField("modifiers");
https://riptutorial.com/ 914
// Get the modifiers on the "NAME" field as an int.
int existingModifiersOnNameField = nameField.getModifiers();
// Set the value of the modifiers field under an object for non-static fields
modifiersField.setInt(nameField, newModifiersOnNameField);
// Here I can directly access it. If needed, use reflection to get it. (Below)
System.out.println(SomeClass.NAME);
Getting fields is much easier. We can use Field#get() and its variants to get its value:
Do note this:
class Hacked {
public String someState;
}
Call constructor
https://riptutorial.com/ 915
Class myClass = ... // get a class object
Constructor[] constructors = myClass.getConstructors();
Where the constructors variable will have one Constructor instance for each public constructor
declared in the class.
If you know the precise parameter types of the constructor you want to access, you can filter the
specific constructor. The next example returns the public constructor of the given class which
takes a Integer as parameter:
enum Compass {
NORTH(0),
EAST(90),
SOUTH(180),
WEST(270);
private int degree;
Compass(int deg){
degree = deg;
}
public int getDegree(){
return degree;
}
}
In Java an enum class is like any other class but has some definied constants for the enum
values. Additionally it has a field that is an array that holds all the values and two static methods
with name values() and valueOf(String).
We can see this if we use Reflection to print all fields in this class
for(Field f : Compass.class.getDeclaredFields())
System.out.println(f.getName());
NORTH
https://riptutorial.com/ 916
EAST
SOUTH
WEST
degree
ENUM$VALUES
So we could examine enum classes with Reflection like any other class. But the Reflection API
offers three enum-specific methods.
enum check
Compass.class.isEnum();
retrieving values
Returns an array of all enum values like Compass.values() but without the need of an instance.
for(Field f : Compass.class.getDeclaredFields()){
if(f.isEnumConstant())
System.out.println(f.getName());
}
Given a String containing the name of a class, it's Class object can be accessed using
Class.forName:
Java SE 1.2
It can be specified, if the class should be initialized (second parameter of forName) and which
ClassLoader should be used (third parameter):
https://riptutorial.com/ 917
try {
clazz = Class.forName("java.lang.Integer", initialize, classLoader);
} catch (ClassNotFoundException ex) {
throw new IllegalStateException(ex);
}
import java.lang.reflect.*;
class NewInstanceWithReflection{
public NewInstanceWithReflection(){
System.out.println("Default constructor");
}
public NewInstanceWithReflection( String a){
System.out.println("Constructor :String => "+a);
}
public static void main(String args[]) throws Exception {
NewInstanceWithReflection object =
(NewInstanceWithReflection)Class.forName("NewInstanceWithReflection").newInstance();
Constructor constructor = NewInstanceWithReflection.class.getDeclaredConstructor( new
Class[] {String.class});
NewInstanceWithReflection object1 =
(NewInstanceWithReflection)constructor.newInstance(new Object[]{"StackOverFlow"});
}
}
output:
Default constructor
Constructor :String => StackOverFlow
Explanation:
Reflection is useful when it is properly used for right purpose. By using reflection, you can access
private variables and re-initialize final variables.
import java.lang.reflect.*;
https://riptutorial.com/ 918
try{
Field[] fields = A.class.getDeclaredFields();
A a = new A();
for ( Field field:fields ) {
if(field.getName().equalsIgnoreCase("name")){
field.setAccessible(true);
field.set(a, "StackOverFlow");
System.out.println("A.name="+field.get(a));
}
if(field.getName().equalsIgnoreCase("age")){
field.set(a, 20);
System.out.println("A.age="+field.get(a));
}
if(field.getName().equalsIgnoreCase("rep")){
field.setAccessible(true);
field.set(a,"New Reputation");
System.out.println("A.rep="+field.get(a));
}
if(field.getName().equalsIgnoreCase("count")){
field.set(a,25);
System.out.println("A.count="+field.get(a));
}
}
}catch(Exception err){
err.printStackTrace();
}
}
}
class A {
private String name;
public int age;
public final String rep;
public static int count=0;
public A(){
name = "Unset";
age = 0;
rep = "Reputation";
count++;
}
}
Output:
A.name=StackOverFlow
A.age=20
A.rep=New Reputation
A.count=25
Explanation:
In normal scenario, private variables can't be accessed outside of declared class ( without getter
and setter methods). final variables can't be re-assigned after initialization.
Reflectionbreaks both barriers can be abused to change both private and final variables as
explained above.
https://riptutorial.com/ 919
field.setAccessible(true) is the key to achieve desired functionality.
If you want to create an instance of an inner nested class you need to provide a class object of the
enclosing class as an extra parameter with Class#getDeclaredConstructor.
If the nested class is static you will not need this enclosing instance.
Dynamic Proxies
Dynamic Proxies do not really have much to do with Reflection but they are part of the API. It's
basically a way to create a dynamic implementation of an interface. This could be helpful when
creating mockup services.
A Dynamic Proxy is an instance of an interface that is created with a so-called invocation handler
that intercepts all method calls and allows the handling of their invocation manually.
https://riptutorial.com/ 920
InvocationHandler handler = new InvocationHandler(){
// this method is invoked for every proxy method call
// method is the invoked method, args holds the method parameters
// it must return the method result
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
String methodName = method.getName();
if(methodName.equals("someMethod1")){
System.out.println("someMethod1 was invoked!");
return null;
}
if(methodName.equals("someMethod2")){
System.out.println("someMethod2 was invoked!");
System.out.println("Parameter: " + args[0]);
return 42;
}
if(methodName.equals("anotherMethod")){
System.out.println("anotherMethod was invoked!");
return null;
}
System.out.println("Unkown method!");
return null;
}
};
The Reflection API could be used to change values of private and final fields even in the JDK
default library. This could be used to manipulate the behaviour of some well known classes as we
will see.
Lets start first with the only limitation means the only field we can't change with Reflection. That is
the Java SecurityManager. It is declared in java.lang.System as
https://riptutorial.com/ 921
private static volatile SecurityManager security = null;
for(Field f : System.class.getDeclaredFields())
System.out.println(f);
Thats because of the fieldFilterMap in sun.reflect.Reflection that holds the map itself and the
security field in the System.class and protects them against any access with Reflection. So we
could not deactivate the SecurityManager.
Crazy Strings
Each Java String is represented by the JVM as an instance of the String class. However, in some
situations the JVM saves heap space by using the same instance for Strings that are. This
happens for string literals, and also for strings that have been "interned" by calling String.intern().
So if you have "hello" in your code multiple times it is always the same object instance.
Strings are supposed to be immutable, but it is possible to use "evil" reflection to change them.
The example below show how we can change the characters in a String by replacing its value
field.
1 = 42
https://riptutorial.com/ 922
}
}
Everything is true
And according to this stackoverflow post we can use reflection to do something really evil.
Note that what we are doing here is going to cause the JVM to behave in inexplicable ways. This
is very dangerous.
https://riptutorial.com/ 923
Chapter 144: Regular Expressions
Introduction
A regular expression is a special sequence of characters that helps in matching or finding other
strings or sets of strings, using a specialized syntax held in a pattern. Java has support for regular
expression usage through the java.util.regex package. This topic is to introduce and help
developers understand more with examples on how Regular Expressions must be used in Java.
Syntax
• Pattern patternName = Pattern.compile(regex);
• Matcher matcherName = patternName.matcher(textToSearch);
• matcherName.matches() //Returns true if the textToSearch exactly matches the regex
• matcherName.find() //Searches through textToSearch for first instance of a substring
matching the regex. Subsequent calls will search the remainder of the String.
• matcherName.group(groupNum) //Returns the substring inside of a capturing group
• matcherName.group(groupName) //Returns the substring inside of a named capturing group
(Java 7+)
Remarks
Imports
You will need to add the following imports before you can use Regex:
import java.util.regex.Matcher
import java.util.regex.Pattern
Pitfalls
In java, a backslash is escaped with a double backslash, so a backslash in the regex string should
be inputted as a double backslash. If you need to escape a double backslash (to match a single
backslash with the regex, you need to input it as a quadruple backslash.
https://riptutorial.com/ 924
Character Description
Further reading
The regex topic contains more information about regular expressions.
Examples
Using capture groups
If you need to extract a part of string from the input string, we can use capture groups of regex.
For this example, we'll start with a simple phone number regex:
\d{3}-\d{3}-\d{4}
If parentheses are added to the regex, each set of parentheses is considered a capturing group. In
this case, we are using what are called numbered capture groups:
(\d{3})-(\d{3})-(\d{4})
^-----^ ^-----^ ^-----^
Group 1 Group 2 Group 3
Before we can use it in Java, we must not forget to follow the rules of Strings, escaping the
backslashes, resulting in the following pattern:
"(\\d{3})-(\\d{3})-(\\d{4})"
We first need to compile the regex pattern to make a Pattern and then we need a Matcher to match
our input string with the pattern:
Next, the Matcher needs to find the first subsequence that matches the regex:
phoneMatcher.find();
Now, using the group method, we can extract the data from the string:
https://riptutorial.com/ 925
String number = phoneMatcher.group(0); //"800-555-1234" (Group 0 is everything the regex
matched)
String aCode = phoneMatcher.group(1); //"800"
String threeDigit = phoneMatcher.group(2); //"555"
String fourDigit = phoneMatcher.group(3); //"1234"
Java SE 7
Java 7 introduced named capture groups. Named capture groups function the same as numbered
capture groups (but with a name instead of a number), although there are slight syntax changes.
Using named capture groups improves readability.
(?<AreaCode>\d{3})-(\d{3})-(\d{4})
^----------------^ ^-----^ ^-----^
AreaCode Group 2 Group 3
Using regex with custom behaviour by compiling the Pattern with flags
A Pattern can be compiled with flags, if the regex is used as a literal String, use inline modifiers:
/* Had the regex not been compiled case insensitively and singlelined,
* it would fail because FOO does not match /foo/ and \n (newline)
* does not match /./.
*/
Escape Characters
Generally
To use regular expression specific characters (?+| etc.) in their literal meaning they need to be
escaped. In common regular expression this is done by a backslash \. However, as it has a
special meaning in Java Strings, you have to use a double backslash \\.
https://riptutorial.com/ 926
"???".replaceAll ("?", "!"); //java.util.regex.PatternSyntaxException
"???".replaceAll ("\?", "!"); //Invalid escape sequence
Escaping backslash \
"\\".matches("\\"); // PatternSyntaxException
"\\".matches("\\\"); // Syntax Error
This works:
"\\".matches("\\\\"); // true
If you need to match characters that are a part of the regular expression syntax you can mark all
or part of the pattern as a regex literal.
\Q marks the beginning of the regex literal. \E marks the end of the regex literal.
// wrapping the bracket in \Q and \E allows the pattern to match as you would expect.
"[123".matches("\\Q[\\E123"); // returns true
An easier way of doing it without having to remember the \Q and \E escape sequences is to use
Pattern.quote()
https://riptutorial.com/ 927
To match something that does not contain a given string, one can use negative lookahead:
Example:
Output:
[popcorn] nope!
[unicorn] matched!
Matching a backslash
If you want to match a backslash in your regular expression, you'll have to escape it.
Backslash is an escape character in regular expressions. You can use '\\' to refer to a single
backslash in a regular expression.
However, backslash is also an escape character in Java literal strings. To make a regular
expression from a string literal, you have to escape each of its backslashes. In a string literal '\\\\'
can be used to create a regular expression with '\\', which in turn can match '\'.
For example, consider matching strings like "C:\dir\myfile.txt". A regular expression ([A-Za-
z]):\\(.*) will match, and provide the drive letter as a capturing group. Note the doubled
backslash.
To express that pattern in a Java string literal, each of the backslashes in the regular expression
needs to be escaped.
If you want to match two backslashes, you'll find yourself using eight in a literal string, to represent
four in the regular expression, to match two.
https://riptutorial.com/ 928
System.out.println( "UNC path: " + path ); // \\myhost\share\myfile.txt"
if ( matcher.matches()) {
System.out.println( "This path is on host '" + matcher.group( 1 ) + "'.");
// This path is on host 'myhost'.
}
https://riptutorial.com/ 929
Chapter 145: Remote Method Invocation
(RMI)
Remarks
RMI requires 3 components: client, server and a shared remote interface. The shared remote
interface defines the client-server contract by specifying the methods a server must implement.
The interface must be visible to the server so that it can implement the methods; the interface
must be visible to the client so that it knows which methods ("services") the server provides.
Any object implementing a remote interface is destined to take the role of a server. As such, a
client-server relationship in which the server can also invoke methods in the client is in fact a
server-server relationship. This is termed callback since the server can call back the "client". With
this in mind, it is acceptable to use the designation client for the servers that function as such.
The shared remote interface is any interface extending Remote. An object that functions as a server
undergoes the following:
In the project setup, the client and server projects are completely unrelated, but each specifies a
shared project in its build path. The shared project contains the remote interfaces.
Examples
Client-Server: invoking methods in one JVM from another
package remote;
import java.rmi.Remote;
import java.rmi.RemoteException;
https://riptutorial.com/ 930
package server;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import remote.RemoteServer;
@Override
public int stringToInt(String string) throws RemoteException {
try {
Registry reg = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
Server server = new Server();
UnicastRemoteObject.exportObject(server, Registry.REGISTRY_PORT);
reg.rebind("ServerName", server);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
package client;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import remote.RemoteServer;
try {
Registry reg = LocateRegistry.getRegistry();
server = (RemoteServer) reg.lookup("ServerName");
} catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
void callServer() {
https://riptutorial.com/ 931
try {
int i = server.stringToInt("120");
System.out.println("Client received: " + i);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
Output:
Overview
In this example 2 clients send information to each other through a server. One client sends the
server a number which is relayed to the second client. The second client halves the number and
sends it back to the first client through the server. The first client does the same. The server stops
the communication when the number returned to it by any of the clients is less than 10. The return
value from the server to the clients (the number it got converted to string representation) then
backtracks the process.
package callbackRemote;
import java.rmi.Remote;
import java.rmi.RemoteException;
https://riptutorial.com/ 932
The server:
package callbackRemote;
import java.rmi.Remote;
import java.rmi.RemoteException;
The client:
package callbackRemote;
import java.rmi.Remote;
import java.rmi.RemoteException;
The implementations
package callbackServer;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
import callbackRemote.RemoteClient;
import callbackRemote.RemoteConnection;
import callbackRemote.RemoteLogin;
@Override
public RemoteConnection login(String name, RemoteClient client) {
https://riptutorial.com/ 933
try {
Registry reg = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
LoginServer server = new LoginServer();
UnicastRemoteObject.exportObject(server, Registry.REGISTRY_PORT);
reg.rebind("LoginServerName", server);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
The server:
package callbackServer;
import java.rmi.NoSuchObjectException;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.Unreferenced;
import callbackRemote.RemoteClient;
import callbackRemote.RemoteConnection;
RemoteClient client;
String name;
this.client = client;
this.name = name;
try {
UnicastRemoteObject.exportObject(this, Registry.REGISTRY_PORT);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void unreferenced() {
try {
UnicastRemoteObject.unexportObject(this, true);
} catch (NoSuchObjectException e) {
e.printStackTrace();
}
}
@Override
public void logout() {
try {
UnicastRemoteObject.unexportObject(this, true);
} catch (NoSuchObjectException e) {
e.printStackTrace();
}
}
https://riptutorial.com/ 934
@Override
public String passInt(String recipient, int i) {
The client:
package callbackClient;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import callbackRemote.RemoteClient;
import callbackRemote.RemoteConnection;
import callbackRemote.RemoteLogin;
RemoteConnection connection;
String name, target;
this.name = name;
this.target = target;
}
if ("Client1".equals(client.name)) {
try {
client.connection.passInt(client.target, 120);
} catch (RemoteException e) {
e.printStackTrace();
}
https://riptutorial.com/ 935
}
}
@Override
public void half(int i) throws RemoteException {
The outputs will appear in 3 consoles since there are 3 JVMs. here they are lumped together:
Client2 logged in
Client1 logged in
Server received from Client1:120
Server received from Client2:60
Server received from Client1:30
Server received from Client2:15
Server received from Client1:7
Client1 received: "7"
Client2 received: "15"
Client1 received: "30"
Client2 received: "60"
This is a simple RMI example with five Java classes and two packages, server and client.
Server Package
PersonListInterface.java
PersonListImplementation.java
https://riptutorial.com/ 936
public class PersonListImplementation
extends UnicastRemoteObject
implements PersonListInterface
{
/**
* Implementation of "PersonListInterface"
* @throws RemoteException
*/
@Override
public ArrayList<String> getPersonList() throws RemoteException
{
ArrayList<String> personList = new ArrayList<String>();
personList.add("Peter Pan");
personList.add("Pippi Langstrumpf");
// add your name here :)
return personList;
}
}
Server.java
/**
* Register servicer to the known public methods
*/
private static void createServer() {
try {
// Register registry with standard port 1099
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
System.out.println("Server : Registry created.");
Client package
PersonListLocal.java
https://riptutorial.com/ 937
public class PersonListLocal {
private static PersonListLocal instance;
private PersonListInterface personList;
/**
* Create a singleton instance
*/
private PersonListLocal() {
try {
// Lookup to the local running server with port 1099
final Registry registry = LocateRegistry.getRegistry("localhost",
Registry.REGISTRY_PORT);
return instance;
}
/**
* Returns the servers PersonList
*/
public ArrayList<String> getPersonList() {
if (instance != null) {
try {
return personList.getPersonList();
} catch (final RemoteException e) {
e.printStackTrace();
}
}
PersonTest.java
https://riptutorial.com/ 938
}
}
Peter Pan
Pippi Langstrumpf
https://riptutorial.com/ 939
Chapter 146: Resources (on classpath)
Introduction
Java allows the retrieval of file-based resources stored inside of a JAR alongside compiled
classes. This topic focuses on loading those resources and making them available to your code.
Remarks
A resource is file-like data with a path-like name, which resides in the classpath. The most
common use of resources is bundling application images, sounds, and read-only data (such as
default configuration).
The only difference between a getResource method and getResourceAsStream method is that the
former returns a URL, while the latter opens that URL and returns an InputStream.
The methods of ClassLoader accept a path-like resource name as an argument and search each
location in the ClassLoader’s classpath for an entry matching that name.
• If a classpath location is a .jar file, a jar entry with the specified name is considered a match.
• If a classpath location is a directory, a relative file under that directory with the specified
name is considered a match.
The resource name is similar to the path portion of a relative URL. On all platforms, it uses forward
slashes (/) as directory separators. It must not start with a slash.
• The resource name may start with a slash, in which case that initial slash is removed and the
rest of the name is passed to the corresponding method of ClassLoader.
• If the resource name does not start with a slash, it is treated as relative to the class whose
getResource or getResourceAsStream method is being called. The actual resource name
becomes package/name, where package is the name of the package to which the class
belongs, with each period replaced by a slash, and name is the original argument given to
the method.
For instance:
package com.example;
https://riptutorial.com/ 940
throws IOException {
Resources should be placed in named packages, rather than in the root of a .jar file, for the same
reason classes are placed in packages: To prevent collisions among multiple vendors. For
example, if multiple .jar files are in the classpath, and more than one of them contains a
config.properties entry in its root, calls to the getResource or getResourceAsStream methods will
return the config.properties from whichever .jar is listed first in the classpath. This is not
predictable behavior in environments where the classpath order is not under the direct control of
the application, such as Java EE.
All getResource and getResourceAsStream methods return null if the specified resource does not
exist. Since resources must be added to the application at build time, their locations should be
known when the code is being written; a failure to find a resource at runtime is usually the result of
programmer error.
Resources are read-only. There is no way to write to a resource. Novice developers often make
the mistake of assuming that since the resource is a separate physical file when developing in an
IDE (like Eclipse), it will be safe to treat it like a separate physical file in the general case.
However, this is not correct; applications are almost always distributed as archives such as .jar or
.war files, and in such cases, a resource will not be a separate file and will not be writable. (The
getFile method of the URL class is not a workaround for this; despite its name, it merely returns
the path portion of a URL, which is by no means guaranteed to be a valid filename.)
There is no safe way to list resources at runtime. Again, since the developers are responsible for
adding resource files to the application at build time, developers should already know their paths.
While there are workarounds, they are not reliable and will eventually fail.
Examples
Loading an image from a resource
package com.example;
https://riptutorial.com/ 941
Loading default configuration
package com.example;
defaults.load(defaultsStream);
}
return defaults;
}
}
Resource with same path and name may exist in more than one JAR file on the classpath.
Common cases are resources following a convention or that are part of a packaging specification.
Examples for such resources are
• META-INF/MANIFEST.MF
• META-INF/beans.xml (CDI Spec)
• ServiceLoader properties containing implementation providers
To get access to all of these resources in different jars, one has to use a ClassLoader, which has
a method for this. The returned Enumeration can be conveniently converted to a List using a
Collections function.
The last three steps are typically accomplished by passing the URL to a library method or
constructor to load the resource. You will typically use a getResource method in this case. It is also
possible to read the resource data in application code. You will typically use getResourceAsStream in
https://riptutorial.com/ 942
this case.
As the Classpath examples describe, a JVM's classpath defines a namespace by overlaying the
namespaces of the directories and JAR or ZIP files in the classpath. When an absolute path is
resolved, it the classloaders interpret the initial / as meaning the root of the namespace. By
contrast, a relative path may be resolved relative to any "folder" in the namespace. The folder
used will depend on the object that you use to resolve the path.
• A class literal will give you the Class object for any class that you can name in Java source
code; e.g. String.class gives you the Class object for the String type.
• The Object.getClass() will give you the Class object for the type od any object; e.g.
"hello".getClass() is another way to get Class of the String type.
• The Class.forName(String) method will (if necessary) dynamically load a class and return its
Class object; e.g. Class.forName("java.lang.String").
Methods Description
https://riptutorial.com/ 943
Methods Description
Notes:
• The main difference between the ClassLoader and Class versions of the methods is in the way
that relative paths are interpreted.
○ The Class methods resolve a relative path in the "folder" that corresponds to the
classes package.
○ The ClassLoader methods treat relative paths as if they were absolute; i.e. the resolve
them in the "root folder" of the classpath namespace.
• If the requested resource (or resources) cannot be found, the getResource and
getResourceAsStreammethods returnnull, and thegetResourcesmethods return an empty
Enumeration`.
• The URLs returned will be resolvable using URL.toStream(). They could be file: URLs or
other conventional URLs, but if the resource resides in a JAR file, they will be jar: URLs that
identify the JAR file and a specific resource within it.
https://riptutorial.com/ 944
Chapter 147: RSA Encryption
Examples
An example using a hybrid cryptosystem consisting of OAEP and GCM
The following example encrypts data by using a hybrid cryptosystem consisting of AES GCM and
OAEP, using their default parameter sizes and an AES key size of 128 bits.
OAEP is less vulnerable to padding oracle attacks than PKCS#1 v1.5 padding. GCM is also
protected against padding oracle attacks.
Decryption can be performed by first retrieving the length of the encapsulated key and then by
retrieving the encapsulated key. The encapsulated key can then be decrypted using the RSA
private key that forms a key pair with the public key. After that the AES/GCM encrypted ciphertext
can be decrypted to the original plaintext.
1. a length field for the wrapped key (RSAPrivateKey misses a getKeySize() method);
2. the wrapped/encapsulated key, of the same size as the RSA key size in bytes;
3. the GCM ciphertext and 128 bit authentication tag (automatically added by Java).
Notes:
• To correctly use this code you should supply an RSA key of at least 2048 bits, bigger is
better (but slower, especially during decryption);
• To use AES-256 you should install the unlimited cryptography policy files first;
• Instead creating your own protocol you might want to use a container format such as the
Cryptographic Message Syntax (CMS / PKCS#7) or PGP instead.
/**
* Encrypts the data using a hybrid crypto-system which uses GCM to encrypt the data and OAEP
to encrypt the AES key.
* The key size of the AES encryption will be 128 bit.
* All the default parameter choices are used for OAEP and GCM.
*
* @param publicKey the RSA public key used to wrap the AES key
* @param plaintext the plaintext to be encrypted, not altered
* @return the ciphertext
* @throws InvalidKeyException if the key is not an RSA public key
* @throws NullPointerException if the plaintext is null
*/
public static byte[] encryptData(PublicKey publicKey, byte[] plaintext)
throws InvalidKeyException, NullPointerException {
https://riptutorial.com/ 945
Cipher oaep;
try {
// SHA-1 is the default and not vulnerable in this setting
// use OAEPParameterSpec to configure more than just the hash
oaep = Cipher.getInstance("RSA/ECB/OAEPwithSHA1andMGF1Padding");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(
"Runtime doesn't have support for RSA cipher (mandatory algorithm for
runtimes)", e);
} catch (NoSuchPaddingException e) {
throw new RuntimeException(
"Runtime doesn't have support for OAEP padding (present in the standard Java
runtime sinze XX)", e);
}
oaep.init(Cipher.WRAP_MODE, publicKey);
KeyGenerator aesKeyGenerator;
try {
aesKeyGenerator = KeyGenerator.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(
"Runtime doesn't have support for AES key generator (mandatory algorithm for
runtimes)", e);
}
// for AES-192 and 256 make sure you've got the rights (install the
// Unlimited Crypto Policy files)
aesKeyGenerator.init(128);
SecretKey aesKey = aesKeyGenerator.generateKey();
byte[] wrappedKey;
try {
wrappedKey = oaep.wrap(aesKey);
} catch (IllegalBlockSizeException e) {
throw new RuntimeException(
"AES key should always fit OAEP with normal sized RSA key", e);
}
Cipher aesGCM;
try {
aesGCM = Cipher.getInstance("AES/GCM/Nopadding");
// we can get away with a zero nonce since the key is randomly generated
// 128 bits is the recommended (maximum) value for the tag size
// 12 bytes (96 bits) is the default nonce size for GCM mode encryption
GCMParameterSpec staticParameterSpec = new GCMParameterSpec(128, new byte[12]);
aesGCM.init(Cipher.ENCRYPT_MODE, aesKey, staticParameterSpec);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(
"Runtime doesn't have support for AES cipher (mandatory algorithm for
runtimes)", e);
} catch (NoSuchPaddingException e) {
https://riptutorial.com/ 946
throw new RuntimeException(
"Runtime doesn't have support for GCM (present in the standard Java runtime
sinze XX)", e);
} catch (InvalidAlgorithmParameterException e) {
throw new RuntimeException(
"IvParameterSpec not accepted by this implementation of GCM", e);
}
// --- create a buffer of the right size for our own protocol ---
// - element 1: make sure that we know the size of the wrapped key
ciphertextBuffer.putShort((short) wrappedKey.length);
return ciphertextBuffer.array();
}
Of course, encryption is not very useful without decryption. Note that this will return minimal
information if decryption fails.
/**
* Decrypts the data using a hybrid crypto-system which uses GCM to encrypt
* the data and OAEP to encrypt the AES key. All the default parameter
* choices are used for OAEP and GCM.
*
* @param privateKey
* the RSA private key used to unwrap the AES key
* @param ciphertext
* the ciphertext to be encrypted, not altered
* @return the plaintext
* @throws InvalidKeyException
* if the key is not an RSA private key
* @throws NullPointerException
* if the ciphertext is null
* @throws IllegalArgumentException
* with the message "Invalid ciphertext" if the ciphertext is invalid (minimize
information leakage)
*/
public static byte[] decryptData(PrivateKey privateKey, byte[] ciphertext)
throws InvalidKeyException, NullPointerException {
Cipher oaep;
try {
https://riptutorial.com/ 947
// SHA-1 is the default and not vulnerable in this setting
// use OAEPParameterSpec to configure more than just the hash
oaep = Cipher.getInstance("RSA/ECB/OAEPwithSHA1andMGF1Padding");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(
"Runtime doesn't have support for RSA cipher (mandatory algorithm for
runtimes)",
e);
} catch (NoSuchPaddingException e) {
throw new RuntimeException(
"Runtime doesn't have support for OAEP padding (present in the standard Java
runtime sinze XX)",
e);
}
oaep.init(Cipher.UNWRAP_MODE, privateKey);
// sanity check #1
if (ciphertextBuffer.remaining() < 2) {
throw new IllegalArgumentException("Invalid ciphertext");
}
// - element 1: the length of the encapsulated key
int wrappedKeySize = ciphertextBuffer.getShort() & 0xFFFF;
// sanity check #2
if (ciphertextBuffer.remaining() < wrappedKeySize + 128 / Byte.SIZE) {
throw new IllegalArgumentException("Invalid ciphertext");
}
Cipher aesGCM;
try {
aesGCM = Cipher.getInstance("AES/GCM/Nopadding");
// we can get away with a zero nonce since the key is randomly
// generated
// 128 bits is the recommended (maximum) value for the tag size
// 12 bytes (96 bits) is the default nonce size for GCM mode
// encryption
https://riptutorial.com/ 948
GCMParameterSpec staticParameterSpec = new GCMParameterSpec(128,
new byte[12]);
aesGCM.init(Cipher.DECRYPT_MODE, aesKey, staticParameterSpec);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(
"Runtime doesn't have support for AES cipher (mandatory algorithm for
runtimes)",
e);
} catch (NoSuchPaddingException e) {
throw new RuntimeException(
"Runtime doesn't have support for GCM (present in the standard Java runtime
sinze XX)",
e);
} catch (InvalidAlgorithmParameterException e) {
throw new RuntimeException(
"IvParameterSpec not accepted by this implementation of GCM",
e);
}
// --- create a buffer of the right size for our own protocol ---
return plaintextBuffer.array();
}
https://riptutorial.com/ 949
Chapter 148: Runtime Commands
Examples
Adding shutdown hooks
Sometimes you need a piece of code to execute when the program stops, such as releasing
system resources that you open. You can make a thread run when the program stops with the
addShutdownHook method:
https://riptutorial.com/ 950
Chapter 149: Scanner
Syntax
• Scanner scanner = new Scanner(Source source);
• Scanner scanner = new Scanner(System.in);
Parameters
Parameter Details
Source Source could be either one of String, File or any kind of InputStream
Remarks
The Scanner class was introduced in Java 5. The reset() method was added in Java 6, and a
couple of new constructors were added in Java 7 for interoperability with the (then) new Path
interface.
Examples
Reading system input using Scanner
The scanner object is initialized to read input from keyboard. So for the below input from keyboar,
it'll produce the output as Reading from keyboard
Reading
from
keyboard
//space
https://riptutorial.com/ 951
scanner = new Scanner(new File("Names.txt"));
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (Exception e) {
System.err.println("Exception occurred!");
} finally {
if (scanner != null)
scanner.close();
}
Here a Scanner object is created by passing a File object containing the name of a text file as
input. This text file will be opened by the File object and read in by the scanner object in the
following lines. scanner.hasNext() will check to see if there is a next line of data in the text file.
Combining that with a while loop will allow you to iterate through every line of data in the Names.txt
file. To retrieve the data itself, we can use methods such as nextLine(),nextInt(),nextBoolean(),
etc. In the example above, scanner.nextLine()is used. nextLine() refers to the following line in a
text file, and combining it with a scanner object allows you to print the contents of the line. To close
a scanner object, you would use .close().
Using try with resources (from Java 7 onwards), the above mentioned code can be written
elegantly as below.
You can use Scanner to read all of the text in the input as a String, by using \Z (entire input) as the
delimiter. For example, this can be used to read all text in a text file in one line:
Remember that you'll have to close the Scanner, as well as catch the IoException this may throw,
as described in the example Reading file input using Scanner.
You can use custom delimiters (regular expressions) with Scanner, with .useDelimiter(","), to
determine how the input is read. This works similarly to String.split(...). For example, you can
use Scanner to read from a list of comma separated values in a String:
https://riptutorial.com/ 952
while(scanner.hasNext()){
System.out.println(scanner.next());
}
}catch(Exception e){
e.printStackTrace();
}finally{
if (scanner != null)
scanner.close();
}
This will allow you to read every element in the input individually. Note that you should not use this
to parse CSV data, instead, use a proper CSV parser library, see CSV parser for Java for other
possibilities.
The following is how to properly use the java.util.Scanner class to interactively read user input
from System.in correctly( sometimes referred to as stdin, especially in C, C++ and other languages
as well as in Unix and Linux). It idiomatically demonstrates the most common things that are
requested to be done.
package com.stackoverflow.scanner;
import javax.annotation.Nonnull;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;
static
{
final SortedSet<String> ecmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
ecmds.addAll(Arrays.asList("exit", "done", "quit", "end", "fino"));
EXIT_COMMANDS = Collections.unmodifiableSortedSet(ecmds);
final SortedSet<String> hcmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
hcmds.addAll(Arrays.asList("help", "helpi", "?"));
HELP_COMMANDS = Collections.unmodifiableSet(hcmds);
DATE_PATTERN = Pattern.compile("\\d{4}([-\\/])\\d{2}\\1\\d{2}"); //
http://regex101.com/r/xB8dR3/1
HELP_MESSAGE = format("Please enter some data or enter one of the following commands
to exit %s", EXIT_COMMANDS);
}
/**
* Using exceptions to control execution flow is always bad.
* That is why this is encapsulated in a method, this is done this
* way specifically so as not to introduce any external libraries
https://riptutorial.com/ 953
* so that this is a completely self contained example.
* @param s possible url
* @return true if s represents a valid url, false otherwise
*/
private static boolean isValidURL(@Nonnull final String s)
{
try { new URL(s); return true; }
catch (final MalformedURLException e) { return false; }
}
private static void output(@Nonnull final String format, @Nonnull final Object... args)
{
System.out.println(format(format, args));
}
https://riptutorial.com/ 954
{
output("Exit command %s issued, exiting!", next);
break;
}
else if (HELP_COMMANDS.contains(next)) { output(HELP_MESSAGE); }
else { output("You entered an unclassified String = %s", next); }
}
}
}
/*
This will close the underlying Readable, in this case System.in, and free those
resources.
You will not be to read from System.in anymore after this you call .close().
If you wanted to use System.in for something else, then don't close the Scanner.
*/
sis.close();
System.exit(0);
}
}
import java.util.Scanner;
If you want to read an int from the command line, just use this snippet. First of all, you have to
create a Scanner object, that listens to System.in, which is by default the Command Line, when
you start the program from the command line. After that, with the help of the Scanner object, you
read the first int that the user passes into the command line and store it in the variable number.
Now you can do whatever you want with that stored int.
it can happen that you use a scanner with the System.in as parameter for the constructor, then
you need to be aware that closing the scanner will close the InputStream too giving as next that
every try to read the input on that (Or any other scanner object) will throw an
java.util.NoSuchElementException or an java.lang.IllegalStateException
example:
https://riptutorial.com/ 955
Chapter 150: Secure objects
Syntax
• SealedObject sealedObject = new SealedObject(obj, cipher);
• SignedObject signedObject = new SignedObject(obj, signingKey, signingEngine);
Examples
SealedObject (javax.crypto.SealedObject)
This class enables a programmer to create an object and protect its confidentiality with a
cryptographic algorithm.
Given any Serializable object, one can create a SealedObject that encapsulates the original
object, in serialized format (i.e., a "deep copy"), and seals (encrypts) its serialized contents, using
a cryptographic algorithm such as AES, DES, to protect its confidentiality. The encrypted content
can later be decrypted (with the corresponding algorithm using the correct decryption key) and de-
serialized, yielding the original object.
SignedObject (java.security.SignedObject)
https://riptutorial.com/ 956
SignedObject is a class for the purpose of creating authentic runtime objects whose integrity
cannot be compromised without being detected.
More specifically, a SignedObject contains another Serializable object, the (to-be-)signed object
and its signature.
//Create a key
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
// create a private key
PrivateKey signingKey = keyGen.generateKeyPair().getPrivate();
// create a Signature
Signature signingEngine = Signature.getInstance("DSA");
signingEngine.initSign(signingKey);
// create a simple object
Serializable obj = new String("John");
// sign our object
SignedObject signedObject = new SignedObject(obj, signingKey, signingEngine);
System.out.println("signedObject-" + signedObject);
System.out.println("signedObject Data-" + signedObject.getObject());
https://riptutorial.com/ 957
Chapter 151: Security & Cryptography
Examples
Compute Cryptographic Hashes
To compute the hashes of relatively small blocks of data using different algorithms:
Additional algorithms may be available depending on your implementation of the Java platform.
new SecureRandom().nextBytes(sample);
Sample: E4F14CEA2384F70B706B53A6DF8C5EFE
Note that the call to nextBytes() may block while entropy is gathered depending on the algorithm
being used.
randomness.nextBytes(sample);
https://riptutorial.com/ 958
System.out.println("Provider: " + randomness.getProvider());
System.out.println("Algorithm: " + randomness.getAlgorithm());
System.out.println("Sample: " + DatatypeConverter.printHexBinary(sample));
dhGenerator.initialize(1024);
dsaGenerator.initialize(1024);
rsaGenerator.initialize(2048);
Additional algorithms and key sizes may be available on your implementation of the Java platform.
To compute a signature:
signer.initSign(privateKey);
signer.update(data);
Note that the signature algorithm must be compatible with the algorithm used to generate the key
pair.
https://riptutorial.com/ 959
To verify a signature:
verifier.initVerify(publicKey);
verifier.update(data);
Signature: true
rsa.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
rsa.update(message.getBytes());
final byte[] result = rsa.doFinal();
Message: Hello
Encrypted: 5641FBB9558ECFA9ED...
Note that when creating the Cipher object, you have to specify a transformation that is compatible
with the type of key being used. (See JCA Standard Algorithm Names for a list of supported
transformations.). For RSA encryption data message.getBytes() length must be smaller than the key
size. See this SO Answer for detail.
rsa.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
rsa.update(cipherText);
final String result = new String(rsa.doFinal());
Decrypted: Hello
https://riptutorial.com/ 960
Read Security & Cryptography online: https://riptutorial.com/java/topic/7529/security---
cryptography
https://riptutorial.com/ 961
Chapter 152: Security & Cryptography
Introduction
Security practices in Java can be separated into two broad, vaguely defined categories; Java
platform security, and secure Java programming.
Java platform security practices deal with managing the security and integrity of the JVM. It
includes such topics as managing JCE providers and security policies.
Secure Java programming practices concern the best ways to write secure Java programs. It
includes such topics as using random numbers and cryptography, and preventing vulnerabilities.
Remarks
While examples should be clearly made, some topics that must be covered are:
Examples
The JCE
The Java Cryptography Extension (JCE) is a framework built into the JVM to allow developers to
easily and securely use cryptography in their programs. It does this by providing a simple, portable
interface to programmers, while using a system of JCE Providers to securely implement the
underlying cryptographic operations.
While the JCE secures cryptographic operations and key generation, it is up to the developer to
actually manage their keys. More information needs to be provided here.
One commonly-accepted best practice for handling keys at runtime is to store them only as byte
arrays, and never as strings. This is because Java strings are immutable, and cannot be manually
"cleared" or "zeroed out" in memory; while a reference to a string can be removed, the exact string
will remain in memory until its segment of memory is garbage-collected and reused. An attacker
would have a large window in which they could dump the program's memory and easily find the
key. Contrarily, byte arrays are mutable, and can have their contents overwritten in place; it is a
good idea to 'zero-out' your keys as soon as you no longer need them.
Needs content
https://riptutorial.com/ 962
Networking Concerns
Needs content
Needs content
For most applications, the java.utils.Random class is a perfectly fine source of "random" data. If
you need to choose a random element from an array, or generate a random string, or create a
temporary "unique" identifier, you should probably use Random.
However, many cryptographic systems rely on randomness for their security, and the randomness
provided by Random simply isn't of high enough quality. For any cryptographic operation that
requires a random input, you should use SecureRandom instead.
A cryptographic hash function is a member of a class of functions with three vital properties;
consistency, uniqueness, and irreversibility.
Consistency: Given the same data, a hash function will always return the same value. That is, if
X = Y, f(x) will always equal f(y) for hash function f.
Uniqueness: No two inputs to a hash function will ever result in the same output. That is, if X != Y,
f(x) != f(y), for any values of X and Y.
Irreversibility: It is impractically difficult, if not impossible, to "reverse" a hash function. That is,
given only f(X), there should be no way of finding the original X short of putting every possible
value of X through the function f (brute-force). There should be no function f1 such that f1(f(X)) =
X.
Many functions lack at least one of these attributes. For example, MD5 and SHA1 are known to
have collisions, i.e. two inputs that have the same output, so they lack uniqueness. Some
functions that are currently believed to be secure are SHA-256 and SHA-512.
https://riptutorial.com/ 963
Chapter 153: SecurityManager
Examples
Enabling the SecurityManager
Java Virtual Machines (JVMs) can be run with a SecurityManager installed. The SecurityManager
governs what the code running in the JVM is allowed to do, based on factors such as where the
code was loaded from and what certificates were used to sign the code.
The SecurityManager can be installed by setting the java.security.manager system property on the
command line when starting the JVM:
System.setSecurityManager(new SecurityManager())
The standard Java SecurityManager grants permissions on the basis of a Policy, which is defined
in a policy file. If no policy file is specified, the default policy file under
$JAVA_HOME/lib/security/java.policy will be used.
The ClassLoader needs to provide a ProtectionDomain identifying the source of the code:
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classDef = provider.getClass(name);
Class<?> clazz = defineClass(name, classDef, 0, classDef.length, pd);
return clazz;
}
}
By overriding findClass rather than loadClass the delegational model is preserved, and the
PluginClassLoader will first query the system and parent classloader for class definitions.
https://riptutorial.com/ 964
Create a Policy:
public PluginSecurityPolicy() {
// amend this as appropriate
appPermissions.add(new AllPermission());
// add any permissions plugins should have to pluginPermissions
}
@Override
public Provider getProvider() {
return super.getProvider();
}
@Override
public String getType() {
return super.getType();
}
@Override
public Parameters getParameters() {
return super.getParameters();
}
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
return new Permissions();
}
@Override
public PermissionCollection getPermissions(ProtectionDomain domain) {
return isPlugin(domain)?pluginPermissions:appPermissions;
}
Policy.setPolicy(new PluginSecurityPolicy());
System.setSecurityManager(new SecurityManager());
https://riptutorial.com/ 965
Notes:
• The standard policy file syntax and mechanism for permission assignment in general remain
unaffected. This means that deny rules within policy files are still expressed as grants.
• The policy wrapper is meant to specifically encapsulate the default file-backed Policy
(assumed to be com.sun.security.provider.PolicyFile).
• Denied permissions are only processed as such at the policy level. If statically assigned to a
domain, they will by default be treated by that domain as ordinary "positive" permissions.
package com.example;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.security.BasicPermission;
import java.security.Permission;
import java.security.UnresolvedPermission;
import java.text.MessageFormat;
/**
* A representation of a "negative" privilege.
* <p>
* A <code>DeniedPermission</code>, when "granted" (to some <code>ProtectionDomain</code>
and/or
* <code>Principal</code>), represents a privilege which <em>cannot</em> be exercised,
regardless of
* any positive permissions (<code>AllPermission</code> included) possessed. In other words,
if a
* set of granted permissions, <em>P</em>, contains a permission of this class, <em>D</em>,
then the
* set of effectively granted permissions is<br/>
* <br/>
* <em>{ P<sub>implied</sub> - D<sub>implied</sub> }</em>.
* </p>
* <p>
* Each instance of this class encapsulates a <em>target permission</em>, representing the
* "positive" permission being denied.
* </p>
* Denied permissions employ the following naming scheme:<br/>
* <br/>
*
<em><target_class_name>:<target_name>(:<target_actions>)</em>
* <br/>
* where:
* <ul>
* <li><em>target_class_name</em> is the name of the target permission's class,</li>
* <li><em>target_name</em> is the name of the target permission, and</li>
* <li><em>target_actions</em> is, optionally, the actions string of the target
permission.</li>
* </ul>
* A denied permission, having a target permission <em>t</em>, is said to <em>imply</em>
another
* permission <em>p</em>, if:
* <ul>
* <li>p <em>is not</em> itself a denied permission, and <code>(t.implies(p) == true)</code>,
https://riptutorial.com/ 966
* or</li>
* <li>p <em>is</em> a denied permission, with a target <em>t1</em>, and
* <code>(t.implies(t1) == true)</code>.
* </ul>
* <p>
* It is the responsibility of the policy decision point (e.g., the <code>Policy</code>
provider) to
* take denied permission semantics into account when issuing authorization statements.
* </p>
*/
public final class DeniedPermission extends BasicPermission {
/**
* Instantiates a <code>DeniedPermission</code> that encapsulates a target permission of
the
* indicated class, specified name and, optionally, actions.
*
* @throws IllegalArgumentException
* if:
* <ul>
* <li><code>targetClassName</code> is <code>null</code>, the empty string,
does not
* refer to a concrete <code>Permission</code> descendant, or refers to
* <code>DeniedPermission.class</code> or
<code>UnresolvedPermission.class</code>.</li>
* <li><code>targetName</code> is <code>null</code>.</li>
* <li><code>targetClassName</code> cannot be instantiated, and it's the
caller's fault;
* e.g., because <code>targetName</code> and/or <code>targetActions</code> do
not adhere
* to the naming constraints of the target class; or due to the target class
not
* exposing a <code>(String name)</code>, or <code>(String name, String
actions)</code>
* constructor, depending on whether <code>targetActions</code> is
<code>null</code> or
* not.</li>
* </ul>
*/
public static DeniedPermission newDeniedPermission(String targetClassName, String
targetName,
String targetActions) {
if (targetClassName == null || targetClassName.trim().isEmpty() || targetName == null)
{
throw new IllegalArgumentException(
"Null or empty [targetClassName], or null [targetName] argument was
supplied.");
}
StringBuilder sb = new StringBuilder(targetClassName).append(":").append(targetName);
if (targetName != null) {
sb.append(":").append(targetName);
}
return new DeniedPermission(sb.toString());
}
/**
* Instantiates a <code>DeniedPermission</code> that encapsulates a target permission of
the class,
https://riptutorial.com/ 967
* name and, optionally, actions, collectively provided as the <code>name</code> argument.
*
* @throws IllegalArgumentException
* if:
* <ul>
* <li><code>name</code>'s target permission class name component is empty,
does not
* refer to a concrete <code>Permission</code> descendant, or refers to
* <code>DeniedPermission.class</code> or
<code>UnresolvedPermission.class</code>.</li>
* <li><code>name</code>'s target name component is <code>empty</code></li>
* <li>the target permission class cannot be instantiated, and it's the
caller's fault;
* e.g., because <code>name</code>'s target name and/or target actions
component(s) do
* not adhere to the naming constraints of the target class; or due to the
target class
* not exposing a <code>(String name)</code>, or
* <code>(String name, String actions)</code> constructor, depending on
whether the
* target actions component is empty or not.</li>
* </ul>
*/
public DeniedPermission(String name) {
super(name);
String[] comps = name.split(":");
if (comps.length < 2) {
throw new IllegalArgumentException(MessageFormat.format("Malformed name [{0}]
argument.", name));
}
this.target = initTarget(comps[0], comps[1], ((comps.length < 3) ? null : comps[2]));
}
/**
* Instantiates a <code>DeniedPermission</code> that encapsulates the given target
permission.
*
* @throws IllegalArgumentException
* if <code>target</code> is <code>null</code>, a
<code>DeniedPermission</code>, or an
* <code>UnresolvedPermission</code>.
*/
public static DeniedPermission newDeniedPermission(Permission target) {
if (target == null) {
throw new IllegalArgumentException("Null [target] argument.");
}
if (target instanceof DeniedPermission || target instanceof UnresolvedPermission) {
throw new IllegalArgumentException("[target] must not be a DeniedPermission or an
UnresolvedPermission.");
}
StringBuilder sb = new
StringBuilder(target.getClass().getName()).append(":").append(target.getName());
String targetActions = target.getActions();
if (targetActions != null) {
sb.append(":").append(targetActions);
}
return new DeniedPermission(sb.toString(), target);
}
https://riptutorial.com/ 968
this.target = target;
}
https://riptutorial.com/ 969
targetActions = "<empty>";
}
throw new IllegalArgumentException(MessageFormat.format(
"Could not instantiate target Permission class [{0}]; provided target
name [{1}] and/or target actions [{2}] potentially erroneous.",
targetClassName, targetName, targetActions), roe);
}
throw new RuntimeException(
"Could not instantiate target Permission class [{0}]; an unforeseen error
occurred - see attached cause for details",
roe);
}
}
/**
* Checks whether the given permission is implied by this one, as per the {@link
DeniedPermission
* overview}.
*/
@Override
public boolean implies(Permission p) {
if (p instanceof DeniedPermission) {
return target.implies(((DeniedPermission) p).target);
}
return target.implies(p);
}
/**
* Returns this denied permission's target permission (the actual positive permission
which is not
* to be granted).
*/
public Permission getTargetPermission() {
return target;
}
package com.example;
import java.security.CodeSource;
import java.security.NoSuchAlgorithmException;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.security.UnresolvedPermission;
import java.util.Enumeration;
/**
* Wrapper that adds rudimentary {@link DeniedPermission} processing capabilities to the
standard
* file-backed <code>Policy</code>.
*/
public final class DenyingPolicy extends Policy {
https://riptutorial.com/ 970
try {
defaultPolicy = Policy.getInstance("javaPolicy", null);
}
catch (NoSuchAlgorithmException nsae) {
throw new RuntimeException("Could not acquire default Policy.", nsae);
}
}
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
return defaultPolicy.getPermissions(codesource);
}
@Override
public PermissionCollection getPermissions(ProtectionDomain domain) {
return defaultPolicy.getPermissions(domain);
}
/**
* @return
* <ul>
* <li><code>true</code> if:</li>
* <ul>
* <li><code>permission</code> <em>is not</em> an instance of
* <code>DeniedPermission</code>,</li>
* <li>an <code>implies(domain, permission)</code> invocation on the system-
default
* <code>Policy</code> yields <code>true</code>, and</li>
* <li><code>permission</code> <em>is not</em> implied by any
<code>DeniedPermission</code>s
* having potentially been assigned to <code>domain</code>.</li>
* </ul>
* <li><code>false</code>, otherwise.
* </ul>
*/
@Override
public boolean implies(ProtectionDomain domain, Permission permission) {
if (permission instanceof DeniedPermission) {
/*
* At the policy decision level, DeniedPermissions can only themselves imply, not
be implied (as
* they take away, rather than grant, privileges). Furthermore, clients aren't
supposed to use this
* method for checking whether some domain _does not_ have a permission (which is
what
* DeniedPermissions express after all).
*/
return false;
}
if (!defaultPolicy.implies(domain, permission)) {
// permission not granted, so no need to check whether denied
return false;
}
/*
* Permission granted--now check whether there's an overriding DeniedPermission. The
following
* assumes that previousPolicy is a sun.security.provider.PolicyFile (different
https://riptutorial.com/ 971
implementations
* might not support #getPermissions(ProtectionDomain) and/or handle
UnresolvedPermissions
* differently).
*/
@Override
public void refresh() {
defaultPolicy.refresh();
}
Demo
package com.example;
import java.security.Policy;
https://riptutorial.com/ 972
grant codeBase "file:///path/to/classes/bin/-"
permission java.util.PropertyPermission "*", "read,write";
permission com.example.DeniedPermission "java.util.PropertyPermission:foo.bar:read";
};
Lastly, run the Main and watch it fail, due to the "deny" rule (the DeniedPermission) overriding the
grant (its PropertyPermission). Note that a setProperty("foo.baz", "xyz") invocation would instead
have succeeded, since the denied permission only covers the "read" action, and solely for the
"foo.bar" property.
https://riptutorial.com/ 973
Chapter 154: Serialization
Introduction
Java provides a mechanism, called object serialization where an object can be represented as a
sequence of bytes that includes the object's data as well as information about the object's type
and the types of data stored in the object.
After a serialized object has been written into a file, it can be read from the file and deserialized
that is, the type information and bytes that represent the object and its data can be used to
recreate the object in memory.
Examples
Basic Serialization in Java
What is Serialization
Serialization is the process of converting an object's state (including its references) to a sequence
of bytes, as well as the process of rebuilding those bytes into a live object at some future time.
Serialization is used when you want to persist the object. It is also used by Java RMI to pass
objects between JVMs, either as arguments in a method invocation from a client to a server or as
return values from a method invocation, or as exceptions thrown by remote methods. In general,
serialization is used when we want the object to exist beyond the lifetime of the JVM.
java.io.Serializable is a marker interface (has no body). It is just used to "mark" Java classes as
serializable.
The serialization runtime associates with each serializable class a version number, called a
serialVersionUID, which is used during de-serialization to verify that the sender and receiver of a
serialized object have loaded classes for that object that are compatible with respect to
serialization. If the receiver has loaded a class for the object that has a different serialVersionUID
than that of the corresponding sender's class, then deserialization will result in an
InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by
declaring a field named serialVersionUID that must be static, final, and of type long:
To persist an object the respective class must implement the java.io.Serializable interface.
import java.io.Serializable;
https://riptutorial.com/ 974
private Date currentTime;
public SerialClass() {
currentTime = Calendar.getInstance().getTime();
}
Now we need to write this object to a file system. We use java.io.ObjectOutputStream for this
purpose.
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
The stored object can be read from file system at later time using java.io.ObjectInputStream as
shown below:
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.java.lang.ClassNotFoundException;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));
time = (SerialClass)in.readObject();
in.close();
} catch(IOException ex){
ex.printStackTrace();
https://riptutorial.com/ 975
} catch(ClassNotFoundException cnfe){
cnfe.printStackTrace();
}
// print out restored time
System.out.println("Restored time: " + time.getTime());
}
}
The serialized class is in binary form. The deserialization can be problematic if the class definition
changes: see the Versioning of Serialized Objects chapter of the Java Serialization Specification
for details.
Serializing an object serializes the entire object graph of which it is the root, and operates correctly
in the presence of cyclic graphs. A reset() method is provided to force the ObjectOutputStream to
forget about objects that have already been serialized.
Transient-fields - Serialization
(Serialization)
//Skills
List<String> skills = new LinkedList<String>();
skills.add("leadership");
skills.add("Java Experience");
//Employe
Employe obj = new Employe();
obj.setFirstName("Christian");
obj.setLastName("Lusardi");
obj.setAge(25);
obj.setSalary(new BigDecimal("10000"));
obj.setSkills(skills);
//Serialization process
Gson gson = new Gson();
String json = gson.toJson(obj);
//{"firstName":"Christian","lastName":"Lusardi","age":25,"salary":10000,"skills":["leadership","Java
Experience"]}
Note that you can not serialize objects with circular references since that will result in infinite
https://riptutorial.com/ 976
recursion.
(Deserialization)
Following is an implementation that demonstrates how an object can be serialized into its
corresponding JSON string.
class Test {
Serialization:
String jsonString;
try {
jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(test);
System.out.println(jsonString);
} catch (JsonProcessingException ex) {
// Handle Exception
}
Output:
https://riptutorial.com/ 977
"idx" : 1,
"name" : "abc"
}
You can omit the Default Pretty Printer if you don't need it.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
Custom Serialization
In this example we want to create a class that will generate and output to console, a random
number between a range of two integers which are passed as arguments during the initialization.
@Override
private void WriteObject(ObjectOutputStreamout) throws IO Exception;
private void ReadObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
public void run() {
while(true) {
Random rand = new Random();
System.out.println("Thread: " + thread.getId() + " Random:" + rand.nextInt(max -
min));
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Now if we want to make this class Serializable there will be some problems. The Thread is one of
the certain system-level classes that are not Serializable. So we need to declare the thread as
transient. By doing this we will be able to serialize the objects of this class but we will still have an
issue. As you can see in the constructor we set the min and the max values of our randomizer and
after this we start the thread which is responsible for generating and printing the random value.
Thus when restoring the persisted object by calling the readObject() the constructor will not run
https://riptutorial.com/ 978
again as there is no creation of a new object. In that case we need to develop a Custom
Serialization by providing two methods inside the class. Those methods are:
Thus by adding our implementation in the readObject() we can initiate and start our thread:
@Override
public void run() {
while(true) {
Random rand = new Random();
System.out.println("Thread: " + thread.getId() + " Random:" + rand.nextInt(max -
min));
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
https://riptutorial.com/ 979
try
{
fos = new FileOutputStream("test");
out = new ObjectOutputStream(fos);
out.writeObject(rangeRandom);
out.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
If you run the main you will see that there are two threads running for each RangeRandom
instance and that is because the Thread.start() method is now in both the constructor and the
readObject().
When you implement java.io.Serializable interface to make a class serializable, the compiler
looks for a static final field named serialVersionUID of type long. If the class doesn't have this
field declared explicitly then the compiler will create one such field and assign it with a value which
comes out of a implementation dependent computation of serialVersionUID. This computation
depends upon various aspects of the class and it follows the Object Serialization Specifications
given by Sun. But, the value is not guaranteed to be the same across all compiler
implementations.
This value is used for checking the compatibility of the classes with respect to serialization and this
is done while de-serializing a saved object. The Serialization Runtime verifies that serialVersionUID
read from the de-serialized data and the serialVersionUID declared in the class are exactly the
same. If that is not the case, it throws an InvalidClassException.
It's highly recommended that you explicitly declare and initialize the static, final field of type long
https://riptutorial.com/ 980
and named 'serialVersionUID' in all your classes you want to make Serializable instead of relying
on the default computation of the value for this field even if you are not gonna use versioning.
'serialVersionUID' computation is extremely sensitive and may vary from one compiler
implementation to another and hence you may turn up getting the InvalidClassException even
for the same class just because you used different compiler implementations on the sender
and the receiver ends of the serialization process.
As long as serialVersionUID is the same, Java Serialization can handle different versions of a
class. Compatible and incompatible changes are;
Compatible Changes
• Adding fields : When the class being reconstituted has a field that does not occur in the
stream, that field in the object will be initialized to the default value for its type. If class-
specific initialization is needed, the class may provide a readObject method that can initialize
the field to nondefault values.
• Adding classes : The stream will contain the type hierarchy of each object in the stream.
Comparing this hierarchy in the stream with the current class can detect additional classes.
Since there is no information in the stream from which to initialize the object, the class's
fields will be initialized to the default values.
• Removing classes : Comparing the class hierarchy in the stream with that of the current
class can detect that a class has been deleted. In this case, the fields and objects
corresponding to that class are read from the stream. Primitive fields are discarded, but the
objects referenced by the deleted class are created, since they may be referred to later in
the stream. They will be garbage-collected when the stream is garbage-collected or reset.
• Adding writeObject/readObject methods : If the version reading the stream has these
methods then readObject is expected, as usual, to read the required data written to the
stream by the default serialization. It should call defaultReadObject first before reading any
optional data. The writeObject method is expected as usual to call defaultWriteObject to
write the required data and then may write optional data.
• Adding java.io.Serializable : This is equivalent to adding types. There will be no values in
the stream for this class so its fields will be initialized to default values. The support for
subclassing nonserializable classes requires that the class's supertype have a no-arg
constructor and the class itself will be initialized to default values. If the no-arg constructor is
not available, the InvalidClassException is thrown.
• Changing the access to a field : The access modifiers public, package, protected, and
private have no effect on the ability of serialization to assign values to the fields.
• Changing a field from static to nonstatic or transient to nontransient : When relying on
default serialization to compute the serializable fields, this change is equivalent to adding a
field to the class. The new field will be written to the stream but earlier classes will ignore the
value since serialization will not assign values to static or transient fields.
https://riptutorial.com/ 981
Incompatible Changes
• Deleting fields : If a field is deleted in a class, the stream written will not contain its value.
When the stream is read by an earlier class, the value of the field will be set to the default
value because no value is available in the stream. However, this default value may adversely
impair the ability of the earlier version to fulfill its contract.
• Moving classes up or down the hierarchy : This cannot be allowed since the data in the
stream appears in the wrong sequence.
• Changing a nonstatic field to static or a nontransient field to transient : When relying
on default serialization, this change is equivalent to deleting a field from the class. This
version of the class will not write that data to the stream, so it will not be available to be read
by earlier versions of the class. As when deleting a field, the field of the earlier version will be
initialized to the default value, which can cause the class to fail in unexpected ways.
• Changing the declared type of a primitive field : Each version of the class writes the data
with its declared type. Earlier versions of the class attempting to read the field will fail
because the type of the data in the stream does not match the type of the field.
• Changing the writeObject or readObject method so that it no longer writes or reads the
default field data or changing it so that it attempts to write it or read it when the previous
version did not. The default field data must consistently either appear or not appear in the
stream.
• Changing a class from Serializable to Externalizable or vice versa is an incompatible change
since the stream will contain data that is incompatible with the implementation of the
available class.
• Changing a class from a non-enum type to an enum type or vice versa since the stream will
contain data that is incompatible with the implementation of the available class.
• Removing either Serializable or Externalizable is an incompatible change since when written
it will no longer supply the fields needed by older versions of the class.
• Adding the writeReplace or readResolve method to a class is incompatible if the behavior
would produce an object that is incompatible with any older version of the class.
We consume rest API as a JSON format and then unmarshal it to a POJO. Jackson’s
org.codehaus.jackson.map.ObjectMapper “just works” out of the box and we really don’t do
anything in most cases. But sometimes we need custom deserializer to fulfill our custom needs
and this tutorial will guide you through the process of creating your own custom deserializer.
https://riptutorial.com/ 982
And
{
"id": 1,
"name": "Program @# 1",
"createdBy": {
"id": 1,
"name": "Bazlur Rahman",
"email": "[email protected]"
},
"contents": "Some contents"
}
Now can do the opposite very easily. If we have this JSON, we can unmarshal to a program object
using ObjectMapper as following –
Now let’s say, this is not the real case, we are going to have a different JSON from an API which
doesn’t match with our Program class.
{
"id": 1,
"name": "Program @# 1",
"ownerId": 1
"contents": "Some contents"
}
Look at the JSON string, you can see, it has a different field that is owenerId.
https://riptutorial.com/ 983
Now if you want to serialize this JSON as we did earlier, you will have exceptions.
There are two ways to avoid exceptions and have this serialized –
Ignore the onwerId. Add the following annotation in the Program class
@JsonIgnoreProperties(ignoreUnknown = true)
public class Program {}
But there are cases when you actually need this owerId field. Let's say you want to relate it as an id
of the User class.
As you can see, first you have to access the JsonNode from the JonsParser. And then you can easily
extract information from a JsonNode using the get() method. and you have to make sure about the
field name. It should be the exact name, spelling mistake will cause exceptions.
mapper.registerModule(module);
@JsonDeserialize(using = ProgramDeserializer.class)
public class Program {
}
https://riptutorial.com/ 984
Chapter 155: ServiceLoader
Remarks
ServiceLoader can be used to get instances of classes extending a given type(=service) that are
specified in a file packed in a .jar file. The service that is extended/implemented is often a
interface, but this is not required.
The extending/implementing classes need to provide a zero argument constructor for the
ServiceLoader to instantiate them.
To be discovered by the ServiceLoader a text file with the name of the fully qualified type name of
the implemented service needs to be stored inside the META-INF/services directory in the jar file.
This file contains one fully qualified name of a class implementing the service per line.
Examples
Logger Service
The following example shows how to instantiate a class for logging via the ServiceLoader.
Service
package servicetest;
import java.io.IOException;
package servicetest.logger;
import servicetest.Logger;
@Override
public void log(String message) {
System.err.println(message);
}
https://riptutorial.com/ 985
@Override
public void close() {
}
package servicetest.logger;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import servicetest.Logger;
@Override
public void log(String message) throws IOException {
writer.append(message);
writer.newLine();
}
@Override
public void close() throws IOException {
writer.close();
}
META-INF/services/servicetest.Logger
The META-INF/services/servicetest.Logger file lists the names of the Logger implementations.
servicetest.logger.ConsoleLogger
servicetest.logger.FileLogger
Usage
The following main method writes a message to all available loggers. The loggers are instantiated
using ServiceLoader.
https://riptutorial.com/ 986
ServiceLoader<Logger> loader = ServiceLoader.load(servicetest.Logger.class);
// iterate through instances of available loggers, writing the message to each one
Iterator<Logger> iterator = loader.iterator();
while (iterator.hasNext()) {
try (Logger logger = iterator.next()) {
logger.log(message);
}
}
}
The ServiceLoader is a simple and easy to use built-in mechanism for dynamic loading of interface
implementations. With the service loader - providing means for instantation (but not the wiring) - a
simple dependency injection mechanism can be built in Java SE. With the ServiceLoader interface
and implementation separation becomes natural and programs can be conveniently extended.
Actually a lot of Java API are implented based on the ServiceLoader
Lets start with the interface and put it in a jar, named for example accounting-api.jar
package example;
long getBalance();
}
package example.impl;
import example.AccountingService;
further, the accounting-impl.jar contains a file declaring that this jar provides an implementation of
AccountingService. The file has to have a path starting with META-INF/services/ and must have the
https://riptutorial.com/ 987
same name as the fully-qualified name of the interface:
• META-INF/services/example.AccountingService
example.impl.DefaultAccountingService
Given both jars are in the classpath of the program, that consumes the AccountingService, an
instance of the Service can be obtained by using the ServiceLauncher
Note that when invoking next() a new instance will allways be created. If you want to re-use an
instance, you have to use the iterator() method of the ServiceLoader or the for-each loop as
shown above.
https://riptutorial.com/ 988
Chapter 156: Sets
Examples
Declaring a HashSet with values
Using guava:
Using Streams:
Generally, sets are a type of collection which stores unique values. Uniqueness is determined by
the equals() and hashCode() methods.
https://riptutorial.com/ 989
LinkedHashSet - Insertion Order
Java SE 7
Java SE 7
Java SE 7
Initialization
A Set is a Collection that cannot contain duplicate elements. It models the mathematical set
abstraction.
Set have its implementation in various classes like HashSet, TreeSet, LinkedHashSet.
For example:
HashSet:
Here T can be String, Integer or any other object. HashSet allows for quick lookup of O(1) but
does not sort the data added to it and loses the insertion order of items.
https://riptutorial.com/ 990
TreeSet:
It stores data in a sorted manner sacrificing some speed for basic operations which take O(lg(n)).
It does not maintain the insertion order of items.
LinkedHashSet:
It is a linked list implementation of HashSet Once can iterate over the items in the order they were
added. Sorting is not provided for its contents. O(1) basic operations are provided, however there
is higher cost than HashSet in maintaining the backing linked list.
Basics of Set
What is a Set?
A set is a data structure which contains a set of elements with an important property that no two
elements in the set are equal.
Types of Set:
Creating a set
set = [12,13]
https://riptutorial.com/ 991
After this set will be:
set = []
Existence of an element in the set can be checked using the contains() method
Output: False
Output: True
Output: 0
https://riptutorial.com/ 992
Eliminating duplicates using Set
Suppose you have a collection elements, and you want to create another collection containing the
same elements but with all duplicates eliminated:
Example:
Output:
https://riptutorial.com/ 993
Chapter 157: Singletons
Introduction
A singleton is a class that only ever has one single instance. For more information on the
Singleton design pattern, please refer to the Singleton topic in the Design Patterns tag.
Examples
Enum Singleton
Java SE 5
Enums have private constructors, are final and provide proper serialization machinery. They are
also very concise and lazily initialized in a thread safe manner.
The JVM provides a guarantee that enum values will not be instantiated more than once each,
which gives the enum singleton pattern a very strong defense against reflection attacks.
What the enum pattern doesn't protect against is other developers physically adding more
elements to the source code. Consequently, if you choose this implementation style for your
singletons it is imperative that you very clearly document that no new values should be added to
those enums.
This is the recommended way of implementing the singleton pattern, as explained by Joshua
Bloch in Effective Java.
This type of Singleton is thread safe, and prevents unnecessary locking after the Singleton
instance has been created.
Java SE 5
// instance of class
private static volatile MySingleton instance = null;
// Private constructor
https://riptutorial.com/ 994
private MySingleton() {
// Some code for constructing object
}
It must be emphasized -- in versions prior to Java SE 5, the implementation above is incorrect and
should be avoided. It is not possible to implement double-checked locking correctly in Java prior to
Java 5.
private Singleton() {}
It can be argued that this example is effectively lazy initialization. Section 12.4.1 of the Java
Language Specification states:
A class or interface type T will be initialized immediately before the first occurrence of
any one of the following:
Therefore, as long as there are no other static fields or static methods in the class, the Singleton
instance will not be initialized until the method getInstance() is invoked the first time.
https://riptutorial.com/ 995
Thread-safe lazy initialization using holder class | Bill Pugh Singleton
implementation
private Singleton() {}
}
This initializes the INSTANCE variable on the first call to Singleton.getInstance(), taking advantage of
the language's thread safety guarantees for static initialization without requiring additional
synchronization.
In this example, base class Singleton provides getMessage() method that returns "Hello world!"
message.
/*
Enumeration that represents possible classes of singleton instance.
If unknown, we'll go with base class - Singleton.
*/
enum SingletonKind {
UNKNOWN,
LOWERCASE,
UPPERCASE
}
//Base class
class Singleton{
/*
Extended classes has to be private inner classes, to prevent extending them in
uncontrolled manner.
*/
private class UppercaseSingleton extends Singleton {
private UppercaseSingleton(){
super();
}
https://riptutorial.com/ 996
@Override
public String getMessage() {
return super.getMessage().toUpperCase();
}
}
@Override
public String getMessage() {
return super.getMessage().toLowerCase();
}
}
/*
By using this method prior to getInstance() method, you effectively change the
type of singleton instance to be created.
*/
public static void setKind(SingletonKind kind) {
Singleton.kind = kind;
}
/*
If needed, getInstance() creates instance appropriate class, based on value of
singletonKind field.
*/
public static Singleton getInstance()
throws NoSuchMethodException,
IllegalAccessException,
InvocationTargetException,
InstantiationException {
if(instance==null){
synchronized (Singleton.class){
if(instance==null){
Singleton singleton = new Singleton();
switch (kind){
case UNKNOWN:
instance = singleton;
break;
case LOWERCASE:
/*
I can't use simple
https://riptutorial.com/ 997
so I use reflection API instead.
LowercaseSingleton.class.getDeclaredConstructor(Singleton.class);
break;
case UPPERCASE:
UppercaseSingleton.class.getDeclaredConstructor(Singleton.class);
ucConstructor.setAccessible(true);
instance = ucConstructor.newInstance(singleton);
}
}
}
}
return instance;
}
//Singleton.setKind(SingletonKind.UPPERCASE);
//Singleton.setKind(SingletonKind.LOWERCASE);
https://riptutorial.com/ 998
Singleton singleton = null;
try {
singleton = Singleton.getInstance();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
System.out.println(singleton.getMessage());
}
}
https://riptutorial.com/ 999
Chapter 158: Sockets
Introduction
A socket is one end-point of a two-way communication link between two programs running on the
network.
Examples
Read from socket
try (
Socket echoSocket = new Socket(hostName, portNumber);
PrintWriter out =
new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdIn =
new BufferedReader(
new InputStreamReader(System.in))
) {
//Use the socket
}
https://riptutorial.com/ 1000
Chapter 159: SortedMap
Introduction
Introduction to sorted Map.
Examples
Introduction to sorted Map.
Keypoint :-
• Comparator comparator( ).
• Object firstKey( ).
• SortedMap headMap(Object end).
• Object lastKey( ).
• SortedMap subMap(Object start, Object end).
• SortedMap tailMap(Object start).
Example
// Get an iterator
Iterator i = set.iterator();
// Display elements
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
}
System.out.println();
https://riptutorial.com/ 1001
// Deposit 1000 into Zara's account
double balance = ((Double)tm.get("Zara")).doubleValue();
tm.put("Zara", new Double(balance + 1000));
System.out.println("Zara's new balance: " + tm.get("Zara"));
}
https://riptutorial.com/ 1002
Chapter 160: Splitting a string into fixed
length parts
Remarks
The goal here is to not lose content, so the regex must not consume (match) any input. Rather it
must match between the last character of the previous target input and the first character of the
next target input. eg for 8-character substrings, we need to break the input up (ie match) at the
places marked below:
a b c d e f g h i j k l m n o p q r s t u v w x y z
^ ^ ^
Ignore the spaces in the input which were required to show between character positions.
Examples
Break a string up into substrings all of a known length
The trick is to use a look-behind with the regex \G, which means "end of previous match":
The regex matches 8 characters after the end of the last match. Since in this case the match is
zero-width, we could more simply say "8 characters after the last match".
Conveniently, \G is initialized to start of input, so it works for the first part of the input too.
Same as the known length example, but insert the length into regex:
int length = 5;
String[] parts = str.split("(?<=\\G.{" + length + "})");
https://riptutorial.com/ 1003
Chapter 161: Stack-Walking API
Introduction
Prior to Java 9, access to the thread stack frames was limited to an internal class
sun.reflect.Reflection. Specifically the method sun.reflect.Reflection::getCallerClass. Some
libraries relies on this method which is deprecated.
An alternative standard API is now provided in JDK 9 via the java.lang.StackWalker class, and is
designed to be efficient by allowing lazy access to the stack frames. Some applications may use
this API to traverse the execution stack and filter on classes.
Examples
Print all stack frames of the current thread
1 package test;
2
3 import java.lang.StackWalker.StackFrame;
4 import java.lang.reflect.InvocationTargetException;
5 import java.lang.reflect.Method;
6 import java.util.List;
7 import java.util.stream.Collectors;
8
9 public class StackWalkerExample {
10
11 public static void main(String[] args) throws NoSuchMethodException, SecurityException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
12 Method fooMethod = FooHelper.class.getDeclaredMethod("foo", (Class<?>[])null);
13 fooMethod.invoke(null, (Object[]) null);
14 }
15 }
16
17 class FooHelper {
18 protected static void foo() {
19 BarHelper.bar();
20 }
21 }
22
23 class BarHelper {
24 protected static void bar() {
25 List<StackFrame> stack = StackWalker.getInstance()
26 .walk((s) -> s.collect(Collectors.toList()));
27 for(StackFrame frame : stack) {
28 System.out.println(frame.getClassName() + " " + frame.getLineNumber() + " " +
frame.getMethodName());
29 }
30 }
31 }
https://riptutorial.com/ 1004
Output:
test.BarHelper 26 bar
test.FooHelper 19 foo
test.StackWalkerExample 13 main
The following prints the current caller class. Note that in this case, the StackWalker needs to be
created with the option RETAIN_CLASS_REFERENCE, so that Class instances are retained in the
StackFrame objects. Otherwise an exception would occur.
class FooHelper {
protected static void foo() {
BarHelper.bar();
}
}
class BarHelper {
protected static void bar() {
System.out.println(StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE).getCallerClass());
}
}
Output:
class test.FooHelper
A couple of other options allow stack traces to include implementation and/or reflection frames.
This may be useful for debugging purposes. For instance, we can add the SHOW_REFLECT_FRAMES
option to the StackWalker instance upon creation, so that the frames for the reflective methods are
printed as well:
package test;
import java.lang.StackWalker.Option;
import java.lang.StackWalker.StackFrame;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;
https://riptutorial.com/ 1005
public class StackWalkerExample {
class FooHelper {
protected static void foo() {
BarHelper.bar();
}
}
class BarHelper {
protected static void bar() {
// show reflection methods
List<StackFrame> stack = StackWalker.getInstance(Option.SHOW_REFLECT_FRAMES)
.walk((s) -> s.collect(Collectors.toList()));
for(StackFrame frame : stack) {
System.out.println(frame.getClassName() + " " + frame.getLineNumber() + " " +
frame.getMethodName());
}
}
}
Output:
test.BarHelper 27 bar
test.FooHelper 20 foo
jdk.internal.reflect.NativeMethodAccessorImpl -2 invoke0
jdk.internal.reflect.NativeMethodAccessorImpl 62 invoke
jdk.internal.reflect.DelegatingMethodAccessorImpl 43 invoke
java.lang.reflect.Method 563 invoke
test.StackWalkerExample 14 main
Note that line numbers for some reflection methods may not be available so
StackFrame.getLineNumber() may return negative values.
https://riptutorial.com/ 1006
Chapter 162: Streams
Introduction
A Stream represents a sequence of elements and supports different kind of operations to perform
computations upon those elements. With Java 8, Collection interface has two methods to
generate a Stream: stream() and parallelStream(). Stream operations are either intermediate or
terminal. Intermediate operations return a Stream so multiple intermediate operations can be
chained before the Stream is closed. Terminal operations are either void or return a non-stream
result.
Syntax
• collection.stream()
• Arrays.stream(array)
• Stream.iterate(firstValue, currentValue -> nextValue)
• Stream.generate(() -> value)
• Stream.of(elementOfT[, elementOfT, ...])
• Stream.empty()
• StreamSupport.stream( iterable.spliterator(), false )
Examples
Using Streams
A Stream is a sequence of elements upon which sequential and parallel aggregate operations can
be performed. Any given Stream can potentially have an unlimited amount of data flowing through
it. As a result, data received from a Stream is processed individually as it arrives, as opposed to
performing batch processing on the data altogether. When combined with lambda expressions
they provide a concise way to perform operations on sequences of data using a functional
approach.
Output:
APPLE
BANANA
https://riptutorial.com/ 1007
ORANGE
PEAR
1. Create a Stream<String> containing a sequenced ordered Stream of fruit String elements using
the static factory method Stream.of(values).
2. The filter() operation retains only elements that match a given predicate (the elements that
when tested by the predicate return true). In this case, it retains the elements containing an
"a". The predicate is given as a lambda expression.
3. The map() operation transforms each element using a given function, called a mapper. In this
case, each fruit String is mapped to its uppercase String version using the method-reference
String::toUppercase.
Note that the map() operation will return a stream with a different generic type if
the mapping function returns a type different to its input parameter. For example
on a Stream<String> calling .map(String::isEmpty) returns a Stream<Boolean>
4. The sorted() operation sorts the elements of the Stream according to their natural ordering
(lexicographically, in the case of String).
5. Finally, the forEach(action) operation performs an action which acts on each element of the
Stream, passing it to a Consumer. In the example, each element is simply being printed to the
console. This operation is a terminal operation, thus making it impossible to operate on it
again.
Note that operations defined on the Stream are performed because of the terminal
operation. Without a terminal operation, the stream is not processed. Streams
can not be reused. Once a terminal operation is called, the Stream object
becomes unusable.
Operations (as seen above) are chained together to form what can be seen as a query on the
data.
Closing Streams
Note that a Stream generally does not have to be closed. It is only required to close
streams that operate on IO channels. Most Stream types don't operate on resources
https://riptutorial.com/ 1008
and therefore don't require closing.
The Stream interface extends AutoCloseable. Streams can be closed by calling the close method or
by using try-with-resource statements.
An example use case where a Stream should be closed is when you create a Stream of lines from a
file:
The Stream interface also declares the Stream.onClose() method which allows you to register
Runnable handlers which will be called when the stream is closed. An example use case is where
code which produces a stream needs to know when it is consumed to perform some cleanup.
The run handler will only execute if the close() method gets called, either explicitly or implicitly by
a try-with-resources statement.
Processing Order
A Stream object's processing can be sequential or parallel.
In a sequential mode, the elements are processed in the order of the source of the Stream. If the
Stream is ordered (such as a SortedMap implementation or a List) the processing is guaranteed to
match the ordering of the source. In other cases, however, care should be taken not to depend on
the ordering (see: is the Java HashMap keySet() iteration order consistent?).
Example:
// sequential
long howManyOddNumbers = integerList.stream()
.filter(e -> (e % 2) == 1)
.count();
System.out.println(howManyOddNumbers); // Output: 2
Live on Ideone
Parallel mode allows the use of multiple threads on multiple cores but there is no guarantee of the
order in which elements are processed.
If multiple methods are called on a sequential Stream, not every method has to be invoked. For
https://riptutorial.com/ 1009
example, if a Stream is filtered and the number of elements is reduced to one, a subsequent call to
a method such as sort will not occur. This can increase the performance of a sequential Stream —
an optimization that is not possible with a parallel Stream.
Example:
// parallel
long howManyOddNumbersParallel = integerList.parallelStream()
.filter(e -> (e % 2) == 1)
.count();
System.out.println(howManyOddNumbersParallel); // Output: 2
Live on Ideone
System.out.println(Arrays
.asList("apple", "banana", "pear", "kiwi", "orange")
.stream()
.filter(s -> s.contains("a"))
.collect(Collectors.toList())
);
// prints: [apple, banana, pear, orange]
Other collection instances, such as a Set, can be made by using other Collectors built-in methods.
For example, Collectors.toSet() collects the elements of a Stream into a Set.
https://riptutorial.com/ 1010
For explicit control over the implementation to be returned, Collectors#toCollection(Supplier) can
be used instead, where the given supplier returns a new and empty collection.
Collector accumulates elements into a Map, Where key is the Student Id and Value is Student
Value.
Output :
The mergeFunction often looks like: (s1, s2) -> s1 to retain value corresponding to the repeated
key, or (s1, s2) -> s2 to put new value for the repeated key.
Often it requires to make a map of list out of a primary list. Example: From a student of list, we
need to make a map of list of subjects for each student.
https://riptutorial.com/ 1011
list.add(new Student("Davis", SUBJECT.GEOGRAPHY, 37.0));
Output:
{ Robert=[LITERATURE],
Sascha=[ENGLISH, MATH, SCIENCE, LITERATURE],
Davis=[MATH, SCIENCE, GEOGRAPHY] }
list.stream().forEach(student -> {
map.computeIfAbsent(student.getName(), s -> new HashMap<>())
.computeIfAbsent(student.getSubject(), s -> new ArrayList<>())
.add(student.getMarks());
});
System.out.println(map);
Output:
{ Robert={ENGLISH=[12.0]},
Sascha={MATH=[80.0, 50.0], ENGLISH=[85.0, 12.0]},
Davis={MATH=[35.0, 37.0], SCIENCE=[12.9, 37.0]} }
Cheat-Sheet
https://riptutorial.com/ 1012
Goal Code
Infinite Streams
It is possible to generate a Stream that does not end. Calling a terminal method on an infinite Stream
causes the Stream to enter an infinite loop. The limit method of a Stream can be used to limit the
number of terms of the Stream that Java processes.
This example generates a Stream of all natural numbers, starting with the number 1. Each
successive term of the Stream is one higher than the previous. By calling the limit method of this
Stream, only the first five terms of the Stream are considered and printed.
Output:
1
2
3
4
5
https://riptutorial.com/ 1013
Another way of generating an infinite stream is using the Stream.generate method. This method
takes a lambda of type Supplier.
Consuming Streams
A Stream will only be traversed when there is a terminal operation, like count(), collect() or
forEach(). Otherwise, no operation on the Stream will be performed.
In the following example, no terminal operation is added to the Stream, so the filter() operation
will not be invoked and no output will be produced because peek() is NOT a terminal operation.
Live on Ideone
This is a Stream sequence with a valid terminal operation, thus an output is produced.
Live on Ideone
Output:
2
4
6
8
After the terminal operation is performed, the Stream is consumed and cannot be reused.
Although a given stream object cannot be reused, it's easy to create a reusable Iterable that
delegates to a stream pipeline. This can be useful for returning a modified view of a live data set
without having to collect results into a temporary structure.
https://riptutorial.com/ 1014
}
Output:
foo
bar
foo
bar
This works because Iterable declares a single abstract method Iterator<T> iterator(). That
makes it effectively a functional interface, implemented by a lambda that creates a new stream on
each call.
NOTE: Argument checks are always performed, even without a terminal operation:
try {
IntStream.range(1, 10).filter(null);
} catch (NullPointerException e) {
System.out.println("We got a NullPointerException as null was passed as an argument to
filter()");
}
Live on Ideone
Output:
The groupingBy(classifier, downstream) collector allows the collection of Stream elements into a Map
by classifying each element in a group and performing a downstream operation on the elements
classified in the same group.
A classic example of this principle is to use a Map to count the occurrences of elements in a Stream.
In this example, the classifier is simply the identity function, which returns the element as-is. The
downstream operation counts the number of equal elements, using counting().
https://riptutorial.com/ 1015
.entrySet()
.forEach(System.out::println);
banana=1
orange=1
apple=2
Parallel Stream
Note: Before deciding which Stream to use please have a look at ParallelStream vs Sequential
Stream behavior.
When you want to perform Stream operations concurrently, you could use either of these ways.
Or:
To execute the operations defined for the parallel stream, call a terminal operator:
aParallelStream.forEach(System.out::println);
Three
Four
One
Two
Five
The order might change as all the elements are processed in parallel (Which may make it faster).
Use parallelStream when ordering does not matter.
Performance impact
In case networking is involved, parallel Streams may degrade the overall performance of an
application because all parallel Streams use a common fork-join thread pool for the network.
On the other hand, parallel Streams may significantly improve performance in many other cases,
https://riptutorial.com/ 1016
depending of the number of available cores in the running CPU at the moment.
You may need to convert a Stream emitting Optional to a Stream of values, emitting only values from
existing Optional. (ie: without null value and not dealing with Optional.empty()).
Creating a Stream
All java Collection<E>s have stream() and parallelStream() methods from which a Stream<E> can be
constructed:
The difference between Arrays.stream() and Stream.of() is that Stream.of() has a varargs
parameter, so it can be used like:
There are also primitive Streams that you can use. For example:
These primitive streams can also be constructed using the Arrays.stream() method:
https://riptutorial.com/ 1017
Note that any primitive stream can be converted to boxed type stream using the boxed method :
This can be useful in some case if you want to collect the data since primitive stream does not
have any collect method that takes a Collector as argument.
Stream is closed when ever terminal operation is called. Reusing the stream of intermediate
operations, when only terminal operation is only varying. we could create a stream supplier to
construct a new stream with all intermediate operations already set up.
// APPLE
// BANANA
// BLACKBERRY
// BLUEBERRY
Java SE 8
Java SE 8
https://riptutorial.com/ 1018
Get a Slice of a Stream
Example: Get a Stream of 30 elements, containing 21st to 50th (inclusive) element of a collection.
Notes:
Concatenate Streams
concat1.forEach(System.out::print);
// prints: abc123
System.out.println(concat2.collect(Collectors.joining(", ")));
// prints: a, b, c, 1, 2, 3, alpha, beta, gamma
Alternatively to simplify the nested concat() syntax the Streams can also be concatenated with
flatMap():
System.out.println(concat3.collect(Collectors.joining(", ")));
// prints: a, b, c, 1, 2, 3, alpha, beta, gamma
https://riptutorial.com/ 1019
Be careful when constructing Streams from repeated concatenation, because accessing an
element of a deeply concatenated Stream can result in deep call chains or even a
StackOverflowException.
IntStream to String
Java does not have a Char Stream, so when working with Strings and constructing a Stream of
Characters, an option is to get a IntStream of code points using String.codePoints() method. So
IntStream can be obtained as below:
It is a bit more involved to do the conversion other way around i.e. IntStreamToString. That can be
done as follows:
System.out.println(data);
System.out.println(sortedData);
Output:
It's also possible to use different comparison mechanism as there is a overloaded sorted version
which takes a comparator as its argument.
https://riptutorial.com/ 1020
This would output [Sydney, New York, Mumbai, London, California, Amsterdam]
You can use Comparator.reverseOrder() to have a comparator that imposes the reverse of the
natural ordering.
List<String> reverseSortedData =
data.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
Streams of Primitives
Java provides specialized Streams for three types of primitives IntStream (for ints), LongStream (for
longs) and DoubleStream (for doubles). Besides being optimized implementations for their respective
primitives, they also provide several specific terminal methods, typically for mathematical
operations. E.g.:
Analog to get a collection for a Stream by collect() an array can be obtained by the
Stream.toArray() method:
For this example, we will find the first Integer whose square is over 50000.
Note that with an infinite Stream, Java will keep checking each element until it finds a result. With a
finite Stream, if Java runs out of elements but still can't find a result, it returns an empty OptionalInt.
https://riptutorial.com/ 1021
Using IntStream to iterate over indexes
Streams of elements usually do not allow access to the index value of the current item. To iterate
over an array or ArrayList while having access to indexes, use IntStream.range(start,
endExclusive).
IntStream.range(0, names.length)
.mapToObj(i -> String.format("#%d %s", i + 1, names[i]))
.forEach(System.out::println);
The range(start, endExclusive) method returns another ÌntStream and the mapToObj(mapper) returns
a stream of String.
Output:
#1 Jon
#2 Darin
#3 Bauke
#4 Hans
#5 Marc
This is very similar to using a normal for loop with a counter, but with the benefit of pipelining and
parallelization:
A Stream of items that are in turn streamable can be flattened into a single continuous Stream:
https://riptutorial.com/ 1022
List<Integer> allValues = map.values() // Collection<List<Integer>>
.stream() // Stream<List<Integer>>
.flatMap(List::stream) // Stream<Integer>
.collect(Collectors.toList());
System.out.println(allValues);
// [1, 2, 3, 4, 5, 6]
To make things more declarative, we can use static method in Function interface -
Function.identity(). We can replace this lambda element -> element with Function.identity().
https://riptutorial.com/ 1023
.collect(Collectors.toMap(
element -> element.hashCode(),
element -> element,
(existingVal, newVal) -> (existingVal + newVal)));
The BinaryOperator passed to Collectors.toMap(...) generates the value to be stored in the case of
a collision. It can:
• return the old value, so that the first value in the stream takes precedence,
• return the new value, so that the last value in the stream takes precedence, or
• combine the old and new values
Grouping by value
You can use Collectors.groupingBy when you need to perform the equivalent of a database
cascaded "group by" operation. To illustrate, the following creates a map in which people's names
are mapped to surnames:
Live on Ideone
First we need to initialize a random number generator. To enhance security for the generated
Strings, it is a good idea to use SecureRandom.
Note: Creating a SecureRandom is quite expensive, so it is best practice to only do this once and call
one of its setSeed() methods from time to time to reseed it.
https://riptutorial.com/ 1024
//20 Bytes as a seed is rather arbitrary, it is the number used in the JavaDoc example
When creating random Strings, we usually want them to use only certain characters (e.g. only
letters and digits). Therefore we can create a method returning a boolean which can later be used
to filter the Stream.
Next we can utilize the RNG to generate a random String of specific length containing the charset
which pass our useThisCharacter check.
//now we can use this Stream to build a String utilizing the collect method.
String randomString = randomCharStream.collect(StringBuilder::new, StringBuilder::append,
StringBuilder::append).toString();
return randomString;
}
Streams,and especially IntStreams, are an elegant way of implementing summation terms (∑). The
ranges of the Stream can be used as the bounds of the summation.
This can be calculated with an arbitrary precision. E.g., for 101 terms:
double pi = Math.sqrt(12) *
IntStream.rangeClosed(0, 100)
.mapToDouble(k -> Math.pow(-3, -1 * k) / (2 * k + 1))
.sum();
Note: With double's precision, selecting an upper bound of 29 is sufficient to get a result that's
indistinguishable from Math.Pi.
https://riptutorial.com/ 1025
Method references make excellent self-documenting code, and using method references with
Streams makes complicated processes simple to read and understand. Consider the following
code:
This last method rewritten using Streams and method references is much more legible and each
step of the process is quickly and easily understood - it's not just shorter, it also shows at a glance
which interfaces and classes are responsible for the code in each step:
https://riptutorial.com/ 1026
When you have a Stream you need to map but want to preserve the initial values as well, you can
map the Stream to a Map.Entry<K,V> using a utility method like the following:
public static <K, V> Function<K, Map.Entry<K, V>> entryMapper(Function<K, V> mapper){
return (k)->new AbstractMap.SimpleEntry<>(k, mapper.apply(k));
}
Then you can use your converter to process Streams having access to both the original and
mapped values:
Set<K> mySet;
Function<K, V> transformer = SomeClass::transformerMethod;
Stream<Map.Entry<K, V>> entryStream = mySet.stream()
.map(entryMapper(transformer));
You can then continue to process that Stream as normal. This avoids the overhead of creating an
intermediate collection.
Stream operations fall into two main categories, intermediate and terminal operations, and two
sub-categories, stateless and stateful.
Intermediate Operations:
An intermediate operation is always lazy, such as a simple Stream.map. It is not invoked until the
stream is actually consumed. This can be verified easily:
Intermediate operations are the common building blocks of a stream, chained after the source and
are usually followed by a terminal operation triggering the stream chain.
Terminal Operations
Terminal operations are what triggers the consumption of a stream. Some of the more common
are Stream.forEach or Stream.collect. They are usually placed after a chain of intermediate
operations and are almost always eager.
https://riptutorial.com/ 1027
Stateless Operations
Statelessness means that each item is processed without the context of other items. Stateless
operations allow for memory-efficient processing of streams. Operations like Stream.map and
Stream.filter that do not require information on other items of the stream are considered to be
stateless.
Stateful operations
Statefulness means the operation on each item depends on (some) other items of the stream. This
requires a state to be preserved. Statefulness operations may break with long, or infinite, streams.
Operations like Stream.sorted require the entirety of the stream to be processed before any item is
emitted which will break in a long enough stream of items. This can be demonstrated by a long
stream (run at your own risk):
Reduction is the process of applying a binary operator to every element of a stream to result in
one value.
The sum() method of an IntStream is an example of a reduction; it applies addition to every term of
the Stream, resulting in one final value:
https://riptutorial.com/ 1028
This is equivalent to (((1+2)+3)+4)
The reduce method of a Stream allows one to create a custom reduction. It is possible to use the
reduce method to implement the sum() method:
IntStream istr;
//Initialize istr
OptionalInt istr.reduce((a,b)->a+b);
The Optional version is returned so that empty Streams can be handled appropriately.
https://riptutorial.com/ 1029
Stream<LinkedList<T>> listStream;
//Create a Stream<LinkedList<T>>
You can also provide an identity element. For example, the identity element for addition is 0, as
x+0==x. For multiplication, the identity element is 1, as x*1==x. In the case above, the identity
element is an empty LinkedList<T>, because if you add an empty list to another list, the list that you
are "adding" to doesn't change:
Stream<LinkedList<T>> listStream;
//Create a Stream<LinkedList<T>>
Note that when an identity element is provided, the return value is not wrapped in an Optional—if
called on an empty stream, reduce() will return the identity element.
The binary operator must also be associative, meaning that (a+b)+c==a+(b+c). This is because the
elements may be reduced in any order. For example, the above addition reduction could be
performed like this:
https://riptutorial.com/ 1030
This reduction is equivalent to writing ((1+2)+(3+4)). The property of associativity also allows Java
to reduce the Stream in parallel—a portion of the Stream can be reduced by each processor, with a
reduction combining the result of each processor at the end.
A use case that comes across frequently, is creating a String from a stream, where the stream-
items are separated by a certain character. The Collectors.joining() method can be used for this,
like in the following example:
System.out.println(result);
Output:
The Collectors.joining() method can also cater for pre- and postfixes:
https://riptutorial.com/ 1031
String result = fruitStream.filter(s -> s.contains("e"))
.map(String::toUpperCase)
.sorted()
.collect(Collectors.joining(", ", "Fruits: ", "."));
System.out.println(result);
Output:
Live on Ideone
https://riptutorial.com/ 1032
Chapter 163: String Tokenizer
Introduction
The java.util.StringTokenizer class allows you to break a string into tokens. It is simple way to
break string.
The set of delimiters (the characters that separate tokens) may be specified either at creation time
or on a per-token basis.
Examples
StringTokenizer Split by space
import java.util.StringTokenizer;
public class Simple{
public static void main(String args[]){
StringTokenizer st = new StringTokenizer("apple ball cat dog"," ");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
}
}
Output:
apple
ball
cat
dog
Output:
apple
ball cat
https://riptutorial.com/ 1033
dog
https://riptutorial.com/ 1034
Chapter 164: StringBuffer
Introduction
Introduction to Java StringBuffer class.
Examples
String Buffer class
Key Points :-
Methods :-
class Test {
public static void main(String args[])
{
String str = "study";
str.concat("tonight");
https://riptutorial.com/ 1035
System.out.println(str); // Output: study
https://riptutorial.com/ 1036
Chapter 165: StringBuilder
Introduction
Java StringBuilder class is used to create mutable (modifiable) string. The Java StringBuilder class
is same as StringBuffer class except that it is non-synchronized. It is available since JDK 1.5.
Syntax
• new StringBuilder ()
Remarks
Creating a new StringBuilder with type char as a parameter would result in calling the constructor
with argument int capacity and not the one with argument String string:
Examples
Repeat a String n times
https://riptutorial.com/ 1037
}
To avoid this StringBuilder should be used, which allows creating the String in O(s.length() * n)
instead:
The StringBuffer, StringBuilder, Formatter and StringJoiner classes are Java SE utility classes that
are primarily used for assembling strings from other information:
• The StringBuffer class has been present since Java 1.0, and provides a variety of methods
for building and modifying a "buffer" containing a sequence of characters.
• The StringBuilder class was added in Java 5 to address performance issues with the original
StringBuffer class. The APIs for the two clases are essentially the same. The main
difference between StringBuffer and StringBuilder is that the former is thread-safe and
synchronized and the latter is not.
int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.
(The StringBuffer class is used the same way: just change StringBuilder to StringBuffer in the
above)
The StringBuffer and StringBuilder classes are suitable for both assembling and modifying strings;
i.e they provide methods for replacing and removing characters as well as adding them in various.
The remining two classes are specific to the task of assembling strings.
• The Formatter class was added in Java 5, and is loosely modeled on the sprintf function in
the C standard library. It takes a format string with embedded format specifiers and a
sequences of other arguments, and generates a string by converting the arguments into text
https://riptutorial.com/ 1038
and substituting them in place of the format specifiers. The details of the format specifiers
say how the arguments are converted into text.
• The StringJoiner class was added in Java 8. It is a special purpose formatter that succinctly
formats a sequence of strings with separators between them. It is designed with a fluent API,
and can be used with Java 8 streams.
The StringJoiner class is not ideal for the above task, so here is an example of a formatting an
array of strings.
https://riptutorial.com/ 1039
Chapter 166: Strings
Introduction
Strings (java.lang.String) are pieces of text stored in your program. Strings are not a primitive
data type in Java, however, they are very common in Java programs.
In Java, Strings are immutable, meaning that they cannot be changed. (Click here for a more
thorough explanation of immutability.)
Remarks
Since Java strings are immutable, all methods which manipulate a String will return a new String
object. They do not change the original String. This includes to substring and replacement
methods that C and C++ programers would expect to mutate the target String object.
Use a StringBuilder instead of String if you want to concatenate more than two String objects
whose values cannot be determined at compile-time. This technique is more performant than
creating new String objects and concatenating them because StringBuilder is mutable.
StringBuffer can also be used to concatenate String objects. However, this class is less
performant because it is designed to be thread-safe, and acquires a mutex before each operation.
Since you almost never need thread-safety when concatenating strings, it is best to use
StringBuilder.
If you can express a string concatenation as a single expression, then it is better to use the +
operator. The Java compiler will convert an expression containing + concatenations into an
efficient sequence of operations using either String.concat(...) or StringBuilder. The advice to
use StringBuilder explicitly only applies when the concatenation involves a multiple expressions.
Don't store sensitive information in strings. If someone is able to obtain a memory dump of your
running application, then they will be able to find all of the existing String objects and read their
contents. This includes String objects that are unreachable and are awaiting garbage collection. If
this is a concern, you will need to wipe sensitive string data as soon as you are done with it. You
cannot do this with String objects since they are immutable. Therefore, it is advisable to use a
char[] objects to hold sensitive character data, and wipe them (e.g. overwrite them with '\000'
characters) when you are done.
All String instances are created on the heap, even instances that correspond to string literals. The
special thing about string literals is that the JVM ensures that all literals that are equal (i.e. that
consists of the same characters) are represented by a single String object (this behavior is
specified in JLS). This is implemented by JVM class loaders. When a class loader loads a class, it
scans for string literals that are used in the class definition, each time it sees one, it checks if there
https://riptutorial.com/ 1040
is already a record in the string pool for this literal (using the literal as a key). If there is already an
entry for the literal, the reference to a String instance stored as the pair for that literal is used.
Otherwise, a new String instance is created and a reference to the instance is stored for the literal
(used as a key) in the string pool. (Also see string interning).
The string pool is held in the Java heap, and is subject to normal garbage collection.
Java SE 7
In releases of Java before Java 7, the string pool was held in a special part of the heap known as
"PermGen". This part was only collected occasionally.
Java SE 7
Note that string literals are implicitly reachable from any method that uses them. This means that
the corresponding String objects can only be garbage collected if the code itself is garbage
collected.
Up until Java 8, String objects are implemented as a UTF-16 char array (2 bytes per char). There
is a proposal in Java 9 to implement String as a byte array with an encoding flag field to note if the
string is encoded as bytes (LATIN-1) or chars (UTF-16).
Examples
Comparing Strings
In order to compare Strings for equality, you should use the String object's equals or
equalsIgnoreCase methods.
For example, the following snippet will determine if the two instances of String are equal on all
characters:
if (firstString.equals(secondString)) {
// Both Strings have the same content.
}
Live demo
if (firstString.equalsIgnoreCase(secondString)) {
https://riptutorial.com/ 1041
// Both Strings are equal, ignoring the case of the individual characters.
}
Live demo
Note that equalsIgnoreCase does not let you specify a Locale. For instance, if you compare the two
words "Taki" and "TAKI" in English they are equal; however, in Turkish they are different (in
Turkish, the lowercase I is ı). For cases like this, converting both strings to lowercase (or
uppercase) with Locale and then comparing with equals is the solution.
System.out.println(firstString.toLowerCase(locale).equals(
secondString.toLowerCase(locale))); //prints false
Live demo
Instead, use the String.equals(Object) method, which will compare the String objects based on
their values. For a detailed explanation, please refer to Pitfall: using == to compare strings.
As of Java 1.7, it is possible to compare a String variable to literals in a switch statement. Make
sure that the String is not null, otherwise it will always throw a NullPointerException. Values are
compared using String.equals, i.e. case sensitive.
switch (stringToSwitch) {
case "a":
System.out.println("a");
break;
https://riptutorial.com/ 1042
case "A":
System.out.println("A"); //the code goes here
break;
case "B":
System.out.println("B");
break;
default:
break;
}
Live demo
"baz".equals(foo)
Java SE 7
A more readable alternative is to use Objects.equals(), which does a null check on both
parameters: Objects.equals(foo, "baz").
String orderings
The String class implements Comparable<String> with the String.compareTo method (as described at
the start of this example). This makes the natural ordering of String objects case-sensitive order.
The String class provide a Comparator<String> constant called CASE_INSENSITIVE_ORDER suitable for
case-insensitive sorting.
"Moreover, a string literal always refers to the same instance of class String. This is
because string literals - or, more generally, strings that are the values of constant
expressions - are interned so as to share unique instances, using the method
String.intern."
https://riptutorial.com/ 1043
This means it is safe to compare references to two string literals using ==. Moreover, the same is
true for references to String objects that have been produced using the String.intern() method.
For example:
// The two string references point two strings that are equal
if (strObj.equals(str)) {
System.out.println("The strings are equal");
}
if (internedStr == str) {
System.out.println("The interned string and the literal are the same object");
}
Behind the scenes, the interning mechanism maintains a hash table that contains all interned
strings that are still reachable. When you call intern() on a String, the method looks up the object
in the hash table:
• If the string is found, then that value is returned as the interned string.
• Otherwise, a copy of the string is added to the hash table and that string is returned as the
interned string.
It is possible to use interning to allow strings to be compared using ==. However, there are
significant problems with doing this; see Pitfall - Interning strings so that you can use == is a bad
idea for details. It is not recommended in most cases.
The String type provides two methods for converting strings between upper case and lower case:
These methods both return the converted strings as new String instances: the original String
objects are not modified because String is immutable in Java. See this for more on immutability :
Immutability of Strings in Java
https://riptutorial.com/ 1044
System.out.println(string); // prints "This is a Random String"
System.out.println(lower); // prints "this is a random string"
System.out.println(upper); // prints "THIS IS A RANDOM STRING"
Non-alphabetic characters, such as digits and punctuation marks, are unaffected by these
methods. Note that these methods may also incorrectly deal with certain Unicode characters
under certain conditions.
Note: These methods are locale-sensitive, and may produce unexpected results if used on strings
that are intended to be interpreted independent of the locale. Examples are programming
language identifiers, protocol keys, and HTML tags.
For instance, "TITLE".toLowerCase() in a Turkish locale returns "tıtle", where ı (\u0131) is the
LATIN SMALL LETTER DOTLESS I character. To obtain correct results for locale insensitive
strings, pass Locale.ROOT as a parameter to the corresponding case converting method (e.g.
toLowerCase(Locale.ROOT) or toUpperCase(Locale.ROOT)).
Although using Locale.ENGLISH is also correct for most cases, the language invariant way is
Locale.ROOT.
A detailed list of Unicode characters that require special casing can be found on the Unicode
Consortium website.
To change the case of a specific character of an ASCII string following algorithm can be used:
Steps:
1. Declare a string.
2. Input the string.
3. Convert the string into a character array.
4. Input the character that is to be searched.
5. Search for the character into the character array.
6. If found,check if the character is lowercase or uppercase.
• If Uppercase, add 32 to the ASCII code of the character.
• If Lowercase, subtract 32 from the ASCII code of the character.
7. Change the original character from the Character array.
8. Convert the character array back into the string.
https://riptutorial.com/ 1045
String c = scanner.next();
char d = c.charAt(0);
To check whether a particular String a is being contained in a String b or not, we can use the
method String.contains() with the following syntax:
The String.contains() method can be used to verify if a CharSequence can be found in the String.
The method looks for the String a in the String b in a case-sensitive way.
To find the exact position where a String starts within another String, use String.indexOf():
The String.indexOf() method returns the first index of a char or String in another String. The
method returns -1 if it is not found.
https://riptutorial.com/ 1046
String str1 = "Hello World";
String str2 = "wOr";
str1.indexOf(str2); // -1
str1.toLowerCase().contains(str2.toLowerCase()); // true
str1.toLowerCase().indexOf(str2.toLowerCase()); // 6
In order to get the length of a String object, call the length() method on it. The length is equal to
the number of UTF-16 code units (chars) in the string.
A char in a String is UTF-16 value. Unicode codepoints whose values are ≥ 0x1000 (for example,
most emojis) use two char positions. To count the number of Unicode codepoints in a String,
regardless of whether each codepoint fits in a UTF-16 char value, you can use the codePointCount
method:
Substrings
Substrings may also be applied to slice and add/replace character into its original String. For
instance, you faced a Chinese date containing Chinese characters but you want to store it as a
well format Date String.
The substring method extracts a piece of a String. When provided one parameter, the parameter
https://riptutorial.com/ 1047
is the start and the piece extends until the end of the String. When given two parameters, the first
parameter is the starting character and the second parameter is the index of the character right
after the end (the character at the index is not included). An easy way to check is the subtraction
of the first parameter from the second should yield the expected length of the string.
Java SE 7
In JDK <7u6 versions the substring method instantiates a String that shares the same backing
char[] as the original String and has the internal offset and count fields set to the result start and
length. Such sharing may cause memory leaks, that can be prevented by calling new
String(s.substring(...)) to force creation of a copy, after which the char[] can be garbage
collected.
Java SE 7
From JDK 7u6 the substring method always copies the entire underlying char[] array, making the
complexity linear compared to the previous constant one but guaranteeing the absence of memory
leaks at the same time.
System.out.println(str.charAt(0)); // "M"
System.out.println(str.charAt(1)); // "y"
System.out.println(str.charAt(2)); // " "
System.out.println(str.charAt(str.length-1)); // Last character "g"
To get the nth character in a string, simply call charAt(n) on a String, where n is the index of the
character you would like to retrieve
Since the new line separator varies from platform to platform (e.g. \n on Unix-like systems or \r\n
on Windows) it is often necessary to have a platform-independent way of accessing it. In Java it
can be retrieved from a system property:
System.getProperty("line.separator")
Java SE 7
Because the new line separator is so commonly needed, from Java 7 on a shortcut method
returning exactly the same result as the code above is available:
System.lineSeparator()
Note: Since it is very unlikely that the new line separator changes during the program's execution,
https://riptutorial.com/ 1048
it is a good idea to store it in in a static final variable instead of retrieving it from the system
property every time it is needed.
When using String.format, use %n rather than \n or '\r\n' to output a platform independent new line
separator.
String name;
int age;
and later in your code you use the following statement in order to print the object:
System.out.println(person.toString());
Person@7ab89d
This is the result of the implementation of the toString() method defined in the Object class, a
superclass of Person. The documentation of Object.toString() states:
The toString method for class Object returns a string consisting of the name of the
class of which the object is an instance, the at-sign character `@', and the unsigned
hexadecimal representation of the hash code of the object. In other words, this method
returns a string equal to the value of:
So, for meaningful output, you'll have to override the toString() method:
https://riptutorial.com/ 1049
@Override
public String toString() {
return "My name is " + this.name + " and my age is " + this.age;
}
System.out.println(person);
Splitting Strings
You can split a String on a particular delimiting character or a Regular Expression, you can use
the String.split() method that has the following signature:
Note that delimiting character or regular expression gets removed from the resulting String Array.
Warning: Do not forget that the parameter is always treated as a regular expression.
In the previous example . is treated as the regular expression wildcard that matches any
character, and since every character is a delimiter, the result is an empty array.
https://riptutorial.com/ 1050
Splitting based on a delimiter which is a regex meta-character
< > - = ! ( ) [ ] { } \ ^ $ | ? * + .
To split a string based on one of the above delimiters, you need to either escape them using \\ or
use Pattern.quote():
• Using Pattern.quote():
String s = "a|b|c";
String regex = Pattern.quote("|");
String[] arr = s.split(regex);
String s = "a|b|c";
String[] arr = s.split("\\|");
split(delimiter) by default removes trailing empty strings from result array. To turn this
mechanism off we need to use overloaded version of split(delimiter, limit) with limit set to
negative value like
The limit parameter controls the number of times the pattern is applied and therefore affects the
length of the resulting array.
If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's
length will be no greater than n, and the array's last entry will contain all input beyond the last
matched delimiter.
If n is negative, then the pattern will be applied as many times as possible and the array can have
any length.
If n is zero then the pattern will be applied as many times as possible, the array can have any
length, and trailing empty strings will be discarded.
Besides the split() method Strings can also be split using a StringTokenizer.
StringTokenizer is even more restrictive than String.split(), and also a bit harder to use. It is
essentially designed for pulling out tokens delimited by a fixed set of characters (given as a String
). Each character will act as a separator. Because of this restriction, it's about twice as fast as
https://riptutorial.com/ 1051
String.split().
Default set of characters are empty spaces (\t\n\r\f). The following example will print out each
word separately.
String str = "the lazy fox jumped over the brown fence";
StringTokenizer tokenizer = new StringTokenizer(str);
while (tokenizer.hasMoreTokens()) {
System.out.println(tokenizer.nextToken());
}
the
lazy
fox
jumped
over
the
brown
fence
j
mp
d ov
r
Java SE 8
https://riptutorial.com/ 1052
To have a fine-grained control over joining, you may use StringJoiner class:
sj.add("foo");
sj.add("bar");
sj.add("foobar");
Reversing Strings
There are a couple ways you can reverse a string to make it backwards.
1. StringBuilder/StringBuffer:
System.out.println(code);
2. Char array:
// print reversed
System.out.println(new String(array));
https://riptutorial.com/ 1053
Counting occurrences of a substring or character in a string
import org.apache.commons.lang3.StringUtils;
String text = "One fish, two fish, red fish, blue fish";
Otherwise for does the same with standard Java API's you could use Regular Expressions:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
String text = "One fish, two fish, red fish, blue fish";
System.out.println(countStringInString("fish", text)); // prints 4
System.out.println(countStringInString(",", text)); // prints 3
int stringOccurrences = 0;
while (matcher.find()) {
stringOccurrences++;
}
return stringOccurrences;
}
String s1 = "a";
String s2 = "b";
String s3 = "c";
String s = s1 + s2 + s3; // abc
Normally a compiler implementation will perform the above concatenation using methods involving
a StringBuilder under the hood. When compiled, the code would look similar to the below:
StringBuilder has several overloaded methods for appending different types, for example, to
https://riptutorial.com/ 1054
append an int instead of a String. For example, an implementation can convert:
String s1 = "a";
String s2 = "b";
String s = s1 + s2 + 2; // ab2
to the following:
The above examples illustrate a simple concatenation operation that is effectively done in a single
place in the code. The concatenation involves a single instance of the StringBuilder. In some
cases, a concatenation is carried out in a cumulative way such as in a loop:
In such cases, the compiler optimization is usually not applied, and each iteration will create a new
StringBuilder object. This can be optimized by explicitly transforming the code to use a single
StringBuilder:
A StringBuilder will be initialized with an empty space of only 16 characters. If you know in
advance that you will be building larger strings, it can be beneficial to initialize it with sufficient size
in advance, so that the internal buffer does not need to be resized:
If (and only if) multiple threads are writing to the same buffer, use StringBuffer, which is a
synchronized version of StringBuilder. But because usually only a single thread writes to a buffer, it
https://riptutorial.com/ 1055
is usually faster to use StringBuilder without synchronization.
This returns a new string that is string1 with string2 added to it at the end. You can also use the
concat() method with string literals, as in:
Note: the original String object will be unchanged, the return value holds the changed String.
Exact match
Replace single character with another single character:
Returns a new string resulting from replacing all occurrences of oldChar in this string
with newChar.
String s = "popcorn";
System.out.println(s.replace('p','W'));
Result:
WoWcorn
Replaces each substring of this string that matches the literal target sequence with the
specified literal replacement sequence.
Result:
https://riptutorial.com/ 1056
metallica petallica et al.
Regex
Note: the grouping uses the $ character to reference the groups, like $1.
Replaces each substring of this string that matches the given regular expression with
the given replacement.
Result:
Replaces the first substring of this string that matches the given regular expression
with the given replacement
Result:
The trim() method returns a new String with the leading and trailing whitespace removed.
If you trim a String that doesn't have any whitespace to remove, you will be returned the same
String instance.
Note that the trim() method has its own notion of whitespace, which differs from the notion used
by the Character.isWhitespace() method:
https://riptutorial.com/ 1057
• All ASCII control characters with codes U+0000 to U+0020 are considered whitespace and are
removed by trim(). This includes U+0020 'SPACE', U+0009 'CHARACTER TABULATION', U+000A 'LINE
FEED' and U+000D 'CARRIAGE RETURN' characters, but also the characters like U+0007 'BELL'.
• Unicode whitespace like U+00A0 'NO-BREAK SPACE' or U+2003 'EM SPACE' are not recognized by
trim().
Like many Java objects, all String instances are created on the heap, even literals. When the JVM
finds a String literal that has no equivalent reference in the heap, the JVM creates a
corresponding String instance on the heap and it also stores a reference to the newly created
String instance in the String pool. Any other references to the same String literal are replaced with
the previously created String instance in the heap.
class Strings
{
public static void main (String[] args)
{
String a = "alpha";
String b = "alpha";
String c = new String("alpha");
true
true
true
true
https://riptutorial.com/ 1058
When we use double quotes to create a String, it first looks for String with same value in the String
pool, if found it just returns the reference else it creates a new String in the pool and then returns
the reference.
However using new operator, we force String class to create a new String object in heap space.
We can use intern() method to put it into the pool or refer to other String object from string pool
having same value.
Java SE 7
Before Java 7, String literals were stored in the runtime constant pool in the method area of
PermGen, that had a fixed size.
Java SE 7
https://riptutorial.com/ 1059
RFC: 6962931
In JDK 7, interned strings are no longer allocated in the permanent generation of the
Java heap, but are instead allocated in the main part of the Java heap (known as the
young and old generations), along with the other objects created by the application.
This change will result in more data residing in the main Java heap, and less data in
the permanent generation, and thus may require heap sizes to be adjusted. Most
applications will see only relatively small differences in heap usage due to this change,
but larger applications that load many classes or make heavy use of the
String.intern() method will see more significant differences.
Java SE 7
itself can not be parameterised to be case insensitive, but if absolutely required, can
switch
behave insensitive to the input string by using toLowerCase() or toUpperCase:
switch (myString.toLowerCase()) {
case "case1" :
...
break;
case "case2" :
...
break;
}
Beware
https://riptutorial.com/ 1060
Chapter 167: sun.misc.Unsafe
Remarks
The Unsafe class allows a program to do things that are not allowed by the Java compiler. Normal
programs should avoid using Unsafe.
WARNINGS
1. If you make a mistake using the Unsafe APIs, your applications are liable to cause the JVM to
crash and/or exhibit symptoms that are hard to diagnose.
2. The Unsafe API is subject to change without notice. If you use it in your code, you may need
to rewrite the code when changing Java versions.
Examples
Instantiating sun.misc.Unsafe via reflection
sun.misc.Unsafe has a Private constructor, and the static getUnsafe() method is guarded with a
check of the classloader to ensure that the code was loaded with the primary classloader.
Therefore, one method of loading the instance is to use reflection to get the static field.
While this example will compile, it is likely to fail at runtime unless the Unsafe class was loaded
with the primary classloader. To ensure that happens the JVM should be loaded with the
https://riptutorial.com/ 1061
appropriate arguments, like:
Unsafe is stored as a private field that cannot be accessed directly. The constructor is private and
the only method to access public static Unsafe getUnsafe() has privileged access. By use of
reflection, there is a work-around to make private fields accessible:
static {
Unsafe unsafe = null;
try {
final PrivilegedExceptionAction<Unsafe> action = () -> {
final Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
unsafe = AccessController.doPrivileged(action);
} catch (final Throwable t) {
throw new RuntimeException("Exception accessing Unsafe", t);
}
UNSAFE = unsafe;
}
Uses of Unsafe
Use API
Direct field and or memory access get* and put* family of methods
https://riptutorial.com/ 1062
Use API
The get and put family of methods are relative to a given object. If the object is null then it is
treated as an absolute address.
Some methods are only defined for int and longs. You can use these methods on floats and
doubles using floatToRawIntBits, intBitsToFloat,doubleToRawLongBits,longBitsToDouble`
https://riptutorial.com/ 1063
Chapter 168: super keyword
Examples
Super keyword use with examples
1. Constructor Level
2. Method Level
3. Variable Level
Constructor Level
super keyword is used to call parent class constructor. This constructor can be default constructor
or parameterized constructor.
class Parentclass
{
Parentclass(){
System.out.println("Constructor of Superclass");
}
}
class Subclass extends Parentclass
{
Subclass(){
/* Compile adds super() here at the first line
* of this constructor implicitly
*/
System.out.println("Constructor of Subclass");
}
Subclass(int n1){
/* Compile adds super() here at the first line
* of this constructor implicitly
*/
System.out.println("Constructor with arg");
}
void display(){
System.out.println("Hello");
}
public static void main(String args[]){
// Creating object using default constructor
Subclass obj= new Subclass();
//Calling sub class method
obj.display();
//Creating object 2 using arg constructor
Subclass obj2= new Subclass(10);
obj2.display();
https://riptutorial.com/ 1064
}
}
Note: super() must be the first statement in constructor otherwise we will get the compilation error
message.
Method Level
superkeyword can also be used in case of method overriding. super keyword can be used to
invoke or call parent class method.
class Parentclass
{
//Overridden method
void display(){
System.out.println("Parent class method");
}
}
class Subclass extends Parentclass
{
//Overriding method
void display(){
System.out.println("Child class method");
}
void printMsg(){
//This would call Overriding method
display();
//This would call Overridden method
super.display();
}
public static void main(String args[]){
Subclass obj= new Subclass();
obj.printMsg();
}
}
Note:If there is not method overriding then we do not need to use super keyword to call parent
class method.
Variable Level
super is used to refer immediate parent class instance variable. In case of inheritance, there may
be possibility of base class and derived class may have similar data members.In order to
differentiate between the data member of base/parent class and derived/child class, in the context
of derived class the base class data members must be preceded by super keyword.
https://riptutorial.com/ 1065
{
/* I am declaring the same variable
* num in child class too.
*/
int num=110;
void printNumber(){
System.out.println(num); //It will print value 110
System.out.println(super.num); //It will print value 100
}
public static void main(String args[]){
Subclass obj= new Subclass();
obj.printNumber();
}
}
Note: If we are not writing super keyword before the base class data member name then it will be
referred as current class data member and base class data member are hidden in the context of
derived class.
https://riptutorial.com/ 1066
Chapter 169: The Classpath
Introduction
The classpath lists places where the Java runtime should look for classes and resources. The
classpath is also used by the Java compiler to find previously compiled and external
dependencies.
Remarks
Java class loading
The JVM (Java Virtual Machine) will load classes as and when the classes are required (this is
called lazy-loading). Locations of the classes to be used are specified in three places:-
1. Those required by the Java Platform are loaded first, such as those in the Java Class Library
and it's dependencies.
2. Extension classes are loaded next (i.e. those in jre/lib/ext/)
3. User-defined classes via the classpath are then loaded
Classes are loaded using classes that are subtypes of java.lang.ClassLoader. This described in a
more detail in this Topic: Classloaders.
Classpath
The classpath is a parameter used by the JVM or compiler which specifies the locations of user-
defined classes and packages. This can be set in the command line as with most of these
examples or through an environmental variable (CLASSPATH)
Examples
Different ways to specify the classpath
Note that the -classpath (or -cp) option takes precedence over the CLASSPATH environment
https://riptutorial.com/ 1067
variable.
3. The classpath for an executable JAR file is specified using the Class-Path element in
MANIFEST.MF:
Note that this only applies when the JAR file is executed like this:
In this mode of execution, the -classpath option and the CLASSPATH environment variable
will be ignored, even if the JAR file has no Class-Path element.
If no classpath is specified, then the default classpath is the selected JAR file when using java -
jar, or the current directory otherwise.
Related:
• https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
• http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html
If you want to add all the JARs in directory to the classpath, you can do this concisely using
classpath wildcard syntax; for example:
someFolder/*
This tells the JVM to add all JAR and ZIP files in the someFolder directory to the classpath. This
syntax can be used in a -cp argument, a CLASSPATH environment variable, or a Class-Path attribute
in an executable JAR file's manifest file.See Setting the Class Path: Class Path Wild Cards for
examples and caveats.
Notes:
1. Classpath wildcards were first introduced in Java 6. Earlier versions of Java do not treat "*"
as a wildcard.
2. You cannot put other characters before or after the ""; e.g. "someFolder/.jar" is not a
wildcard.
3. A wildcard matches only files with the suffix ".jar" or ".JAR". ZIP files are ignored, as are JAR
files with a different suffixes.
4. A wildcard matches only JAR files in the directory itself, not in its subdirectories.
5. When a group of JAR files is matched by a wildcard entry, their relative order on the
classpath is not specified.
https://riptutorial.com/ 1068
The classpath is a sequence of entries which are directory pathnames, JAR or ZIP file pathnames,
or JAR / ZIP wildcard specifications.
• For the Class-Path element in a JAR file's MANIFEST.MF, use a single space to separate the
entries.
• When the classpath is specified on the command line, it is simply a matter of using the
appropriate shell quoting. For example:
(The details may depend on the command shell that you use.)
• When the classpath is specified in a JAR file's a "MANIFEST.MF" file, URL encoding must
be used.
Dynamic Classpath
Sometimes, just adding all the JARs from a folder isn't enough, for example when you have native
code and need to select a subset of JARs. In this case, you need two main() methods. The first
one builds a classloader and then uses this classloader to call the second main().
Here is an example which selects the correct SWT native JAR for your platform, adds all your
application's JARs and then invokes the real main() method: Create cross platform Java SWT
Application
It can be useful to load a resource (image, text file, properties, KeyStore, ...) that is packaged
inside a JAR. For this purpose, we can use the Class and ClassLoaders.
program.jar
|
\-com
\-project
|
|-file.txt
\-Test.class
https://riptutorial.com/ 1069
And we want to access the contents of file.txt from the Test class. We can do so by asking the
classloader :
InputStream is = Test.class.getClassLoader().getResourceAsStream("com/project/file.txt");
By using the classloader, we need to specify the fully qualified path of our resource (each
package).
InputStream is = Test.class.getResourceAsStream("file.txt");
Using the class object, the path is relative to the class itself. Our Test.class being in the
com.project package, the same as file.txt, we do not need to specify any path at all.
We can, however, use absolute paths from the class object, like so :
is = Test.class.getResourceAsStream("/com/project/file.txt");
The standard Java toolchain (and 3rd-party tools designed to interoperate with them) have specific
rules for mapping the names of classes to the pathnames of files and other resources that
represent them.
• For classes in the default package, the pathnames are simple filenames.
• For classes in a named package, the package name components map to directories.
• For named nested and inner classes, the filename component is formed by joining the class
names with a $ character.
• For anonymous inner classes, numbers are used in place of names.
https://riptutorial.com/ 1070
The purpose of the classpath is to tell a JVM where to find classes and other resources. The
meaning of the classpath and the search process are intertwined.
The classpath is a form of search path which specifies a sequence of locations to look for
resources. In a standard classpath, these places are either, a directory in the host file system, a
JAR file or a ZIP file. In each cases, the location is the root of a namespace that will be searched.
The standard procedure for searching for a class on the classpath is as follows:
1. Map the class name to a relative classfile pathname RP. The mapping for class names to
class filenames is described elsewhere.
The procedure for searching for a resource on the classpath depends on whether the resource
path is absolute or relative. For an absolute resource path, the procedure is as above. For a
relative resource path resolved using Class.getResource or Class.getResourceAsStream, the path for
the classes package is prepended prior to searching.
(Note these are the procedures implemented by the standard Java classloaders. A custom
classloader might perform the search differently.)
The normal Java classloaders look for classes first in the bootstrap classpath, before checking for
extensions and the application classpath. By default, the bootstrap classpath consists of the "rt.jar"
file and some other important JAR files that are supplied by the JRE installation. These provide all
of the classes in the standard Java SE class library, along with various "internal" implementation
classes.
Under normal circumstances, you don't need to concern yourself with this. By default, commands
like java, javac and so on will use the appropriate versions of the runtime libraries.
Very occasionally, it is necessary to override the normal behavior of the Java runtime by using an
alternative version of a class in the standard libraries. For example, you might encounter a "show
stopper" bug in the runtime libraries that you cannot work around by normal means. In such a
situation, it is possible to create a JAR file containing the altered class and then add it to the
bootstrap classpath which launching the JVM.
The java command provides the following -X options for modifying the bootstrap classpath:
https://riptutorial.com/ 1071
• -Xbootclasspath:<path> replaces the current boot classpath with the path provided.
• -Xbootclasspath/a:<path> appends the provided path to the current boot classpath.
• -Xbootclasspath/p:<path> prepends the provided path to the current boot classpath.
Note that when use the bootclasspath options to replace or override a Java class (etcetera), you
are technically modifying Java. There may be licensing implications if you then distribute your
code. (Refer to the terms and conditions of the Java Binary License ... and consult a lawyer.)
https://riptutorial.com/ 1072
Chapter 170: The Java Command - 'java' and
'javaw'
Syntax
• java [ <opt> ... ] <class-name> [ <argument> ... ]
Remarks
The java command is used for running a Java application from the command line. It is available as
a part of any Java SE JRE or JDK.
On other systems (e.g. Linux, Mac OSX, UNIX) only the java command is provided, and it does
not launch a new console window.
The <opt> symbol in the syntax denotes an option on the java command line. The "Java Options"
and "Heap and stack sizing options" topics cover the most commonly used options. Others are
covered in the JVM Flags topic.
Examples
Running an executable JAR file
Executable JAR files are the simplest way to assemble Java code into a single file that can be
executed. *(Editorial Note: Creation of JAR files should be covered by a separate Topic.) *
Assuming that you have an executable JAR file with pathname <jar-path>, you should be able to
run it as follows:
If the command requires command-line arguments, add them after the <jar-path>. For example:
If you need to provide additional JVM options on the java command line, they need to go before
the -jar option. Note that a -cp / -classpath option will be ignored if you use -jar. The application's
classpath is determined by the JAR file manifest.
https://riptutorial.com/ 1073
Running a Java applications via a "main" class
When an application has not been packaged as an executable JAR, you need to provide the name
of an entry-point class on the java command line.
Assuming that the (compiled) "HelloWorld.class" file is in the current directory, it can be launched
as follows:
java HelloWorld
• We must provide the name of the class: not the pathname for the ".class" file or the ".java"
file.
• If the class is declared in a package (as most Java classes are), then the class name we
supply to the java command must be the full classname. For instance if SomeClass is declared
in the com.example package, then the full classname will be com.example.SomeClass.
Specifying a classpath
Unless we are using in the java -jar command syntax, the java command looks for the class to be
loaded by searching the classpath; see The Classpath. The above command is relying on the
default classpath being (or including) the current directory. We can be more explicit about this by
specifying the classpath to be used using the -cp option.
This says to make the current directory (which is what "." refers to) the sole entry on the classpath.
The -cp is an option that is processed by the java command. All options that are intended for the
java command should be before the classname. Anything after the class will be treated as an
command line argument for the Java application, and will be passed to application in the String[]
that is passed to the main method.
(If no -cp option is provided, the java will use the classpath that is given by the CLASSPATH
environment variable. If that variable is unset or empty, java uses "." as the default classpath.)
A Java entry-point class has a main method with the following signature and modifiers:
https://riptutorial.com/ 1074
public static void main(String[] args)
When the java command starts the virtual machine, it loads the specified entry-point classes and
tries to find main. If successful, the arguments from command line are converted to Java String
objects and assembled into an array. If main is invoked like this, the array will not be null and won't
contain any null entries.
It is conventional to declare the class as public but this not strictly necessary. From Java 5
onward, the main method's argument type may be a String varargs instead of a string array. main
can optionally throw exceptions, and its parameter can be named anything, but conventionally it is
args.
JavaFX entry-points
From Java 8 onwards the java command can also directly launch a JavaFX application. JavaFX is
documented in the JavaFX tag, but a JavaFX entry-point must do the following:
• Extend javafx.application.Application
• Be public and not abstract
• Not be generic or nested
• Have an explicit or implicit public no-args constructor
This example covers common errors with using the 'java' command.
when trying to run the java command, this means that there is no java command on your shell's
command search path. The cause could be:
https://riptutorial.com/ 1075
• you don't have a Java JRE or JDK installed at all,
• you have not updated the PATH environment variable (correctly) in your shell initialization file,
or
• you have not "sourced" the relevant initialization file in the current shell.
Refer to "Installing Java" for the steps that you need to take.
• You have specified an entry point class that does not exist.
• The class exists, but you have specified it incorrectly.
• The class exists and you have specified it correctly, but Java cannot it find it because the
classpath is incorrect.
• If you have source code for a class, then the full name consists of the package name
and the simple class name. The instance the "Main" class is declared in the package
"com.example.myapp" then its full name is "com.example.myapp.Main".
• If you have a compiled class file, you can find the class name by running javap on it.
• If the class file is in a directory, you can infer the full class name from the directory
names.
• If the class file is in a JAR or ZIP file, you can infer the full class name from the file path
in the JAR or ZIP file.
2. Look at the error message from the java command. The message should end with the full
class name that java is trying to use.
• Check that it exactly matches the full classname for the entry-point class.
• It should not end with ".java" or ".class".
• It should not contain slashes or any other character that is not legal in a Java identifier1
.
• The casing of the name should exactly match the full class name.
3. If you are using the correct classname, make sure that the class is actually on the classpath:
• Work out the pathname that the classname maps to; see Mapping classnames to
pathnames
• Work out what the classpath is; see this example: Different ways to specify the
classpath
• Look at each of the JAR and ZIP files on the classpath to see if they contain a class
with the required pathname.
https://riptutorial.com/ 1076
• Look at each directory to see if the pathname resolves to a file within the directory.
If checking the classpath by hand did not find the issue, you could add the -Xdiag and -
XshowSettings options. The former lists all classes that are loaded, and the latter prints out settings
that include the effective classpath for the JVM.
• An executable JAR file with a Main-Class attribute that specifies a class that does not exist.
• An executable JAR file with an incorrect Class-Path attribute.
• If you mess up2 the options before the classname, the java command may attempt to
interpret one of them as the classname.
• If someone has ignored Java style rules and used package or class identifiers that differ only
in letter case, and you are running on a platform that treats letter case in filenames as non-
significant.
• Problems with homoglyphs in class names in the code or on the command line.
• If you are trying to run an executable JAR file, then the JAR's manifest has an incorrect
"Main-Class" attribute that specifies a class that is not a valid entry point class.
• You have told the java command a class that is not an entry point class.
• The entry point class is incorrect; see Entry point classes for more information.
Other Resources
• What does "Could not find or load main class" mean?
• http://docs.oracle.com/javase/tutorial/getStarted/problems/index.html
1 - From Java 8 and later, the java command will helpfully map a filename separator ("/" or "") to a period (".").
However, this behavior is not documented in the manual pages.
2 - A really obscure case is if you copy-and-paste a command from a formatted document where the text editor has
used a "long hyphen" instead of a regular hyphen.
Typical Java applications consist of an application-specific code, and various reusable library code
that you have implemented or that has been implemented by third parties. The latter are
commonly referred to as library dependencies, and are typically packaged as JAR files.
https://riptutorial.com/ 1077
Java is a dynamically bound language. When you run a Java application with library
dependencies, the JVM needs to know where the dependencies are so that it can load classes as
required. Broadly speaking, there are two ways to deal with this:
• The application and its dependencies can be repackaged into a single JAR file that contains
all of the required classes and resources.
• The JVM can be told where to find the dependent JAR files via the runtime classpath.
For an executable JAR file, the runtime classpath is specified by the "Class-Path" manifest
attribute. (Editorial Note: This should be described in a separate Topic on the jar command.)
Otherwise, the runtime classpath needs to be supplied using the -cp option or using the CLASSPATH
environment variable.
For example, suppose that we have a Java application in the "myApp.jar" file whose entry point
class is com.example.MyApp. Suppose also that the application depends on library JAR files
"lib/library1.jar" and "lib/library2.jar". We could launch the application using the java command as
follows in a command line:
$ # Alternative 1 (preferred)
$ java -cp myApp.jar:lib/library1.jar:lib/library2.jar com.example.MyApp
$ # Alternative 2
$ export CLASSPATH=myApp.jar:lib/library1.jar:lib/library2.jar
$ java com.example.MyApp
(On Windows, you would use ; instead of : as the classpath separator, and you would set the
(local) CLASSPATH variable using set rather than export.)
While a Java developer would be comfortable with that, it is not "user friendly". So it is common
practice to write a simple shell script (or Windows batch file) to hide the details that the user
doesn't need to know about. For example, if you put the following shell script into a file called
"myApp", made it executable, and put it into a directory on the command search path:
#!/bin/bash
# The 'myApp' wrapper script
export DIR=/usr/libexec/myApp
export CLASSPATH=$DIR/myApp.jar:$DIR/lib/library1.jar:$DIR/lib/library2.jar
java com.example.MyApp
Any arguments on the command line will be passed to the Java application via the "$@" expansion.
(You can do something similar with a Windows batch file, though the syntax is different.)
https://riptutorial.com/ 1078
First of all, the problem of handling spaces in arguments is NOT actually a Java problem. Rather it
is a problem that needs to be handled by the command shell that you are using when you run a
Java program.
As an example, let us suppose that we have the following simple program that prints the size of a
file:
import java.io.File;
Now suppose that we want print the size of a file whose pathname has spaces in it; e.g.
/home/steve/Test File.txt. If we run the command like this:
the shell won't know that /home/steve/Test File.txt is actually one pathname. Instead, it will pass 2
distinct arguments to the Java application, which will attempt to find their respective file sizes, and
fail because files with those paths (probably) do not exist.
The double-quotes around the pathname tell the shell that it should be passed as a single
argument. The quotes will be removed when this happens. There are a couple of other ways to do
this:
Single (straight) quotes are treated like double-quotes except that they also suppress various
expansions within the argument.
A backslash escapes the following space, and causes it not to be interpreted as an argument
separator.
https://riptutorial.com/ 1079
For more comprehensive documentation, including descriptions of how to deal with other special
characters in arguments, please refer to the quoting topic in the Bash documentation.
• You can put double-quotes around an argument in a java command, and that will allow you
to pass arguments with spaces in them.
• Apparently, the java command itself is parsing the command string, and it gets it more or
less right
• However, when you try to combine this with the use of SET and variable substitution in a
batch file, it gets really complicated as to whether double-quotes get removed.
• The cmd.exe shell apparently has other escaping mechanisms; e.g. doubling double-quotes,
and using ^ escapes.
Java Options
• All options start with a single hyphen or minus-sign (-): the GNU/Linux convention of using --
for "long" options is not supported.
• Options must appear before the <classname> or the -jar <jarfile> argument to be
recognized. Any arguments after them will be treated as arguments to be passed to Java
app that is being run.
• Options that do not start with -X or -XX are standard options. You can rely on all Java
implementations1 to support any standard option.
• Options that start with -X are non-standard options, and may be withdrawn from one Java
version to the next.
• Options that start with -XX are advanced options, and may also be withdrawn.
https://riptutorial.com/ 1080
parameter can be repeated to set different properties.
Note that enabling to assertion checking is liable to alter the behavior of a Java programming.
• The "client" form is tuned for user applications and offers faster startup.
• The "server" form is tuned for long running applications. It takes longer capturing statistic
during JVM "warm up" which allows the JIT compiler to do a better of job of optimizing the
https://riptutorial.com/ 1081
native code.
By default, the JVM will run in 64bit mode if possible, depending on the capabilities of the platform.
The -d32 and -d64 options allow you to select the mode explicitly.
1 - Check the official manual for the java command. Sometimes a standard option is described as "subject to
change".
https://riptutorial.com/ 1082
Chapter 171: The java.util.Objects Class
Examples
Basic use for object null check
With the Objects.nonNull method and Java8 Stream API, we can do the above in this way:
https://riptutorial.com/ 1083
Chapter 172: ThreadLocal
Remarks
Best used for objects which depend on internals during invoking a call, but are stateless otherwise,
like SimpleDateFormat, Marshaller
Examples
ThreadLocal Java 8 functional initialization
Java ThreadLocal is used to create thread local variables. It is known that threads of an Object
share it’s variables, so the variable is not thread safe. We can use synchronization for thread
safety but if we want to avoid synchronization,ThreadLocal allows us to create variables which are
local to the thread, i.e. only that thread can read or write to those variables, so the other threads
executing the same piece of code will not be able to access each others ThreadLocal variables.
This can be usedwe can use ThreadLocal variables. in situations where you have a thread pool like
for example in a web service. For example, Creating a SimpleDateFormat object every time for every
request is time consuming and a Static one cannot be created as SimpleDateFormat is not thread
safe, so we can create a ThreadLocal so that we can perform thread safe operations without the
overhead of creating SimpleDateFormat every time.
Every thread has it’s own ThreadLocal variable and they can use it’s get() and set() methods to get
the default value or change it’s value local to Thread.
ThreadLocal instances are typically private static fields in classes that wish to associate state with a
thread.
Here is a small example showing use of ThreadLocal in java program and proving that every
https://riptutorial.com/ 1084
thread has it’s own copy of ThreadLocal variable.
package com.examples.threads;
import java.text.SimpleDateFormat;
import java.util.Random;
@Override
public void run() {
System.out.println("Thread Name= "+Thread.currentThread().getName()+" default
Formatter = "+formatter.get().toPattern());
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
formatter.set(new SimpleDateFormat());
Output:
https://riptutorial.com/ 1085
Thread Name= 4 default Formatter = yyyyMMdd HHmm
As we can see from the output that Thread-0 has changed the value of formatter but still thread-2
default formatter is same as the initialized value.
In this example we have only one object but it is shared between/executed on different threads.
Ordinary usage of fields to save state would not be possible because the other thread would see
that too (or probably not see).
In Foo we count starting from zero. Instead of saving the state to a field we store our current
number in the ThreadLocal object which is statically accessible. Note that the synchronization in
this example is not related to the usage of ThreadLocal but rather ensures a better console output.
https://riptutorial.com/ 1086
@Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
synchronized (threadLocal) {
//Although accessing a static field, we get our own (previously saved) value.
int value = threadLocal.get();
System.out.println(Thread.currentThread().getName() + ": " + value);
try {
threadLocal.notifyAll();
if (i < ITERATIONS - 1) {
threadLocal.wait();
}
} catch (InterruptedException ex) {
}
}
}
}
}
From the output we can see that each thread counts for itself and does not use the value of the
other one:
Thread 1: 0
Thread 2: 0
Thread 1: 1
Thread 2: 1
Thread 1: 2
Thread 2: 2
Thread 1: 3
Thread 2: 3
Thread 1: 4
Thread 2: 4
Thread 1: 5
Thread 2: 5
Thread 1: 6
Thread 2: 6
Thread 1: 7
Thread 2: 7
Thread 1: 8
Thread 2: 8
Thread 1: 9
Thread 2: 9
https://riptutorial.com/ 1087
Chapter 173: TreeMap and TreeSet
Introduction
TreeMap and TreeSet are basic Java collections added in Java 1.2. TreeMap is a mutable, ordered,
Map implementation. Similarly, TreeSet is a mutable, ordered Set implementation.
Examples
TreeMap of a simple Java type
First, we create an empty map, and insert some elements into it:
Java SE 7
Java SE 7
treeMap.put(10, "ten");
treeMap.put(4, "four");
treeMap.put(1, "one");
treeSet.put(12, "twelve");
Once we have a few elements in the map, we can perform some operations:
We can also iterate over the map elements using either an Iterator, or a foreach loop. Note that
the entries are printed according to their natural ordering, not the insertion order:
Java SE 7
https://riptutorial.com/ 1088
Iterator<Entry<Integer, String>> iter = treeMap.entrySet().iterator();
while (iter.hasNext()) {
System.out.print(iter.next() + " "); //prints 1=one 4=four 10=ten 12=twelve
}
First, we create an empty set, and insert some elements into it:
Java SE 7
Java SE 7
treeSet.add(10);
treeSet.add(4);
treeSet.add(1);
treeSet.add(12);
Once we have a few elements in the set, we can perform some operations:
System.out.println(treeSet.first()); // Prints 1
System.out.println(treeSet.last()); // Prints 12
System.out.println(treeSet.size()); // Prints 4, since there are 4 elemens in the set
System.out.println(treeSet.contains(12)); // Prints true
System.out.println(treeSet.contains(15)); // Prints false
We can also iterate over the map elements using either an Iterator, or a foreach loop. Note that
the entries are printed according to their natural ordering, not the insertion order:
Java SE 7
Since TreeMaps and TreeSets maintain keys/elements according to their natural ordering. Therefor
TreeMap keys and TreeSet elements have to comparable to one another.
https://riptutorial.com/ 1089
public class Person {
To fix that, let's assume that we want to order Person instances based on the order of their ids (
private int id). We could do it in one of two ways:
@Override
public int compareTo(Person o) {
return Integer.compare(this.id, o.id); //Compare by id
}
}
Java SE 8
https://riptutorial.com/ 1090
However, there are two caveats to both approaches:
1. It's very important not to modify any fields used for ordering once an instance has been
inserted into a TreeSet/TreeMap. In the above example, if we change the id of a person that's
already inserted into the collection, we might run into unexpected behavior.
2. It's important to implement the comparison properly and consistently. As per the Javadoc:
The implementor must also ensure that the relation is transitive: (x.compareTo(y)>0 &&
y.compareTo(z)>0) implies x.compareTo(z)>0.
TreeMap and TreeSet are not thread-safe collections, so care must be taken to ensure when used in
multi-threaded programs.
Both TreeMap and TreeSet are safe when read, even concurrently, by multiple threads. So if they
have been created and populated by a single thread (say, at the start of the program), and only
then read, but not modified by multiple threads, there's no reason for synchronization or locking.
However, if read and modified concurrently, or modified concurrently by more than one thread, the
collection might throw a ConcurrentModificationException or behave unexpectedly. In these cases,
it's imperative to synchronize/lock access to the collection using one of the following approaches:
1. Using Collections.synchronizedSorted..:
This will provide a SortedSet/SortedMap implementation backed by the actual collection, and
synchronized on some mutex object. Note that this will synchronize all read and write access
to the collection on a single lock, so even concurrent reads would not be possible.
...
//Thread 1
synchronized (set) {
https://riptutorial.com/ 1091
set.add(4);
}
...
//Thread 2
synchronized (set) {
set.remove(5);
}
...
//Thread 1
lock.writeLock().lock();
set.add(4);
lock.writeLock().unlock();
...
//Thread 2
lock.readLock().lock();
set.contains(5);
lock.readLock().unlock();
https://riptutorial.com/ 1092
Chapter 174: Type Conversion
Syntax
• TargetType target = (SourceType) source;
Examples
Non-numeric primitive casting
The boolean type cannot be cast to/from any other primitive type.
A char can be cast to/from any numeric type by using the code-point mappings specified by
Unicode. A char is represented in memory as an unsigned 16-bit integer value (2 bytes), so
casting to byte (1 byte) will drop 8 of those bits (this is safe for ASCII characters). The utility
methods of the Character class use int (4 bytes) to transfer to/from code-point values, but a short
(2 bytes) would also suffice for storing a Unicode code-point.
Numeric primitives can be cast in two ways. Implicit casting happens when the source type has
smaller range than the target type.
//Implicit casting
byte byteVar = 42;
short shortVar = byteVar;
int intVar = shortVar;
long longVar = intvar;
float floatVar = longVar;
double doubleVar = floatVar;
Explicit casting has to be done when the source type has larger range than the target type.
//Explicit casting
double doubleVar = 42.0d;
float floatVar = (float) doubleVar;
long longVar = (long) floatVar;
https://riptutorial.com/ 1093
int intVar = (int) longVar;
short shortVar = (short) intVar;
byte byteVar = (byte) shortVar;
When casting floating point primitives (float, double) to whole number primitives, the number is
rounded down.
Object casting
Implicit casting happens when the source type extends or implements the target type (casting to a
superclass or interface).
Explicit casting has to be done when the source type is extended or implemented by the target
type (casting to a subtype). This can produce a runtime exception (ClassCastException) when the
object being cast is not of the target type (or the target's subtype).
Java provides the instanceof operator to test if an object is of a certain type, or a subclass of that
type. The program can then choose to cast or not cast that object accordingly.
https://riptutorial.com/ 1094
}
if(obj instanceof Date)
{
time = ((Date)obj).getTime(); // This line will never be reached, obj is not a Date type.
}
https://riptutorial.com/ 1095
Chapter 175: Unit Testing
Introduction
Unit testing is an integral part of test-driven development, and an important feature for building any
robust application. In Java, Unit testing is almost exclusively performed using external libraries and
frameworks, most of which have their own documentation tag. This stub serves as a means of
introducing the reader to the tools available, and their respective documentation.
Remarks
JUnit
TestNG
Mockito - Mocking framework; allows objects to be mimicked. Useful for mimicking the expected
behavior of an external unit within a given unit's test, as to not link the external unit's behavior to
the given unit's tests.
Examples
What is Unit Testing?
This is a bit of a primer. It's mostly put it in because documentation is forced to have an example,
even if it's intended as a stub article. If you already know unit-testing basics, feel free to skip
forward to the remarks, where specific frameworks are mentioned.
https://riptutorial.com/ 1096
Unit testing is ensuring that a given module behaves as expected. In large-scale applications,
ensuring the appropriate execution of modules in a vacuum is an integral part of ensuring
application fidelity.
// Application-level test.
public Example() {
Consumer c = new Consumer();
System.out.println("VALUE = " + c.getVal());
}
// Your Module.
class Consumer {
private Capitalizer c;
public Consumer() {
c = new Capitalizer();
}
public Capitalizer() {
dr = new DataReader();
}
So this example is trivial; DataReader gets the data from a file, passes it to the Capitalizer, which
converts all the characters to upper-case, which then gets passed to the Consumer. But the
https://riptutorial.com/ 1097
DataReaderis heavily-linked to our application environment, so we defer testing of this chain until
we are ready to deploy a test release.
Now, assume, somewhere along the way in a release, for reasons unknown, the getVal() method
in Capitalizer changed from returning a toUpperCase() String to a toLowerCase() String:
Clearly, this breaks expected behavior. But, because of the arduous processes involved with
execution of the DataReader, we won't notice this until our next test deployment. So
days/weeks/months go by with this bug sitting in our system, and then the product manager sees
this, and instantly turns to you, the team leader associated with the Consumer. "Why is this
happening? What did you guys change?" Obviously, you're clueless. You have no idea what's
going on. You didn't change any code that should be touching this; why is it suddenly broken?
Eventually, after discussion between the teams and collaboration, the issue is traced, and the
problem solved. But, it begs the question; how could this have been prevented?
You have to appreciate that, in this example, I've expressed one very trivial bug that was
introduced and unnoticed. In an industrial application, with dozens of modules constantly being
updated, these can creep in all over the place. You fix something with one module, only to realize
that the very behavior you "fixed" was relied upon in some manner elsewhere (either internally or
externally).
Without rigorous validation, things will creep into the system. It's possible that, if neglected far
enough, this will result in so much extra work trying to fix changes (and then fixing those fixes,
etc.), that a product will actually increase in remaining work as effort is put into it. You do not want
to be in this situation.
https://riptutorial.com/ 1098
The product manager pinged you when the testers noticed it, you investigated and found that the
Capitalizer was returning seemingly bad data, you pinged the Capitalizer team with your findings,
they investigated, etc. etc. etc.
The same point I made above about the quantity and difficulty of this trivial example hold here.
Obviously anyone reasonably well-versed with Java could find the introduced problem quickly. But
it's often much, much more difficult to trace and communicate issues. Maybe the Capitalizer team
provided you a JAR with no source. Maybe they're located on the other side of the world, and
communication hours are very limited (perhaps to e-mails that get sent once daily). It can result in
bugs taking weeks or longer to trace (and, again, there could be several of these for a given
release).
In order to mitigate against this, we want rigorous testing on as fine a level as possible (you also
want coarse-grained testing to ensure modules interact properly, but that's not our focal point
here). We want to rigorously specify how all outward-facing functionality (at minimum) operates,
and tests for that functionality.
Enter unit-testing
Imagine if we had a test, specifically ensuring that the getVal() method of Capitalizer returned a
capitalized string for a given input string. Furthermore, imagine that test was run before we even
committed any code. The bug introduced into the system (that is, toUpperCase() being replaced
with toLowerCase()) would cause no issues because the bug would never be introduced into the
system. We would catch it in a test, the developer would (hopefully) realize their mistake, and an
alternative solution would be reached as to how to introduce their intended effect.
There's some omissions made here as to how to implement these tests, but those are covered in
the framework-specific documentation (linked in the remarks). Hopefully, this serves as an
example of why unit testing is important.
https://riptutorial.com/ 1099
Chapter 176: Using Other Scripting
Languages in Java
Introduction
Java in itself is an extremely powerful language, but its power can further be extended Thanks to
JSR223 (Java Specification Request 223) introducing a script engine
Remarks
The Java Scripting API enables external scripts to interact with Java
The Scripting API can enable interaction between the script and java. The Scripting Languages
must have an implementation of Script Engine on the classpath.
By Default JavaScript (also known as ECMAScript) is provided by nashorn by default. Every Script
Engine has a script context where all the variables, functions, methods are stored in bindings.
Sometimes you might want to use multiple contexts as they support redirecting the output to a
buffered Writer and error to another.
There are many other script engine libraries like Jython and JRuby. As long as they are on the
classpath you can eval code.
We can use bindings to expose variables into the script. We need multiple bindings in some cases
as exposing variables to the engine basically is exposing variables to only that engine, sometimes
we require to expose certain variables like system environment and path that is the same for all
engines of the same type. In that case, we require a binding which is a global scope. Exposing
variables to that expose it to all script engines created by the same EngineFactory
Examples
Evaluating A javascript file in -scripting mode of nashorn
/*
* Note Nashorn is only available for Java-8 onwards
* You can use rhino from ScriptEngineManager.getEngineByName("js");
*/
ScriptEngine engine;
ScriptContext context;
public Bindings scope;
https://riptutorial.com/ 1100
// Script context is an interface so we need an implementation of it
context = new SimpleScriptContext();
// Create bindings to expose variables into
scope = engine.createBindings();
}
// Apply the bindings to the context and set the engine's default context
public void startBatch(int SCP){
context.setBindings(scope, SCP);
engine.setContext(context);
}
https://riptutorial.com/ 1101
// Evaluate the code
jse.eval("print(x);");
}
As you can see the exposed variable x has been printed. Now testing with a file.
print(x);
function test(){
print("hello test.js:test");
}
test();
Assuming that test.js is in the same directory as your application You should have output similar to
this
hello world
hello test.js:test
https://riptutorial.com/ 1102
Chapter 177: Using the static keyword
Syntax
• public static int myVariable; //Declaring a static variable
• public static myMethod() { } //Declaring a static method
• public static final double MY_CONSTANT; //Declaring a constant variable that is shared
among all instances of the class
• public final double MY_CONSTANT; // Declaring a constant variable specific to this instance
of the class (best used in a constructor that generates a different constant for each instance)
Examples
Using static to declare constants
As the static keyword is used for accessing fields and methods without an instantiated class, it
can be used to declare constants for use in other classes. These variables will remain constant
across every instantiation of the class. By convention, static variables are always ALL_CAPS and
use underscores rather than camel case. ex:
static E STATIC_VARIABLE_NAME
As constants cannot change, static can also be used with the final modifier:
Static gives a method or variable storage that is not allocated for each instance of the class.
Rather, the static variable is shared among all class members. Incidentally, trying to treat the static
https://riptutorial.com/ 1103
variable like a member of the class instance will result in a warning:
Methods that are declared static behave in much the same way, but with an additional restriction:
In general, it's best to declare generic methods that apply to different instances of a class (such as
clone methods) static, while keeping methods like equals() as non-static. The main method of a
Java program is always static, which means that the keyword this cannot be used inside main().
Static variables and methods are not part of an instance, There will always be a single copy of that
variable no matter how many objects you create of a particular class.
For example you might want to have an immutable list of constants, it would be a good idea to
keep it static and initialize it just once inside a static method. This would give you a significant
performance gain if you are creating several instances of a particular class on a regular basis.
Furthermore you can also have a static block in a class as well. You can use it to assign a default
value to a static variable. They are executed only once when the class is loaded into memory.
Instance variable as the name suggest are dependent on an instance of a particular object, they
live to serve the whims of it. You can play around with them during a particular life cycle of an
object.
https://riptutorial.com/ 1104
All the fields and methods of a class used inside a static method of that class must be static or
local. If you try to use instance (non-static) variables or methods, your code will not compile.
https://riptutorial.com/ 1105
Chapter 178: Using ThreadPoolExecutor in
MultiThreaded applications.
Introduction
When creating a performant and data-driven application, it can be very helpful to complete time-
intensive tasks in an asynchronous manner and to have multiple tasks running concurrently. This
topic will introduce the concept of using ThreadPoolExecutors to complete multiple ansynchronous
tasks concurrently.
Examples
Performing Asynchronous Tasks Where No Return Value Is Needed Using a
Runnable Class Instance
Some applications may want to create so-called "Fire & Forget" tasks which can be periodically
triggered and do not need to return any type of value returned upon completion of the assigned
task (for example, purging old temp files, rotating logs, autosaving state).
In this example, we will create two classes: One which implements the Runnable interface, and
one which contains a main() method.
AsyncMaintenanceTaskCompleter.java
import lombok.extern.java.Log;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
@Log
public class AsyncMaintenanceTaskCompleter implements Runnable {
private int taskNumber;
} catch (InterruptedException e) {
log.warning(e.getMessage());
}
}
}
https://riptutorial.com/ 1106
AsyncExample1
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
https://riptutorial.com/ 1107
Observations of Note: There are several things to note in the output above,
It is often necessary to execute a long-running task and use the result of that task once it has
completed.
In this example, we will create two classes: One which implements the Callable<T> interface
(where T is the type we wish to return), and one which contains a main() method.
AsyncValueTypeTaskCompleter.java
import lombok.extern.java.Log;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
@Log
public class AsyncValueTypeTaskCompleter implements Callable<Integer> {
private int taskNumber;
@Override
public Integer call() throws Exception {
int timeout = ThreadLocalRandom.current().nextInt(1, 20);
try {
log.info(String.format("Task %d is sleeping", taskNumber));
TimeUnit.SECONDS.sleep(timeout);
log.info(String.format("Task %d is done sleeping", taskNumber));
} catch (InterruptedException e) {
log.warning(e.getMessage());
}
return timeout;
}
}
AsyncExample2.java
import lombok.extern.java.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
https://riptutorial.com/ 1108
import java.util.concurrent.Future;
@Log
public class AsyncExample2 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<Integer>> futures = new ArrayList<>();
for (int i = 0; i < 10; i++){
Future<Integer> submittedFuture = executorService.submit(new
AsyncValueTypeTaskCompleter(i));
futures.add(submittedFuture);
}
executorService.shutdown();
while(!futures.isEmpty()){
for(int j = 0; j < futures.size(); j++){
Future<Integer> f = futures.get(j);
if(f.isDone()){
try {
int timeout = f.get();
log.info(String.format("A task just completed after sleeping for %d
seconds", timeout));
futures.remove(f);
} catch (InterruptedException | ExecutionException e) {
log.warning(e.getMessage());
}
}
}
}
}
}
https://riptutorial.com/ 1109
INFO: A task just completed after sleeping for 2 seconds
Dec 28, 2016 3:07:17 PM AsyncValueTypeTaskCompleter call
INFO: Task 9 is done sleeping
Dec 28, 2016 3:07:17 PM AsyncExample2 main
INFO: A task just completed after sleeping for 2 seconds
Dec 28, 2016 3:07:19 PM AsyncValueTypeTaskCompleter call
INFO: Task 3 is done sleeping
Dec 28, 2016 3:07:19 PM AsyncExample2 main
INFO: A task just completed after sleeping for 4 seconds
Dec 28, 2016 3:07:20 PM AsyncValueTypeTaskCompleter call
INFO: Task 0 is done sleeping
Dec 28, 2016 3:07:20 PM AsyncExample2 main
INFO: A task just completed after sleeping for 5 seconds
Dec 28, 2016 3:07:21 PM AsyncValueTypeTaskCompleter call
INFO: Task 5 is done sleeping
Dec 28, 2016 3:07:21 PM AsyncExample2 main
INFO: A task just completed after sleeping for 6 seconds
Dec 28, 2016 3:07:25 PM AsyncValueTypeTaskCompleter call
INFO: Task 1 is done sleeping
Dec 28, 2016 3:07:25 PM AsyncExample2 main
INFO: A task just completed after sleeping for 10 seconds
Dec 28, 2016 3:07:27 PM AsyncValueTypeTaskCompleter call
INFO: Task 6 is done sleeping
Dec 28, 2016 3:07:27 PM AsyncExample2 main
INFO: A task just completed after sleeping for 12 seconds
Dec 28, 2016 3:07:29 PM AsyncValueTypeTaskCompleter call
INFO: Task 7 is done sleeping
Dec 28, 2016 3:07:29 PM AsyncExample2 main
INFO: A task just completed after sleeping for 14 seconds
Dec 28, 2016 3:07:31 PM AsyncValueTypeTaskCompleter call
INFO: Task 4 is done sleeping
Dec 28, 2016 3:07:31 PM AsyncExample2 main
INFO: A task just completed after sleeping for 16 seconds
Observations of Note:
While good software design often maximizes code reusability, sometimes it can be useful to define
asynchronous tasks inline in your code via Lambda expressions to maximize code readability.
https://riptutorial.com/ 1110
In this example, we will create a single class which contains a main() method. Inside this method,
we will use Lambda expressions to create and execute instances of Callable and Runnable<T>.
AsyncExample3.java
import lombok.extern.java.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
@Log
public class AsyncExample3 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<Integer>> futures = new ArrayList<>();
for(int i = 0; i < 5; i++){
final int index = i;
executorService.execute(() -> {
int timeout = getTimeout();
log.info(String.format("Runnable %d has been submitted and will sleep for %d
seconds", index, timeout));
try {
TimeUnit.SECONDS.sleep(timeout);
} catch (InterruptedException e) {
log.warning(e.getMessage());
}
log.info(String.format("Runnable %d has finished sleeping", index));
});
Future<Integer> submittedFuture = executorService.submit(() -> {
int timeout = getTimeout();
log.info(String.format("Callable %d will begin sleeping", index));
try {
TimeUnit.SECONDS.sleep(timeout);
} catch (InterruptedException e) {
log.warning(e.getMessage());
}
log.info(String.format("Callable %d is done sleeping", index));
return timeout;
});
futures.add(submittedFuture);
}
executorService.shutdown();
while(!futures.isEmpty()){
for(int j = 0; j < futures.size(); j++){
Future<Integer> f = futures.get(j);
if(f.isDone()){
try {
int timeout = f.get();
log.info(String.format("A task just completed after sleeping for %d
seconds", timeout));
futures.remove(f);
} catch (InterruptedException | ExecutionException e) {
log.warning(e.getMessage());
}
}
}
}
}
https://riptutorial.com/ 1111
public static int getTimeout(){
return ThreadLocalRandom.current().nextInt(1, 20);
}
}
Observations of Note:
1. Lambda expressions have access to variables and methods which are available to the scope
in which they are defined, but all variables must be final (or effectively final) for use inside a
lambda expression.
2. We do not have to specify whether our Lambda expression is a Callable or a Runnable<T>
explicitly, the return type is inferred automatically by the return type.
https://riptutorial.com/ 1112
Chapter 179: Varargs (Variable Argument)
Remarks
A “varargs” method argument allows callers of that method to specify multiple arguments of the
designated type, each as a separate argument. It is specified in the method declaration by three
ASCII periods (...) after the base type.
The method itself receives those arguments as a single array, whose element type is the type of
the varargs argument. The array is created automatically (though callers are still permitted to pass
an explicit array instead of passing multiple values as separate method arguments).
You must follow above rules otherwise program will give compile error.
Examples
Specifying a varargs parameter
The three periods after the final parameter's type indicate that the final argument may be passed
as an array or as a sequence of arguments. Varargs can be used only in the final argument
position.
Using varargs as a parameter for a method definition, it is possible to pass either an array or a
sequence of arguments. If a sequence of arguments are passed, they are converted into an array
automatically.
This example shows both an array and a sequence of arguments being passed into the
printVarArgArray() method, and how they are treated identically in the code inside the method:
// this method will print the entire contents of the parameter passed in
void printVarArgArray(int... x) {
https://riptutorial.com/ 1113
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + ",");
}
}
//Using an array:
int[] testArray = new int[]{10, 20};
obj.printVarArgArray(testArray);
System.out.println(" ");
Output:
10,20,
5,6,5,8,6,31
If you define the method like this, it will give compile-time errors.
void method(String... a, int... b , int c){} //Compile time error (multiple varargs )
void method(int... a, String b){} //Compile time error (varargs must be the last argument
https://riptutorial.com/ 1114
Chapter 180: Visibility (controlling access to
members of a class)
Syntax
• public type name[ = value];
• private type name[ = value];
• protected type name[ = value];
• type name[ = value];
• public class name{
• class name{
Remarks
From the Java tutorial:
Access level modifiers determine whether other classes can use a particular field or invoke a
particular method. There are two levels of access control:
A class may be declared with the modifier public, in which case that class is visible to all classes
everywhere. If a class has no modifier (the default, also known as package-private), it is visible
only within its own package.
At the member level, you can also use the public modifier or no modifier (package-private) just as
with top-level classes, and with the same meaning. For members, there are two additional access
modifiers: private and protected. The private modifier specifies that the member can only be
accessed in its own class. The protected modifier specifies that the member can only be accessed
within its own package (as with package-private) and, in addition, by a subclass of its class in
another package.
The following table shows the access to members permitted by each modifier.
Access Levels:
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
https://riptutorial.com/ 1115
Examples
Interface members
public class X {
}
class Y {
}
}
Interface members always have public visibility, even if the public keyword is omitted. So both
foo(), bar(), TEXT, ANSWER, X, and Y have public visibility. However, access may still be limited by the
containing interface - since MyInterface has public visibility, its members may be accessed from
anywhere, but if MyInterface had had package visibility, its members would only have been
accessible from within the same package.
Public Visibility
public Test(){
}
}
Now let's try to create an instance of the class. In this example, we can access number because it
is public.
Private Visibility
https://riptutorial.com/ 1116
visibility allows a variable to only be accessed by its class. They are often used in
private
conjunction with public getters and setters.
class SomeClass {
private int variable;
Package Visibility
With no modifier, the default is package visibility. From the Java Documentation, "[package
visibility] indicates whether classes in the same package as the class (regardless of their
parentage) have access to the member." In this example from javax.swing,
package javax.swing;
public abstract class JComponent extends Container … {
…
static boolean DEBUG_GRAPHICS_LOADED;
…
}
package javax.swing;
public class DebugGraphics extends Graphics {
…
static {
JComponent.DEBUG_GRAPHICS_LOADED = true;
}
…
}
https://riptutorial.com/ 1117
Protected Visibility
Protected visibility causes means that this member is visible to its package, along with any of its
subclasses.
As an example:
package com.stackexchange.docs;
public class MyClass{
protected int variable; //This is the variable that we are trying to access
public MyClass(){
variable = 2;
};
}
Now we'll extend this class and try to access one of its protected members.
package some.other.pack;
import com.stackexchange.docs.MyClass;
public class SubClass extends MyClass{
public SubClass(){
super();
System.out.println(super.variable);
}
}
You would be also able to access a protected member without extending it if you are accessing it
from the same package.
Note that this modifier only works on members of a class, not on the class itself.
There was once a private protected (both keywords at once) modifier that could be applied to
methods or variables to make them accessible from a subclass outside the package, but make
them private to the classes in that package. However, this was removed in Java 1.0's release.
https://riptutorial.com/ 1118
Chapter 181: WeakHashMap
Introduction
Concepts of weak Hashmap
Examples
Concepts of WeakHashmap
Key Points:-
• Implementation of Map.
• stores only weak references to its keys.
Weak References : The objects that are referenced only by weak references are garbage
collected eagerly; the GC won’t wait until it needs memory in that case.
If the Java memory manager no longer has a strong reference to the object specified as a key,
then the entry in the map will be removed in WeakHashMap.
Example :-
hashMap.put(keyHashMap, "Ankita");
weakHashMap.put(keyWeakHashMap, "Atul");
System.gc();
System.out.println("Before: hash map value:"+hashMap.get("keyHashMap")+" and weak hash
map value:"+weakHashMap.get("keyWeakHashMap"));
keyHashMap = null;
keyWeakHashMap = null;
System.gc();
https://riptutorial.com/ 1119
Calling size() method on HashMap object will return the same number of key-value pairs. size will
decrease only if remove() method is called explicitly on the HashMap object.
Because the garbage collector may discard keys at anytime, a WeakHashMap may behave as
though an unknown thread is silently removing entries. So it is possible for the size method to
return smaller values over time.So, in WeakHashMap size decrease happens automatically.
https://riptutorial.com/ 1120
Chapter 182: XJC
Introduction
XJC is a Java SE tool that compiles an XML schema file into fully annotated Java classes.
Syntax
• xjc [ options ] schema file/URL/dir/jar ... [-b bindinfo ] ...
Parameters
Parameter Details
Remarks
The XJC tool is available as part of the JDK. It allows creating java code annotated with JAXB
annotations suitable for (un)marshalling.
Examples
Generating Java code from simple XSD file
<?xml version="1.0"?>
<xs:schema version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns="http://www.stackoverflow.com/users"
elementFormDefault="qualified"
targetNamespace="http://www.stackoverflow.com/users">
<xs:element name="users" type="ns:Users"/>
<xs:complexType name="Users">
<xs:sequence>
<xs:element type="ns:User" name="user" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
https://riptutorial.com/ 1121
<xs:complexType name="User">
<xs:attribute name="name" use="required" type="xs:string"/>
<xs:attribute name="reputation" use="required">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>
Using xjc
This requires the path to the xjc tool (JDK binaries) to be in the OS path variable.
xjc schema.xsd
Result files
There will be some additional comments, but basically the java files generated look like this:
package com.stackoverflow.users;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Users", propOrder = {
"user"
})
public class Users {
package com.stackoverflow.users;
https://riptutorial.com/ 1122
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "User")
public class User {
package com.stackoverflow.users;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
@XmlRegistry
public class ObjectFactory {
public ObjectFactory() {
}
https://riptutorial.com/ 1123
}
package-info.java
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.stackoverflow.com/users",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.stackoverflow.users;
https://riptutorial.com/ 1124
Chapter 183: XML Parsing using the JAXP
APIs
Remarks
XML Parsing is the interpretation of XML documents in order to manipulate their content using
sensible constructs, be they "nodes", "attributes", "documents", "namespaces", or events related
to these constructs.
Java has a native API for XML document handling, called JAXP, or Java API for XML Processing.
JAXP and a reference implementation has been bundled with every Java release since Java 1.4
(JAXP v1.1) and has evolved since. Java 8 shipped with JAXP version 1.6.
The API provides different ways of interacting with XML documents, which are :
Under the Document Object Model interface, an XML document is represented as a tree, starting
with the "Document Element". The base type of the API is the Node type, it allows to navigate from
a Node to its parent, its children, or its siblings (although, not all Nodes can have children, for
example, Text nodes are final in the tree, and never have childre). XML tags are represented as
Elements, which notably extend the Node with attribute-related methods.
The DOM interface is very usefull since it allows a "one line" parsing of XML documents as trees,
and allows easy modification of the constructed tree (node addition, suppression, copying, ...), and
finally its serialization (back to disk) post modifications. This comes at a price, though : the tree
resides in memory, therefore, DOM trees are not always practical for huge XML documents.
Furthermore, the construction of the tree is not always the fastest way of dealing with XML
content, especially if one is not interested in all parts of the XML document.
https://riptutorial.com/ 1125
The SAX API uses a "push parsing" approach, where a SAX Parser is responsible for interpreting
the XML document, and invokes methods on a delegate (a ContentHandler) to deal with whatever
event is found in the XML document. Usually, one never writes a parser, but one provides a
handler to gather all needed informations from the XML document.
The SAX interface overcomes the DOM interface's limitations by keeping only the minimum
necessary data at the parser level (e.g. namespaces contexts, validation state), therefore, only
informations that are kept by the ContentHandler - for which you, the developer, is responsible - are
held into memory. The tradeoff is that there is no way of "going back in time/the XML document"
with such an approach : while DOM allows a Node to go back to its parent, there is no such
possibility in SAX.
The API starts with XMLStreamReader (or XMLEventReader), which are the gateways through
which the developer can ask nextEvent(), in an iterator-style way.
Examples
Parsing and navigating a document using the DOM API
One can use the following code to build a DOM tree out of a String :
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
https://riptutorial.com/ 1126
+ "<library>"
+ "<book id='1'>Effective Java</book>"
+ "<book id='2'>Java Concurrency In Practice</book>"
+ "</library>";
One can use the following code to parse it and build a map of book titles by book id.
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
https://riptutorial.com/ 1127
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
System.out.println(bookTitlesById);
}
This outputs :
1. THe use of xmlStreamReader.getAttributeValue works because we have checked first that the
parser is in the START_ELEMENT state. In evey other states (except ATTRIBUTES), the parser is
https://riptutorial.com/ 1128
mandated to throw IllegalStateException, because attributes can only appear at the
beginning of elements.
For more complex documents parsing (deeper, nested elements, ...), it is a good practice to
"delegate" the parser to sub-methods or other objets, e.g. have a BookParser class or method, and
have it deal with every element from the START_ELEMENT to the END_ELEMENT of the book
XML tag.
One can also use a Stack object to keep around important datas up and down the tree.
https://riptutorial.com/ 1129
Chapter 184: XML XPath Evaluation
Remarks
XPath expressions are used to navigate and select one or more nodes within an XML tree
document, such as selecting a certain element or attribute node.
Examples
Evaluating a NodeList in an XML document
<documentation>
<tags>
<tag name="Java">
<topic name="Regular expressions">
<example>Matching groups</example>
<example>Escaping metacharacters</example>
</topic>
<topic name="Arrays">
<example>Looping over arrays</example>
<example>Converting an array to a list</example>
</topic>
</tag>
<tag name="Android">
<topic name="Building Android projects">
<example>Building an Android application using Gradle</example>
<example>Building an Android application using Maven</example>
</topic>
<topic name="Layout resources">
<example>Including layout resources</example>
<example>Supporting multiple device screens</example>
</topic>
</tag>
</tags>
</documentation>
The following retrieves all example nodes for the Java tag (Use this method if only evaluating XPath
in the XML once. See other example for when multiple XPath calls are evaluated in the same XML
file.):
https://riptutorial.com/ 1130
Parsing multiple XPath Expressions in a single XML
Using the same example as Evaluating a NodeList in an XML document, here is how you would
make multiple XPath calls efficiently:
<documentation>
<tags>
<tag name="Java">
<topic name="Regular expressions">
<example>Matching groups</example>
<example>Escaping metacharacters</example>
</topic>
<topic name="Arrays">
<example>Looping over arrays</example>
<example>Converting an array to a list</example>
</topic>
</tag>
<tag name="Android">
<topic name="Building Android projects">
<example>Building an Android application using Gradle</example>
<example>Building an Android application using Maven</example>
</topic>
<topic name="Layout resources">
<example>Including layout resources</example>
<example>Supporting multiple device screens</example>
</topic>
</tag>
</tags>
</documentation>
This is how you would use XPath to evaluate multiple expressions in one document:
...
In this case, you want to have the expression compiled before the evaluations, so that each call to
evaluate does not compile the same expression. The simple syntax would be:
https://riptutorial.com/ 1131
DocumentBuilder builder = DocumentBuilderFactory.newInstance();
Document doc = builder.parse(new File("path/to/xml.xml")); //Specify XML file path
Overall, two calls to XPathExpression.evaluate() will be much more efficient than two calls to
XPath.evaluate().
https://riptutorial.com/ 1132
Chapter 185: XOM - XML Object Model
Examples
Reading a XML file
In order to load the XML data with XOM you will need to make a Builder from which you can build
it into a Document.
To get the root element, the highest parent in the xml file, you need to use the getRootElement() on
the Document instance.
Now the Element class has a lot of handy methods that make reading xml really easy. Some of the
most useful are listed below:
When you call the getChildElements() you get a Elements instance. From this you can loop through
and call the get(int index) method on it to retrieve all the elements inside.
XML File:
https://riptutorial.com/ 1133
Code for reading and printing it:
import java.io.File;
import java.io.IOException;
import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Elements;
import nu.xom.ParsingException;
// get the name element and its children: first and last
Element nameElement = person.getFirstChildElement("name");
Element firstNameElement = nameElement.getFirstChildElement("first");
Element lastNameElement = nameElement.getFirstChildElement("last");
https://riptutorial.com/ 1134
Element ageElement = person.getFirstChildElement("age");
try {
fName = firstNameElement.getValue();
lName = lastNameElement.getValue();
age = Integer.parseInt(ageElement.getValue());
ageUnit = ageElement.getAttributeValue("unit");
favColor = favColorElement.getValue();
Writing to a XML File using XOM is very similar to reading it except in this case we are making the
instances instead of retrieving them off the root.
To make a new Element use the constructor Element(String name). You will want to make a root
element so that you can easily add it to a Document.
The Element class has some handy methods for editing elements. They are listed below:
• appendChild(String name) - this will basically set the value of the element to name.
• appendChild(Node node) - this will make node the elements parent. (Elements are nodes so you
https://riptutorial.com/ 1135
can parse elements).
• addAttribute(Attribute attribute) - will add an attribute to the element.
The Attribute class has a couple of different constructors. The simplest one is Attribute(String
name, String value).
Once you have all of your elements add to your root element you can turn it into a Document.
Document will take a Element as an argument in it's constructor.
You can use a Serializer to write your XML to a file. You will need to make a new output stream to
parse in the constructor of Serializer.
Example
Code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import nu.xom.Attribute;
import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Elements;
import nu.xom.ParsingException;
import nu.xom.Serializer;
// make the name element and it's children: first and last
Element nameElement = new Element("name");
Element firstNameElement = new Element("first");
Element lastNameElement = new Element("last");
https://riptutorial.com/ 1136
// make age element
Element ageElement = new Element("age");
public Person(String lName, String fName, String ageUnit, String favColor, int age){
this.lName = lName;
this.fName = fName;
this.age = age;
this.ageUnit = ageUnit;
this.favColor = favColor;
https://riptutorial.com/ 1137
}
https://riptutorial.com/ 1138
Credits
S.
Chapters Contributors
No
https://riptutorial.com/ 1139
Alternative
3 mnoronha, ppeterka, Viacheslav Vedenin
Collections
Apache Commons
5 Jonathan Barbero
Lang
AppDynamics and
TIBCO
6 BusinessWorks Alexandre Grimaud
Instrumentation for
Easy Integration
https://riptutorial.com/ 1140
Slegers, JohnB, Jojodmo, Jonathan, Jordi Castilla, Jorn, Jorn
Vernee, Josh, JStef, JudgingNotJudging, Justin, Kapep,
KartikKannapur, Kayathiri, Kaz Wolfe, Kenster, Kevin Thorne,
Lambda Ninja, Liju Thomas, llamositopia, Loris Securo, Luan
Nico, Lucas Paolillo, maciek, Magisch, Makoto, Makyen, Malt,
Marc, Markus, Marvin, MasterBlaster, Matas Vaitkevicius,
matsve, Matt, Matt, Matthias Braun, Maxim Kreschishin, Maxim
Plevako, Maximillian Laumeister, MC Emperor, Menasheh,
Michael Piefel, michaelbahr, Miljen Mikic, Minhas Kamal, Mitch
Talmadge, Mohamed Fadhl, Muhammed Refaat, Muntasir,
Mureinik, Mzzzzzz, NageN, Nathaniel Ford, Nayuki, nicael,
Nigel Nop, niyasc, noɥʇʎԀʎzɐɹƆ, Nuri Tasdemir, Ocracoke,
OldMcDonald, Onur, orccrusher99, Ortomala Lokni, Panda,
Paolo Forgia, Paul Bellora, Paweł Albecki, PeerNet, Peter
Gordon, phatfingers, Pimgd, Piyush, ppeterka, Přemysl Šťastný
, PSN, Pujan Srivastava, QoP, Radiodef, Radouane ROUFID,
Raidri, Rajesh, Rakitić, Ram, RamenChef, Ravi Chandra, René
Link, Reut Sharabani, Richard Hamilton, Robert Columbia,
rolfedh, rolve, Roman Cherepanov, roottraveller, Ross, Ryan
Hilbert, Sam Hazleton, sandbo00, Saurabh, Sayakiss, sebkur,
Sergii Bishyr, sevenforce, shmosel, Shoe, Siguza, Simulant,
Slayther, Smi, solidcell, Spencer Wieczorek, Squidward,
stackptr, stark, Stephen C, Stephen Leppik, Sualeh Fatehi,
sudo, Sumurai8, Sunnyok, syb0rg, tbodt, tdelev, tharkay,
Thomas, ThunderStruct, Tol182, ʇolɐǝz ǝɥʇ qoq, tpunt, Travis J,
Tunaki, Un3qual, Unihedron, user6653173, uzaif, vasili111,
VedX, Ven, Victor G., Vikas Gupta, vincentvanjoe, Vogel612,
Wilson, Winter, X.lophix, YCF_L, Yohanes Khosiawan , yuku,
Yury Fedorov, zamonier, ΦXocę Пepeúpa ツ
https://riptutorial.com/ 1141
Schauder, JonasCz, Jorn Vernee, juergen d, Makoto, Matt
Champion, philnate, Ram, Santhosh Ramanan, sevenforce,
Stephen C, teek, Unihedron, Uri Agassi, xwoker
14 Benchmarks esin88
Bytecode
20 bloo, Display Name, rakwaht, Squidward
Modification
Calendar and its Bob Rivers, cdm, kann, Makoto, mnoronha, ppeterka, Ram,
22
Subclasses VGR
Choosing
24 John DiFini
Collections
Class - Java
25 gobes, KIRAN KUMAR MATAM
Reflection
Collection Factory
28 Jacob G.
Methods
https://riptutorial.com/ 1142
4castle, A_Arnold, Ad Infinitum, Alek Mieczkowski, alex s,
altomnr, Andy Thomas, Anony-Mousse, Ashok Felix,
Aurasphere, Bob Rivers, ced-b, ChandrasekarG, Chirag Parmar
, clinomaniac, Codebender, Craig Gidney, Daniel Stradowski,
dcod, DimaSan, Dušan Rychnovský, Enigo, Eran, fabian, fgb,
GPI, Grzegorz Górkiewicz, ionyx, Jabir, Jan Vladimir Mostert,
KartikKannapur, Kenster, KIRAN KUMAR MATAM, koder23,
29 Collections KudzieChase, Makoto, Maroun Maroun, Martin Frank,
Matsemann, Mike H, Mo.Ashfaq, Mrunal Pagnis, mystarrocks,
Oleg Sklyar, Pablo, Paweł Albecki, Petter Friberg, philnate,
Polostor, Poonam, Powerlord, ppeterka, Prasad Reddy,
Radiodef, rajadilipkolli, rd22, rdonuk, Ruslan Bes, Samk, SjB,
Squidward, Stephen C, Stephen Leppik, Unihedron,
user2296600, user3105453, Vasiliy Vlasov, Vasily Kabunov,
VatsalSura, vsminkov, webo80, xploreraj
Command line
30 Argument Burkhard, Michael von Wenckstern, Stephen C
Processing
Concurrent
34 GPI, Kenster, Powerlord, user2296600
Collections
https://riptutorial.com/ 1143
Sudhir Singh, Tobias Friedinger, Unihedron, Vasiliy Vlasov,
Vlad-HC, Vogel612, wolfcastle, xTrollxDudex, YCF_L, Yury
Fedorov, ZX9
Creating Images
39 alain.janinm, Dariusz, kajacx, Kenster, mnoronha
Programmatically
Disassembling and
45 ipsi, mnoronha
Decompiling
https://riptutorial.com/ 1144
Dispatch
https://riptutorial.com/ 1145
Stephen C, Stephen Leppik
Functional
60 Andreas
Interfaces
Generating Java
61 Tony
Code
https://riptutorial.com/ 1146
66 Immutable Class Mykola Yashchenko
https://riptutorial.com/ 1147
'javac' C, Sнаđошƒа, Tom Gijselinck
Java Editions,
76 Versions, Releases Gal Dreiman, screab, Stephen C
and Distributions
Java Floating Point Dariusz, hd84335, HTNW, Ilya, Mr. P, Petter Friberg, ravthiru,
77
Operations Stephen C, Stephen Leppik, Vogel612
Java Memory Daniel M., engineercoding, fgb, John Nash, jwd630, mnoronha,
78
Management OverCoder, padippist, RamenChef, Squidward, Stephen C
Java Native Coffee Ninja, Fjoni Yzeiri, Jorn Vernee, RamenChef, Stephen C
81
Interface , user1803551
Java Performance
82 Gene Marin, jatanp, Stephen C, Vogel612
Tuning
Java Pitfalls -
87 Threads and dorukayhan, james large, Stephen C
Concurrency
https://riptutorial.com/ 1148
90 Java SE 7 Features compuhosny, RamenChef
97 JMX esin88
https://riptutorial.com/ 1149
Ritson, Wolfgang, Xaerxess, xploreraj, Yogi, Ze Rubeus
Logging
113 bn., Christophe Weis, Emil Sierżęga, P.J.Meisch, vallismortis
(java.util.logging)
Multi-Release JAR
116 manouti
Files
118 Nested and Inner ChemicalFlash, DimaSan, fgb, hd84335, Mshnik, RamenChef,
https://riptutorial.com/ 1150
Classes Sandesh, sargue, Slava Babin, Stephen C, tynn
https://riptutorial.com/ 1151
Grzegorz Górkiewicz, gwintrob, Hadson, hd84335, hzpz, J Atkin
, Jean-François Savard, John Slegers, Jude Niroshan, Maroun
Maroun, Michael Wiles, OldMcDonald, shmosel, Squidward,
Stefan Dollase, Stephen C, ultimate_guy, Unihedron,
user140547, Vince, vsminkov, xwoker
Parallel
131 programming with Community, Joe C
Fork/Join framework
https://riptutorial.com/ 1152
JD9999, KIRAN KUMAR MATAM, Mureinik, Stephen C,
139 Readers and Writers
VatsalSura
Reference Data Do Nhu Vy, giucal, Jorn Vernee, Lord Farquaad, Yohanes
141
Types Khosiawan
Remote Method
145 RamenChef, smichel, Stephen C, user1803551, Vasiliy Vlasov
Invocation (RMI)
Security &
151 John Nash, shibli049
Cryptography
https://riptutorial.com/ 1153
Bandi, Vasilis Vasilatos, Vasiliy Vlasov
https://riptutorial.com/ 1154
Steve K, Sugan, suj1th, thiagogcm, tpunt, Tunaki, Unihedron,
user1133275, user1803551, Valentino, vincentvanjoe, vsnyc,
Wilson, Ze Rubeus, zwl
https://riptutorial.com/ 1155
Fedorov, Zachary David Saunders, Zack Teater, Ze Rubeus, Φ
Xocę Пepeúpa ツ
The java.util.Objects
170 mnoronha, RamenChef, Stephen C
Class
TreeMap and
172 Malt, Stephen C
TreeSet
Using Other
175 Scripting Languages Nikhil R
in Java
Using
ThreadPoolExecutor
177 Brendon Dugan
in MultiThreaded
applications.
https://riptutorial.com/ 1156
XML Parsing using
182 GPI
the JAXP APIs
XML XPath
183 17slim, manouti
Evaluation
https://riptutorial.com/ 1157