Java (1995) has C-like syntax with curly braces. It's an imperative, garbage collecting language with developed C++-like OOP. New versions support lambdas. Very similar to C#.
As a whole Java syntax is very stable, and many features are implemented as classes instead of syntax, for example, Optional
.
Java has extensive standard library.
Related languages: Kotlin, C#, JavaScript, C++.
There're two category of types:
- primitive types
- reference types
Primitive types have value semantics.
Primitive types are:
boolean
, byte
, short
, int
, long
, float
, double
, char
A programmer can't create new primitive types.
All numeric types in Java are signed! (char
is unsigned.)
char
is a single 16-bit Unicode character, as in C# and JavaScript. So Java has good support of Unicode out of the box.
TOADD: records
All other types are reference types. For example, Object
, String
, ArrayList
.
There's also distinct type category for C-like arrays of fixed-size. Arrays have reference semantics also.
Literals for primitive types:
true false
123_456 123_456L (long) (there's no `byte` or `short` suffix)
0xfe, 0b1010
+123.0e10 (double), 123.0f, 123.0d (exists, but not needed)
'a', 'b', 'c'
Literals for reference types:
"hello"
null
Special characters:
\b (backspace)
\t (tab)
\n (line feed)
\f (form feed)
\r (carriage return)
\" (double quote)
\' (single quote)
\\ (backslash)
There're also weird special class literals:
Object.class
Integer.class
String.class
ArrayList.class
int[] a = { 11, 22, 33 };
a.length
a[0], a[1], a[2]
Note that array length
is a special attribute, so no ()
.
No slice syntax. No negative indices.
TOCHECK: No methods.
Strings are immutable.
Strings has no indexed access, but there is charAt
method.
Strings can be null
.
s.length()
Operator ==
compares strings' identities, not values (but there's equals
method).
s.equals(t)
Everything but local variables is zero-initialized (default-initialized) by default.
`false`, `0`, `+0.0`,`'\0'`, `null`
Java does definite initialization (DI) analysis.
final
variables can obtain value after introduction, or in different code paths thanks to DI analysis.
Java requires all code path to have return
-like statement in a function.
For uninitialized variables Java has definite initialization analys, used also for final
local variables.
There're two switch
construct syntaxes: C-like and shortened switch
statement/expresion:
int x = 1;
String s = switch (x) {
case 1 -> "one";
case 2 -> "two";
default -> "?";
};
Generics in Java are checked on compile time and then normalized to use Object
internally. It's called type erasure. So there is no reification of templated code.
TOCHEK: Generics on primitive types are impossible, due to type erasure, because primitive types are not convertable to Object
easily. But one can write generic code on boxed primitives, like Boolean
, Character
, Integer
.
Static methods do not inherit genericness of a class. To make a static method generic, one can use the following syntax:
public static <T> Optional<T> of(T value) {
}
ArrayList::size
TODO