0% found this document useful (0 votes)
7 views

Data types and Control Statements

The document provides a comprehensive overview of Java keywords, detailing over 50 reserved keywords that have special meanings in the Java programming language. It categorizes these keywords into groups such as access modifiers, flow control, and error handling, and explains specific keywords like abstract, assert, and enum with examples of their usage. Additionally, it highlights the significance of certain keywords and their evolution in Java versions, such as the introduction of 'var' in Java 10 and 'record' and 'yield' in Java 14.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Data types and Control Statements

The document provides a comprehensive overview of Java keywords, detailing over 50 reserved keywords that have special meanings in the Java programming language. It categorizes these keywords into groups such as access modifiers, flow control, and error handling, and explains specific keywords like abstract, assert, and enum with examples of their usage. Additionally, it highlights the significance of certain keywords and their evolution in Java versions, such as the introduction of 'var' in Java 10 and 'record' and 'yield' in Java 14.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Java Keywords

You know, the Java programming language has over 50 reserved keywords which have
special meaning for the compiler and cannot be used as variable names. Following is
a list of Java keywords in alphabetical order. You can click on an individual
keyword to see its description and usage example.

abstract assert boolean


break byte case
catch char class
const continue default
do double else
enum extends final
finally float for
goto if implements
import instanceof int
interface long native
new package private
protected public return
short static strictfp
super switch synchronized
this throw throws
transient try void
volatile while var
record yield

Some noteworthy points regarding Java keywords:

const and goto are resevered words but not used.


true, false and null are literals, not keywords.
Since Java 8, the default keyword is also used to declare default methods in
interfaces.
Since Java 10, the word var is used to declare local variables (local variables
type inference). For backward compatibility, you can still use var as variable
names. So var is a reserved word, not keyword.
Java 14 adds two new keywords record and yield (but in preview mode)
all keywords are in lower-case.

And based on categories, the keywords in Java can be grouped as follows:

Access modifiers: private, protected, public

Class, method, variable modifiers:

abstract, class, default, extends, final,


implements, interface, native, new,

static, strictfp, synchronized, transient,

var, record, volatile

Flow control:

break, case, continue, default, do, else,

for, if, instanceof, return, switch, while,

yield

Package control: import, package

Primitive types: boolean, byte, char,

double, float, int, long, short

Error handling: assert, catch, finally,

throw, throws, try

Enumeration: enum

Others: super, this, void

Unused (reserved): const, goto

continued..

# abstract

the abstract keyword is used to declare a class or a method as abstract. An


abstract class can have abstract methods which have to be implemented by its sub
classes. An abstract method does not have concrete implementation or body, and must
ends with a semicolon. The following example declares a class Car as abstract:
public abstract class Car {
public abstract void drive();
}
The method drive() is also declared as abstract.

1. Some rules for abstract class and abstract method:


An abstract class:

cannot be instantiated by the new keyword. The purpose of an abstract class is to


be inherited by derived classes.
can have both abstract and non-abstract methods.

An abstract method:

does not have body and must end with a semicolon.


must be implemented by concrete sub classes.
makes the enclosing class must be declared as abstract also

2. Java abstract class and method example


A class that extends the abstract Car class and implements its abstract method:

class PoliceCar extends Car {


public void drive() {
// drive faster than normal car
}
}
An abstract class has both abstract and non-abstract methods:

abstract class Airplane {


public abstract void takeOff();
public void landing() {
// landing smoothly
}
}

# assert

The assert keyword is used in assertion statement which is a feature of the Java
programming language since Java 1.4. Assertion enables developers to test
assumptions in their programs as a way to defect and fix bugs.
1. Syntax of assert statement
Syntax of an assert statement is as follow (short version):

assert expression1;

or (full version):

assertexpression1 : expression2;

Where:

expression1 must be a booleanexpression.


expression2 must return a value (must not return void).
The assert statement is working as follows:

If assertion is enabled, then the assert statement will be evaluated. Otherwise, it


does not get executed.
If expression1 is evaluated to false, an AssertionError error is thrown which
causes the program stops immediately. And depending on existence of expression2:
If expression2 does not exist, then the AssertionError is thrown with no detail
error message.
If expression2 does exist, then a String representation of expression2’s return
value is used as detail error message.

If expression1 is evaluate to true, then the program continues normally.

2. Enable assertion in Java


