Working with Java data types
- Use primitives and wrapper classes, including, operators, parentheses, type promotion and casting
- Handle text using
StringandStringBuilderclasses- Use local variable type inference, including as lambda parameters
Java primitive types are boolean(falseandtrueas possible values),char,byte,short(16-bit long),int,long(64-bit long),floatanddoubleRule(s)
- Primitive types have equivalent wrapper types:
Boolean,Character…, which must be used in generics.- Non-primitive types are constructed as data structures by means of the
classkeyword. Note thatStringin Java is not a primitive type!- The
interfacekeyword is also part of the Java typing system.- Differently from C++,
voidcannot be used as the type of a variable. However, as a Java construct,voidis itself the unique instance of a type. More precisely,java.lang.Voidconveys us to the type ofvoidas shown in the following example.Example Primitive_types.Java.zip
![]()
try { assert (java.lang.Void.class == void.class); // The 'Void' type *IS NOT* itself the direct type of 'void' assert (java.lang.Void.TYPE == void.class); // Yes, it works! } catch (AssertionError ae) { // Run program with '-ea' option System.err.println(ae.getMessage()); // Error comes from first assertion! }Rule(s)
- Differently from C++, Java primitive types have fixed sizes. For example, the size of
shortis 16-bit long. Variation intervals are accessible through wrapper types, for example: [Short.MIN_VALUE(- 215)Short.MAX_VALUE(215 - 1)].- Common types are:
java.lang.Object(single root of inheritance graph),java.lang.System,java.lang.Error, etc. From Java 5, there is a seamless mapping (the idea of “autoboxing”) between primitive types and their counterparts as wrapper types in the Java kernel, i.e.,java.lang.Example
float x = 1.F; Float y = new Float(1.F); // Heavy style, to be avoided… float z = x + y; // Autoboxing: 'float' and 'Float' are seamlessly compatibleRule(s)
- The type of a variable can be tested by means of the
instanceofoperator with limitations.Example Primitive_types.Java.zip
![]()
int i; // assert(i instanceof int); // Type of a variable like 'i' having a primitive type like 'int' cannot be tested (compilation error) // assert(i instanceof Integer); // Compilation error as well... String surname = "Barbier"; assert(surname instanceof String); // This works (no assertion error at execution time)! Don't forget that 'java.lang.String' is not a primitive but a constructed typeExample
public class User_defined_type { boolean attribute0; byte attribute1; short attribute2; int attribute3; long attribute4; float attribute5; double attribute6; char attribute7; public static void main(String[] args) { User_defined_type object = new User_defined_type(); object.attribute0 = true; System.out.println(object.attribute0); // 'true' object.attribute1 = '\r'; System.out.println(object.attribute1); // '13' object.attribute2 = 0x7777; System.out.println(object.attribute2); // '30583' object.attribute3 = 0xFFFFFFFF; System.out.println(object.attribute3); // '-1' object.attribute4 = Long.MAX_VALUE; System.out.println(object.attribute4); // '9223372036854775807' object.attribute5 = 6.5E1F; System.out.println(object.attribute5); // '65.0' object.attribute6 = 7.2e-2D; System.out.println(object.attribute6); // '0.072' object.attribute7 = 66; System.out.println(object.attribute7); // 'B' } }Rule(s)
- The necessity of converting a type to another or more generally mixing objects/variables with different types in expressions calls for type promotion and casting.
Example
short s1 = 0; int i = s1; // Type promotion... short s2 = (short) i; // Casting with possible undesired side effects (data loss)...Rule(s)
- Strings are immutable objects in Java.
Example
StringBuilder s = new StringBuilder(""); s.append("Franck"); s.append(' '); s.append("Barbier"); String s1 = "", s2 = s1; assert (s1 == s2); s1 += "Franck"; // 's1' refers to a *NEW* memory object... s1 += ' '; // Again, 's1' refers to a *NEW* memory object... s1 += "Barbier"; // And, again, 's1' refers to a *NEW* memory object... assert(s1 != s2);
Basic (i.e., primitive) arrays in Java Rule(s)
- Java basic arrays, e.g.,
char given_name[] = {'F','r','a','n','c','k'};are values of a primitive type (this is similar to JavaScript arrays).Example
assert (!(given_name instanceof Object)); // So, primitive type... assert (given_name.getClass() == char[].class); // More precisely...Rule(s)
- Java primitive arrays have elements, whose type may be primitive or not.
Example
Object tab[] = new Object[1000]; String another_tab[] = new String[1000]; assert(tab instanceof Object[]); assert(another_tab instanceof Object[]); // Initialization: Object my_tab[] = new Object[]{new Object()}; // 'my_tab' is created with one object inside at position '0' assert(my_tab.length == 1);Rule(s)
- The use of primitive arrays is questionable since generic “containers” exist in Java, e.g.,
java.util.ArrayList<E>. Primitive arrays are useful when array size is steady in a Java program. Instead, generic arrays may grow or slim on demand without specific memory management.
java.lang.Object class
Rule(s)
java.lang.Objectclass is the root of the Java inheritance tree. By default, unless an explicit inheritance declaration, any constructed class inherits fromjava.lang.Object. So,public User_defined_type extends java.lang.Object { …is totally equivalent topublic User_defined_type { …. This behavior is fairly different from C++, which has no inheritance graph root.Multithreading related method(s) in
java.lang.Objectvoid wait() throws InterruptedException // + variants void notify() // + variantsObject identity related method(s) in
java.lang.Objectprotected Object clone() throws CloneNotSupportedException boolean equals(Object object) int hashCode()Example Hashtable_illustration.Java.zip
![]()
String s1 = "Franck"; String s2 = "Franck"; assert (s1 != s2); // 's1' and 's2' are NOT the same memory object assert (s1.equals(s2)); // However, 's1' equals to 's2' assert (s1.hashCode() == s2.hashCode());Utility related method(s) in
java.lang.ObjectString toString()Finalization related method(s) in
java.lang.Objectprotected void finalize() throws ThrowableExample
System.finalization(); // Alternatively: Runtime.getRuntime().runFinalization();
Rule(s)
- As statically typed programming language, Java imposes the typing of objects. Usages are then checked by the compiler in conformance with “announced” types. Contrary to JavaScript or Python, anomalies as potential execution errors are eliminated at compilation time (execution time for JavaScript or Python). Nonetheless, “type announcement” may create no added-value code. In this scope, type inference is the ability of the compiler to derive the type of an object.
- From Java 10, the
varkeyword forces the compiler to establish the type an object on its own.
varkeyword (Java 10)Example (diamond-based instantiation omits effective type(s) in place of generic type(s))
java.util.Map<Integer, Double> polynomial = new java.util.HashMap<>(); polynomial.put(1, -12.D); polynomial.put(39, 8.D);Example
// var polynomial = new java.util.HashMap<>(); // Danger => 'java.util.HashMap<Object,Object>' var polynomial = new java.util.HashMap<Integer, Double>(); // Diamond-based instantiation is avoided with 'var'... polynomial.put(1, -12.D); polynomial.put(39, 8.D);
varkeyword in conjunction with lambda expression (Java 11)Rule(s)
- From Java 11, the
varkeyword is allowed in lambda expression syntax.Example From_Java_9.Java.zip
var positives = java.util.Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); var stream = positives.stream().filter((var p) -> p > 1 && java.util.stream.IntStream.rangeClosed(2, (int) Math.sqrt(p)).noneMatch((var i) -> (p % i == 0))); var primes = stream.collect(java.util.stream.Collectors.toList()); primes.forEach((var p) -> System.out.print(" " + p)); // '2 3 5 7 11' is displayed...Rule(s)
- The
varkeyword may seem useless since the type of lambda expression parameters is “naturally” inferred. However, special cases show the relative interest ofvar.Example From_Java_9.Java.zip
(annotation imposes
Integerandintas types of lambda expression parameters)@java.lang.annotation.Target(value = java.lang.annotation.ElementType.PARAMETER) @interface Must_be_positive { } … var stream = positives.stream().filter((@Must_be_positive Integer p) -> p > 1 && java.util.stream.IntStream.rangeClosed(2, (int) Math.sqrt(p)).noneMatch((@Must_be_positive int i) -> (p % i == 0))); … primes.forEach((@Must_be_positive Integer p) -> System.out.print(" " + p)); // '2 3 5 7 11' is displayed...Example From_Java_9.Java.zip
(using
varejectsIntegerandint)… var stream = positives.stream().filter((@Must_be_positive var p) -> p > 1 && java.util.stream.IntStream.rangeClosed(2, (int) Math.sqrt(p)).noneMatch((@Must_be_positive var i) -> (p % i == 0))); … primes.forEach((@Must_be_positive var p) -> System.out.print(" " + p)); // '2 3 5 7 11' is displayed...See also