Java
everything that seemed like a good idea 20 years ago
see object-oriented programming
hello world
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
compilation and execution:
java HelloWorld.java
a painful language
java › auto boxing is a band-aid and java › wrappers are a duct-tape solution
java does not support operator overloading. java does not have first-class functions
java does not allow the creation of generic arrays E[] a = new E[capacity] where E is the generic type. E[] = (E[]) Object[capacity] is to be used instead, which will generate a compile-time a warning, which may be suppressed using the decorator @SuppressWarnings("unchecked") --- https://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java
java has simplistic type inference, through the var keyword --- https://www.geeksforgeeks.org/var-keyword-in-java/
java arrays are indexed by integers, meaning no java array can hold more than \(2^{31}\) elements
java import best practices are basically cargo cult programming --- https://youtu.be/FyCYva9DhsI?t=1673
also see https://en.m.wikipedia.org/wiki/Criticism_of_Java
overriding equals
see polymorphism
overriding Object.equals in java should ideally follow the pattern below --- ITI1121 Introduction to Computing II
public class Account {
private int id;
private String name;
// ...
public boolean equals(Object o) {
if (o == null) return false;
if (getClass() != o.getClass()) return false;
// if (!(o instanceof Account)) return false; // alternative
Account other = (Account) o;
if (id != other.id) return false;
if (name == null && other.name != null) return false;
if (name != null && !name.equals(other.name)) return false;
return true;
}
}
== on references
using the == operator on java › references compares memory locations, which can be influenced by compiler optimization
example
public class References { public static void main(String[] args) { String a = "asdf"; String b = "asdf"; String c = "a" + "sdf"; String first = "a"; String d = first + "sdf"; System.out.println(a == b); // true System.out.println(a == c); // true System.out.println(a == d); // false } }
auto boxing
auto boxing is the automatic conversion from a java › primitive to a java › reference; auto unboxing is the automatic conversion from a java › reference to a java › primitive
example
Integer i = 1; // valid in Java 5 and up Integer i = Integer.valueOf(1); // transforms into this (called boxing) Integer i = new Integer(1); // this syntax is deprecated since Java 9
example
Integer i = 1; i = i + 5; //gets turned into i = Integer.valueOf( i.intValue() + 5 // unboxing and adding to another primitive ); // re-boxing the value again
type "system"
Generic
see generic
java › generics are basically compile-time-checked type casts to java's top ‹type Object, a process known as type erasure --- https://stackoverflow.com/questions/48438160/how-do-java-generic-methods-work-under-the-hood. consequently, collections may not contain java › primitives --- https://stackoverflow.com/questions/4594529/java-collections-why-no-primitive-types
Primitive
java › primitives are stored on the stack
java › primitives are passed by value and can be passed by reference through java › wrappers
examples
byte short int long float double boolean char
Reference
java › reference types are stored on the heap; pointers to java › reference types are stored on the stack
despite java being a managed language, memory leaks can still occur if references to objects are not explicitly deleted
java › references are passed by reference. java › references inherit from Object, which allows them to be used in java › generics. all user-defined classes are java › references
note declaring a java class
class MyClassis shorthand forclass MyClass extents ObjectasObjectis the top ‹type in java
examples
String Integer Object
Wrapper
every java › primitive has a corresponding java › wrapper, which are java › references
example
Integeris a wrapper forint