By default, assertion is disabled at runtime. To enable assertion, specify the
switch –enableassertions or -ea at command line of java program. For example, to
enable assertion for the program called CarManager:

java –enableassertions CarManager

or this for short:

java –ea CarManager

Assertion can be enabled or disable specifically for named classes or packages. For
more information on how to enable and disable assertion, read this article.

3. Java Assertion examples


The following simple program illustrates the short version of assertstatement:

public class AssertionExample {


public static void main(String[] args) {
// get a number in the first argument
int number = Integer.parseInt(args[0]);

assert number <= 10; // stops if number > 10

System.out.println("Pass");

}
}
When running the program above with this command:

java -ea AssertionExample 15

A java.lang.AssertionError error will be thrown:

Exception in thread "main" java.lang.AssertionError

at AssertionExample.main(AssertionExample.java:6)

But the program will continue and print out “Pass” if we pass a number less than
10, in this command:

java -ea AssertionExample 8

And the following example is using the full version of assert statement:

public class AssertionExample2 {


public static void main(String[] args) {

int argCount = args.length;

assert argCount == 5 : "The number of arguments must be 5";

System.out.println("OK");

}
}
When running the program above with this command:

java -ea AssertionExample2 1 2 3 4

it will throw this error:

Exception in thread "main" java.lang.AssertionError: The number of arguments must


be 5

at AssertionExample2.main(AssertionExample2.java:6)

Generally, assertion is enabled during development time to defect and fix bugs, and
is disabled at deployment or production to increase performance.

# continue

the continue keyword is used to stop execution of a current iteration in a for loop
or a while loop, then advance to the next iteration. The statements after the
continue keyword won’t be executed. The syntax is as follows:

for/while (expressions) {
// statemenst 1...
if (condition) {
continue;
}
// statements 2...
}
The following example uses continue keyword to skip the even value of the variable
i, thus the for loop will print out all the odd numbers from 1 to 100:

for (int i = 1; i < 100; i++) {


if (i % 2 == 0) {
continue;
}
System.out.println(i);
}
Similarly, the following while loop will produce a list of even numbers from 1 to
100:

int count = 1;
while (count <= 100) {
if (count % 2 != 0) {
count++;
continue;
}
System.out.println(count);
count++;
}

# default

Basically, there are 3 places you can use the default keyword in Java:

Specify the default value in a switch case statement


Declare default values in a Java annotation
Declare default method in an interface
Let’s see some code examples that use the default keyword.

In the following method, the default keyword is used in as switch case statement to
return the default value for other cases:

public static int getDaysOfMonth(int month) {


switch (month) {
case 2:
return 28;
case 4:
case 6:
case 9:
case 11:
return 30;
default:
return 31;
}
}

In the following example, the default keyword is used to declare default value for
a method in a custom annotation class:

public @interface Editable {

boolean value() default false;

String name() default "Untitled";


}

And lastly, the default keyword is used to declare a default method in an


interface. For example:
public interface Animal {

public void eat();

public void move();

public default void sleep() {

// implementation goes here...

}
}
The purpose of default method is to add new methods to an interface that will not
break the existing subtypes of that interface.

# enum

the enum keyword is used to declare a new enumeration type. This keyword has been
introduced since Java 5. The declaration syntax for an enum type is as follows:

enum <name> {
<enum_constant_1>,
<enum_constant_2>,
...
<enum_constant_n>
<enum_constructor>
// other variables & methods as usual
}
An enum constant can be declared as follows:

<constant_name>[(arguments)] [{class body}]

Some rules for enum type in Java:


An enum constant specifies an instance of the enum type.
An enum constant can be optionally followed by a list of arguments and a class
body. The class body is an anonymous class which conforms to rules of anonymous
classes and:
It cannot have any constructor.
It cannot have any abstract methods.
Instance methods declared in the class body are only accessible if they override
accessible methods declared in the enclosing enum type.
An enum type cannot be declared abstract or final
The Enum<E>is the direct superclass of an enum type.
An enum type can be only declared inside class level, same as class level or in a
separate source file. It cannot be declared inside a method or an inner class.
An enum type can have constructors, methods and variables just like a regular Java
class.
Java enum type examples:
A simplest enum type declared inside a class:

class Foo {
enum DayOfWeek {MON, TUE, WED, THU, FRI, SAT, SUN};
}
A simple enum type declared in a separate Java file:

public enum ErrorCode {


LOW, HIGH, SEVERE
}
An enum type which contains constructor, method and variable:

