Data Types
_______________⇓_______________
↓ ↓
Primitive Types Reference Types
_________________________⇓_________________________
↓ ↓ ↓
Interface Class Array
booleancharbyte, short, int, longfloat, doublebyte → short → int → longchar → intint → long → float → doubleint → floatlong → floatlong → doublelong value = intValue;Otherwise, you need to manually cast the value from one type to another:
int value = (int) longValue;Note that the value might be truncated if it exceeds the numeric range supported by the target type:
byte value = (byte) 128; // "value" will be equal to -128When applying a binary operator to operands of different types, the following rules apply:
double, the other will be converted to doublefloat, the other will be converted to floatlong, the other will be converted to longint
(byte, short, and char operands are always promoted to int)boolean can hold the values true or false.char can hold characters.char c1 = 'a';A variable of type
char can also hold positive integers.char can hold values in the range: [0, 65535]cast is required to assign an integer value to a variable of type char.char c2 = (char) 65535;A character can be expressed as a hexadecimal value using the prefix \u
char c3 = '\u005B';Escape Characters:
escape character | unicode value | name
\" | \u0022 | Double quote \' | \u0027 | Single quote \\ | \u005c | Backslash \t | \u0009 | Tab \n | \u000a | Line feed \r | \u000d | Carriage return \b | \u0008 | BackspaceUnicode escape characters are interpreted before the code is parsed.
System.out.println("\u0022 + \u0022");
System.out.println("" + "");
char c\u0061 = 'x'; System.out.println(ca); // \u0061 in the identifier becomes the letter 'a'
System.out.println("" "");:
System.out.println("\u0022 \u0022");
// the line feed \u000a will cause multiple compiler errors
// invalid unicode: missing the 4 hex digits after \u: \unicode
char can hold any 16-bit (basic) Unicode character.
For supplementary Unicode characters, each character has a code value (code point) that is represented as a pair of 16-bit code units.
When working with strings that may include supplementary Unicode characters,
you should be aware that a char value might hold just one of the code units representing such a character.
For example, the smiley symbol "🙂" is represented using 2 code units:
String smiley = "🙂";
System.out.println(smiley.length()); // code units count: 2
System.out.println(smiley.codePointCount(0, smiley.length())); // code points count: 1
System.out.println(String.format("%X", (int) smiley.charAt(0))); // first code unit D83D of the smiley character
System.out.println(String.format("%X", (int) smiley.charAt(1))); // second code unit DE42 of the smiley character
System.out.println(String.format("%X", smiley.codePointAt(0))); // code point 1F642 of the smiley character
If you need to print all characters in a string, use the codePoints method of the String class:
"mti🙂tek".codePoints().forEach(cp -> System.out.println(new String(Character.toChars(cp))));
m t i 🙂 t e kSee the Java API documentation for how to use the
Character.toChars method:
public static char[] toChars(int codePoint) //Converts the specified character (Unicode code point) to its UTF-16 representation stored in a char array. //If the specified code point is a BMP (Basic Multilingual Plane or Plane 0) value, the resulting char array has the same value as codePoint. //If the specified code point is a supplementary code point, the resulting char array has the corresponding surrogate pair. //Parameters: //codePoint - a Unicode code point //Returns: //a char array containing the UTF-16 representation of the code point.
byte can hold both positive and negative values.byte can hold values in the range [-128, 127].byte, short, int, long).byte type with 8 bits, the bit weights are:| Bit Position | 7 (MSB) | 6 | 5 | 4 | 3 | 2 | 1 | 0 (LSB) |
|---|---|---|---|---|---|---|---|---|
| Weight | -128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
(-128 × bit7) + (64 × bit6) + (32 × bit5) + (16 × bit4) + (8 × bit3) + (4 × bit2) + (2 × bit1) + (1 × bit0)00000001 = (-128×0) + (64×0) + (32×0) + (16×0) + (8×0) + (4×0) + (2×0) + (1×1) = 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 = 1 10000001 = (-128×1) + (64×0) + (32×0) + (16×0) + (8×0) + (4×0) + (2×0) + (1×1) = -128 + 0 + 0 + 0 + 0 + 0 + 0 + 1 = -127 11111111 = (-128×1) + (64×1) + (32×1) + (16×1) + (8×1) + (4×1) + (2×1) + (1×1) = -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1 1000 0000 = (-128×1) + (64×0) + (32×0) + (16×0) + (8×0) + (4×0) + (2×0) + (1×0) = -128 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = -128
short can hold both positive and negative values.short can hold values in the range [-32,768, 32,767].byte, two's complement representation is used to represent short values.int can hold both positive and negative values.int can hold values in the range [-2,147,483,648 to 2,147,483,647].byte, two's complement representation is used to represent int values.long can hold both positive and negative values.long can hold values in the range [-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807].byte, two's complement representation is used to represent long values.long l1 = 1l; long l2 = 1L;
float can hold real numbers.// 1.0 is a double literal by default, which is why the explicit cast or f suffix is needed. float f1 = 1.0; // compiler error: "Type mismatch: cannot convert from double to float" float f2 = (float) 1.0; // OK float f3 = 1.0f; // OK float f4 = 1.0F; // OKConstant holding the positive infinity of type float:
/** * A constant holding the positive infinity of type float. * It is equal to the value returned by Float.intBitsToFloat(0x7f800000). */ float POSITIVE_INFINITY = 1.0f / 0.0f;Constant holding the negative infinity of type float:
/** * A constant holding the negative infinity of type float. * It is equal to the value returned by Float.intBitsToFloat(0xff800000). */ float NEGATIVE_INFINITY = -1.0f / 0.0f;Constant holding a Not-a-Number (NaN) value of type float:
/** * A constant holding a Not-a-Number (NaN) value of type float. * It is equivalent to the value returned by Float.intBitsToFloat(0x7fc00000). */ float NaN = 0.0f / 0.0f;Check if a variable is not a number:
if (Float.isNaN(f3))The following is always false (use Float.isNaN instead):
if (f3 == Float.NaN)Check if a variable is positive infinity:
if (f3 == Float.POSITIVE_INFINITY)Check if a variable is negative infinity:
if (f3 == Float.NEGATIVE_INFINITY)Check if a variable is a finite floating-point value:
if (Float.isFinite(f3))Check if a variable is either positive infinity or negative infinity:
if (Float.isInfinite(f3))
double can hold real numbers.double d1 = 1.0; // OK double d2 = 1.0d; // OK double d3 = 1.0D; // OKConstant holding the positive infinity of type double:
/** * A constant holding the positive infinity of type double. * It is equal to the value returned by Double.longBitsToDouble(0x7ff0000000000000L). */ double POSITIVE_INFINITY = 1.0 / 0.0;Constant holding the negative infinity of type double:
/** * A constant holding the negative infinity of type double. * It is equal to the value returned by Double.longBitsToDouble(0xfff0000000000000L). */ double NEGATIVE_INFINITY = -1.0 / 0.0;Constant holding a Not-a-Number (NaN) value of type double:
/** * A constant holding a Not-a-Number (NaN) value of type double. * It is equivalent to the value returned by Double.longBitsToDouble(0x7ff8000000000000L). */ double NaN = 0.0d / 0.0;Check if a variable is not a number:
if (Double.isNaN(d1))The following is always false (use Double.isNaN instead):
if (d1 == Double.NaN)Check if a variable is positive infinity:
if (d1 == Double.POSITIVE_INFINITY)Check if a variable is negative infinity:
if (d1 == Double.NEGATIVE_INFINITY)Check if a variable is a finite floating-point value:
if (Double.isFinite(d1))Check if a variable is either positive infinity or negative infinity:
if (Double.isInfinite(d1))
final keyword.
public class MyClass {
void foo() {
Integer var1; // The variable var1 will always be of type Integer!!!
}
}
final keyword, then once it is initialized, its value cannot be changed (in other words, the variable cannot reference another object).
public class MyClass {
void foo() {
Integer var1 = Integer.valueOf(0);
final Integer var2 = Integer.valueOf(0);
var1 = Integer.valueOf(10); // OK
var2 = Integer.valueOf(20); // Compiler error: The final local variable var2 cannot be assigned. It must be blank and not using a compound assignment
}
}
public class MyClass {
void foo() {
Integer var1 = Integer.valueOf(0); // OK: referenced object is the same type (Integer) as variable var1
Object var2 = Integer.valueOf(0); // OK: referenced object type (Integer) is a subtype of variable var2’s type (Object)
String var3 = var1; // Compiler error: Type mismatch: cannot convert from Integer to String
String var4 = var2; // Compiler error: Type mismatch: cannot convert from Object to String
}
}
public class MyClass {
void foo() {
Integer var1 = Integer.valueOf(0);
Object var2 = Integer.valueOf(0);
var1.intValue();
var2.intValue(); // Compiler error: The method intValue() is undefined for the type Object
}
}
public abstract interface MyInterfaceType {}
public and abstract modifiers.public access modifier (in this case it will have default access).abstract modifier; an interface can contain method declarations as well as methods with the default modifier.protected or private.static or final.
public abstract interface MyInterfaceType {
public final static Integer ADD_OPERATION_ID = 0;
Integer MULTIPLY_OPERATION_ID = 1;
}
public, final, and static.public, final, and static;
the compiler adds them by default.protected or private.
public abstract interface MyInterfaceType {
public abstract Integer addOperation(Integer value1, Integer value2);
Integer multiplyOperation(Integer value1, Integer value2);
default Integer identity(Integer i) { return i;}
}
public and abstract.public and abstract; the compiler adds them by default.protected or private.final (because of the abstract keyword), native, or strictfp.abstract keyword) unless they are marked as default.static modifier and must provide an implementation.public access modifier (which is implicit if omitted).extends) only other interfaces (it cannot extend classes).
package com.mtitek.inheritance;
interface MyInterface1 {
public void doAction1();
}
interface MyInterface2 {
public void doAction2();
}
interface MyInterface3 extends MyInterface1, MyInterface2 {
public void doAction3();
}
implements) multiple interfaces.
package com.mtitek.inheritance;
interface MyInterface1 {
public void doAction1();
}
interface MyInterface2 {
public void doAction2();
}
interface MyInterface3 {
public void doAction3();
}
/* The class "SuperClass1" is abstract, so it is not required to implement any of the methods from the interfaces "MyInterface1" and "MyInterface2". */
abstract class SuperClass1 implements MyInterface1, MyInterface2 {
@Override
public void doAction1() {
}
}
/* The class "SuperClass2" is not required to implement the method "doAction1" because it is already implemented by the class "SuperClass1". */
class SuperClass2 extends SuperClass1 implements MyInterface3 {
@Override
public void doAction2() {
}
@Override
public void doAction3() {
}
}
/* The class "SubClass1" is not required to implement any methods because they are already implemented by its superclasses. */
class SubClass1 extends SuperClass2 implements MyInterface2 {
}
default modifier and must provide an implementation.public access modifier (which is implicit if omitted).abstract, static, final, native, strictfp, or synchronized.protected or private.
interface MyInterface4 {
// Abstract method
public abstract void doAction1();
// Default method
default void doAction2() {
doAction3(); // OK: can call private methods
doAction4(); // OK: can call static methods
}
// Static method
static void doAction3() {
System.out.println("This is a static method");
}
// Private method
private void doAction4() {
System.out.println("This is a private method");
}
}
public class MyClass4 {
public static void main(String[] args) {
MyInterface4 myInterface4 = new MyInterface4() {
@Override
public void doAction1() {
System.out.println("This is the implementation of the abstract method");
}
};
myInterface4.doAction1();
myInterface4.doAction2();
MyInterface4.doAction3();
}
}
InterfaceName.super.methodName()
interface MyInterface5 {
default void doAction1() {
System.out.println("Default from MyInterface5");
}
}
interface MyInterface6 {
default void doAction1() {
System.out.println("Default from MyInterface6");
}
}
// Case 1: implements interface with default method
class MyClass5 implements MyInterface5 {
public void doAction2() {
doAction1(); // uses default implementation
}
}
// Case 2: implements interface + overrides default method
class MyClass6 implements MyInterface5 {
@Override
public void doAction1() {
System.out.println("Overridden in MyClass6");
MyInterface5.super.doAction1(); // Can call default implementation
}
public void doAction3() {
doAction1(); // uses overridden method
}
}
// Case 3: Diamond problem - must resolve conflict
class MyClass7 implements MyInterface5, MyInterface6 {
@Override
public void doAction1() {
System.out.println("Overridden in MyClass7");
MyInterface5.super.doAction1(); // Must choose implementation to resolve conflict
}
public void doAction4() {
doAction1(); // uses overridden method
}
}
public class MyClass8 {
public static void main(String[] args) {
new MyClass5().doAction1(); // call MyInterface5
new MyClass5().doAction2(); // call MyClass5
new MyClass6().doAction1(); // call MyClass6
new MyClass6().doAction3(); // call MyClass6
new MyClass7().doAction1(); // call MyClass7
new MyClass7().doAction4(); // call MyClass7
}
}
extends) only one class.implements) multiple interfaces.new).this.final, static, or abstract.
class MyClassType implements MyInterfaceType {
MyClassType() {
// constructor code
}
@Override
public Integer addOperation(Integer value1, Integer value2) {
return value1 + value2;
}
@Override
public Integer multiplyOperation(Integer value1, Integer value2) {
return value1 * value2;
}
}
Object type structure that can hold a fixed number of elements of the same type (primitive or reference).int myIntsArray[] = new int[10]; myIntsArray[0] = 3; System.out.println(myIntsArray.length); // 10 System.out.println(myIntsArray[0]); // 3Declare an array that can hold objects:
Object[] myObjectsArray = new Object[5]; myObjectsArray[0] = Integer.valueOf(7); System.out.println(myObjectsArray.length); // 5 System.out.println(myObjectsArray[0]); // 7Declare a String array and initialize it with initial values:
String[] myStringsArray = {"value1", "value2"};
// explicit syntax:
String[] myStringsArray = new String[] {"value1", "value2"};
Declare an Object array and initialize it with initial values:
Object[] myComplexObjectsArray = { myStringsArray, myObjectsArray, myIntsArray };
// explicit syntax:
Object[] myComplexObjectsArray = new Object[] { myStringsArray, myObjectsArray, myIntsArray };
Declare a 2-dimensional array and initialize it with initial values:
String[][] myStringsArray2D = {{"value11", "value12"}, {"value21", "value22"}, {"value31", "value32"}, {"value41", "value42"}};
// explicit syntax:
String[][] myStringsArray2D = new String[][] {{"value11", "value12"}, {"value21", "value22"}, {"value31", "value32"}, {"value41", "value42"}};
System.out.println(myStringsArray2D.length); // 4
System.out.println(myStringsArray2D[0].length); // 2
Declare an empty array:
String[] emptyArray1 = new String[0];
String[] emptyArray2 = {};
String[] emptyArray3 = new String[] {};
System.out.println(emptyArray1.length); // 0
System.out.println(emptyArray2.length); // 0
System.out.println(emptyArray3.length); // 0
To iterate over an array, use a "for-each" loop: for (type element : array) statementcopyOf" method of the "Arrays" class: Arrays.copyOf(array, array.length)sort" method of the "Arrays" class: Arrays.sort(array)