enum Day {
MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6), SUN(7);

Day(int dayNumber) {
this.dayNumber = dayNumber;
}

private int dayNumber;

public int getDayNumber() {


return this.dayNumber;
}
}
An enum type with class body for each enum constant:

enum Priority {
LOW {
int getPriorityNumber() {
return 0;
}
},

NORMAL {
int getPriorityNumber() {
return 1;
}
},

HIGH {
int getPriorityNumber() {
return 2;
}
},

SEVERE {
int getPriorityNumber() {
return 3;
}
};

abstract int getPriorityNumber();


}

# instanceof

the instanceof keyword is used to check whether an object is an instance of a


particular class or interface. For example:

Object msg = new String("Hello");


if (msg instanceof String) {
System.out.println("A String");
}

The instanceof operation returns true if the variable is of type (or subtype) of
the specified calss. The above code will give the output "A String" because msg is
of type String.

So we can consider instanceof as an operator. It is widely used in when overriding


the equals() method, for example:

public class Student {

public boolean equals(Object obj) {


if (obj instanceof Student) {
// comparing...
}

return false;
}
}

# native

the native keyword is used to declare a method which is implemented in


platform-dependent code such as C or C++. When a method is marked as native, it
cannot have a body and must ends with a semicolon instead. The Java Native
Interface (JNI) specification governs rules and guidelines for implementing native
methods, such as data type conversion between Java and the native application.

The following example shows a class with a method declared as native:

public class NativeExample {

public native void fastCopyFile(String sourceFile, String destFile);


# return

the return keyword is used to stop execution of a method and return a value for the
caller. Usage of this keyword is as following:

return value;

where value is can be of:

A reference of any Java object.


A literal of String, boolean, number or null.
For example:

String getName() {
return "Peter";
}

int getAge() {
int myAge = 29;
return myAge;
}

Object getObject() {
Object myObject = new Object();
// do something with my object...
return myObject;
}

The return keyword can also be used to stop execution of a void method and return
to the caller, for example:

void doSomething() {
// do something
if (condition) {
return;
}
}

# static

the static keyword can be applied for inner classes, methods and variables.

- Static methods and variables are shared among all instances of a class. They can
be invoked and accessed without creating new instances of the class. The following
example shows a class contains a static variable, a static method and a regular
method:
public class Car {
static String color;

static void beep() {


//beep beep!
}

void brake() {
// stop
}
}
The static variable color and static method beep() can be accessed like this:

Car.color = "Red";
Car.beep();
whereas the regular method brake() must be called on an instance of Car class:

Car myCar = new Car();


myCar.brake();
- A regular class cannot be static, only inner class can be static. The following
example shows an example of a static inner class:

public class Car {


static class Engine {
}
}
The inner class Engine can be instantiated without creating an instance of the
enclosing class Car, for example:

Car.Engine carEngine = new Car.Engine();

# strictfp

The strictfp keyword is used to force the precision of floating point calculations
(float or double) in Java conform to IEEE’s 754 standard, explicitly. Without using
strictfp keyword, the floating point precision depends on target platform’s
hardware, i.e. CPU’s floating point processing capability. In other words, using
strictfp ensures result of floating point computations is always same on all
platforms.

The strictfp keyword can be applied for classes, interfaces and methods.

Some Rules about strictfp:


strictfp cannot be applied for constructors.
If an interface or class is declared with strictfp, then all methods and
nested types within that interface or class are implicitly strictfp.
strictfp cannot be applied for interface methods.

Java strictfp keyword Examples:


The following class is declared with strictfp, hence all the floating point
computations within that class conform to IEEE’s 754 standard:

strictfp class StrictFPClass {


double num1 = 10e+102;
double num2 = 6e+08;
double calculate() {
return num1 + num2;
}
}
The following interface is declared with strictfp, but its methods cannot:

strictfp interface StrictFPInterface {


double calculate();
strictfp double compute(); // compile error
}
The following method is declared with strictfp:

class StrictFPMethod {
strictfp double computeTotal(double x, double y) {
return x + y;
}
}

# switch

The switch-case construct is a flow control structure that tests value of a


variable against a list of values. Syntax of this structure is as follows:

switch (expression) {
case constant_1:
// statement 1
break;
case constant_2:
// statement 2
break;
case constant_3:
// statement 3
break;
//...
case constant_n:
// statement n
break;
default:
// if all the cases do not match
}

Some Rules about switch-case construct:


The expression is a variable or an expression which must be evaluated to
one of the following types:
Primitive numbers: byte, short, char and int
Primitive wrappers: Byte, Short, Characterand Integer.
Enumerated types (enum type).
String literals (since Java 1.7)
The constant_1, constant_2, constant_3, …, constant_n must be a constant
or literals of the allowed types.
Each case is tested from top to bottom, until a case is matched and a
break statement is found.
If a case matches the expression, the statements block after the case
clause are executed, until a break statement is reached.
It is not required that each case must have a corresponding break
statement. If a matching case block does not have a break statement, the execution
will fall through the next case block, until a first break statement is reached or
end of switch statement is encountered.

The statements block after default will be executed if there is no


matching case found.

Some Java switch-case examples:


The following example shows a switch statement that tests for an integer
variable. It products the output: The number is Three

int number = 3;

String text = "";

switch (number) {
case 1:
text = "One";
break;
case 2:
text = "Two";
break;
case 3:
text = "Three";
break;
default:
text = "Other number";
}

System.out.println("The number is: " + text);

The following example shows a switch statement that tests for a String variable,
without a default block. It will output: The distance from earth to Jupiter is: 4

String planet = "Jupiter";

long distanceFromEarth = 0;

switch (planet) {
case "Mars":
distanceFromEarth = 3;
break;
case "Saturn":
distanceFromEarth = 5;
break;
case "Jupiter":
distanceFromEarth = 4;
break;
case "Venus":
distanceFromEarth = 1;
break;
}

System.out.println("The distance from earth to " + planet + " is: " +


distanceFromEarth);

The following example shows a switch statement that tests for an enum
type, Priority. It will output the result: Task priority: 3

Priority priority = Priority.HIGH;

int taskPriority = 0;

switch (priority) {
case LOW:
taskPriority = 1;
break;
case NORMAL:
taskPriority = 2;
break;
case HIGH:
taskPriority = 3;
break;
case SEVERE:
taskPriority = 4;
break;
}

System.out.println("Task priority: " + taskPriority);


The enum Priority is declared as follows:

1
public enum Priority { LOW, NORMAL, HIGH, SEVERE }

From Java 14, you can use switch block as an expression. For example:

int taskPriority = switch (priority) {


case LOW -> 1;
case NORMAL -> 2;
case HIGH -> 3;
case SEVERE -> 4;
};

System.out.println("Task priority: " + taskPriority);

# synchronized

The synchronized keyword is used for code blocks and methods where thread-safe
matters and for multi-threaded (concurrent) programming. A synchronized method or a
synchronized statement can be executed by only one thread at a time.

The syntax for a synchronizedmethod is as follows:

<method modifier> synchronized <method signature> {


// synchronized code block
}

The syntax for a synchronizedstatement is as follows:

synchronized (expression) {
// synchronized code block
}

Some Rules about synchronized keyword:


- The expression must be evaluated to a reference type, i.e an object
reference.

- The current executing thread will try to acquire a lock before executes
the synchronized code block:

For synchronized statement: the monitor associates with the object returns by the
expression.
For synchronized method:
If the method is static, the lock associates with the Class object of the class in
which the method is declared.
If the method is non-static, the lock associates with this – the object for which
the method is invoked.
- If the lock is not acquired by any thread, the current executing thread
will own the lock and execute the synchronized code block.

- While the current executing thread owns the lock, no other threads can
acquire that lock.

- When the synchronized code block completes, the current executing thread
releases the lock.

- There is no something called “synchronized constructor”.

Java synchronized keyword Examples:


The following code example illustrates the synchronized keyword is applied for a
static method:

class Counter {
private static int count;
static synchronized void increase() {
count++;
}
}

The following code example shows instance methods are synchronized:

class BankAccount {
private double balance;
synchronized void withdraw(double amount) {
this.balance -= amount;
}
synchronized void deposit(double amount) {
this.balance += amount;
}
}

The following code example shows a synchronized statement is applied for a code
block, not a method:
Object lock = new Object();
synchronized (lock) {
System.out.println("Synchronized statement");
}

# transient

the transient keyword is used to mark a member variable (field) not a part of the
persistent state of an object, i.e. the field will not be persisted when its parent
object is serialized.

The following example shows a class which has a transient variable:

class Rectangle {
int width;
int height;
transient long area;
}
When an object of Rectangle class is being serialized, the fields width and height
will be persisted, but the field area.

The transient keyword can be only applied for member variable, not for class,
method and local variable.

# volatile

The volatile keyword can be applied for only member variables (fields). When a
volatile variable is accessed concurrently by threads, its value is updated
consistently among threads. In some cases, using volatile can be an alternative to
using synchronized code.

Example:

class VolatileExample {

volatile int x;

}
Rules:

The volatile keyword cannot be applied for class, method and local
variable.
A final variable cannot be declared volatile.

# var
var keyword is added to the Java language since Java 10 (JDK 10), supporting a new
feature called local variable type inference, in which Java compiler guesses the
type of the variables based on the surround context – allowing programmers to not
declare the type explicitly.

Consider the following statement that declares a local variable:

List<String> list = new ArrayList<String>();


As you can see, in this variable declaration, the type information (List and
String) is repeated two times, both on the left side and right side, which causes
repetition and boilerplate code.

So it can be rewritten using the var keyword like this:

var list = new ArrayList<String>();


This may not be obvious to see the benefit of using the var keyword. Let’s consider
another example:

List<String> list = Arrays.asList("One", "Two", "Three", "Four", "Five");


You can rewrite this statement using var like this:

var list = Arrays.asList("One", "Two", "Three", "Four", "Five");


Here, the Java compiler can infer the type of the variable list because the return
type of the method.

Then you can use the inferred variable:

String first = list.get(0);


Take another example. Consider the following method:

public Map<String, List<Student>> foo() {

// return a map

}
Without using var, you have to specify the type explicitly when calling the foo()
method like this:

Map<String, List<Student>> map = foo();


But using var, thing gets pretty much easier:

var map = foo();


So you see, using var keyword makes the code succinct, more readable and reduces
boilerplate. However, there are some restrictions as well:

You can use var only for local variables (in methods). It cannot be used for
instance variables (at class level).
You cannot use var in Lambda expressions.
You cannot use var for method signatures (in return types and parameters).
And remember, you cannot use var to declare a variable without explicit
initialization, hence the following:

var x;
is not allowed, since local variable declaration requires initialization on the
right side. That also means this declaration is not valid:

var x = null;

# record

the record keyword is used to declare a special class type that acts as a “data
carrier” i.e. model class or POJO class. This keyword is added to the Java language
since JDK 14.

Consider an example:

record Point(int x, int y) { }

The Java compiler will generate appropriate constructor, getters and setters for
all fields, equals(), hashCode() and toString() methods for a record type. The
record type Point above is equivalent to code the following class:

public class Point {


private int x;
private int y;

public Point(int x, int y) {


this.x = x;
this.y = y;
}

public void setX(int x) {


this.x = x;
}

public int getX() {


return this.x;
}

public void setY(int y) {


this.y = y;
}

public int getY() {


return this.y;
}

public boolean equals(Object obj) {


// implement equals based on fields x and y
}

public int hashCode() {


// implement hashCode based on fields x and y
}

public String toString() {


// implement toString based on fields x and y
}
}
So as you can see, with the new record type, you can save a lot of time when coding
such POJO classes. You also avoid error-prone implementation of equals() and
hashCode() if you do it by yourself.

The record type feature is under review in JDK 14 (preview) and it will be
finalized in future JDK releases.

# yield

The yield keyword is added to the Java language since Java 14, for implementing
switch expression.

It is used to return value from a case in a switch expression. For example:

int x = switch (dayOfWeek) {


case MONDAY:
yield 2;
case TUESDAY:
yield 3;
case WEDNESDAY:
yield 4;
default:
yield 0;
};

If the switch block is used with new form of switch label “case L ->”, the yield
keyword is used to return a value in a case arm that is a block of code. For
example:

int x = switch (dayOfWeek) {


case MONDAY -> 2;

case TUESDAY -> 3;

case WEDNESDAY -> 4;

case THURSDAY, FRIDAY -> 5;


case SATURDAY, SUNDAY -> {
// line 1..
// line 2...
// line 3...
yield 8;
}

};

Note that the code after yield can be an expression that returns a value. For
example:

int days = switch (month) {


case 1, 3, 5, 7, 8, 10, 12:
yield 31;

case 4, 6, 9:
yield foo();

case 2:
yield (year % 4 == 0 ? 29 : 28);

default:
throw new IllegalArgumentException();
};

In this example, foo() is a method that returns an integer value.

You might also like