Java vs Python
runestone.academy/ns/books/published/java4python/
Why should you know something about Java?
▪ Java is an example of a statically typed object oriented language
(like C and C++) opposed to Python’s being dynamically typed
▪ One of the most widespread used programming languages
▪ Used in other courses at the Department of Computer Science
Java history
▪ Java 1.0 released 1995 by Sun Microsystems
(acquired by Oracle 2010) PyPy is adopting the same
ideas to Python
▪ ”Write Once, Run Anywhere” (Just-in-Time compilation)
▪ 1999 improved performance by the Java HotSpot Performance Engine
▪ Current version Java 20 (released March 2023)
▪ Java compiler generates Java bytecode that is executed on a
Java virtual machine (JVM)
Installing Java
▪ To compile Java programs into bytecode you
need a compiler, e.g. from Java SE Development
Kit (JDK):
www.oracle.com/java/technologies/downloads/
(you might need to add the JDK directory to your
PATH, e.g. C:\Program Files\Java\jdk-18.0.1.1\bin)
▪ To only run compiled Java programs:
java.com/download
(If you use JDK, you should not download this)
Java IDE
▪ Many available, some popular:
Visual Studie Code, IntelliJ IDEA, Eclipse, and NetBeans
▪ An IDE for beginners: BlueJ
Compiling and running a Java program
HelloWorld.java
public class HelloWorld {
public static void main( String[] args ) {
System.out.println( "Hello World!" );
HelloWorld.java }
}
Java compiler
(javac)
HelloWorld.class
Java Virtual
Machine
(java)
execution
Java : main
▪ name.java must be equal to the public class name
▪ A class can only be excuted using java name (without .class) if the
class has a class method main with signature
public static void main(String[] args)
▪ (main is inherited from C and C++ sharing a lot of syntax with Java)
▪ Java convention is that class names should use CamelCase
PrintArguments.java shell
public class PrintArguments { > java PrintArguments x y z
public static void main( String[] args ) { |x
for (int i=0; i<args.length; i++) |y
System.out.println( args[i] ); |z
}
}
a static method in
a class is a class method
(exists without creating objects) method name
there can be several classes type of return value class name containing main
in a file – but only one class (void = no return value) must have same name as file
should be public and have
same name as file type of argument,
PrintArguments.java array of String values
public class PrintArguments {
the main method must
public static void main( String[] args ) {
be public to be visible
for (int i=0; i<args.length; i++)
outside class name of argument
System.out.println( args[i] );
}
}
For-loop equivalent to
int i=0
declare new int variable the print statement is found while (i<args.length) {
code
locally inside for-loop in the System class
i++;
java arrays are indexed from }
0 to args.length – 1 i += 1
and the length of an array
object is fixed once created
Argument list also exists in Python...
PrintArguments.py
import sys
print(sys.argv)
shell
> python PrintArguments.py a b 42
| ['PrintArguments.py', 'a', 'b', '42']
Primitive.java
/**
* A Java docstring to be processed using 'javadoc'
*/
// comment until end-of-line
public class Primitive {
public static void main( String[] args ) {
int x; // type of variable must be declared before used
x = 1; // remember ';' after each statement
int y=2; // indentation does not matter
int a=3, b=4; // multiple declarations and initialization
System.out.println(x + y + a + b);
int[] v={1, 2, 42, 3}; // array of four int
System.out.println(v[2]); // prints 42, arrays 0-indexed
/* multi-line comment
that continues until here */
v = new int[3]; // new array of size three, containing zeros
System.out.println(v[2]); // prints 0
if (x == y) { // if-syntax '(' and ')' mandatory
a = 1;
b = 2;
} else { // use '{' and '}' to create block of statements
a = 4; b = 3; // two statements on one line
}
}}
Why state types – Python works without...
▪ Just enforcing a different programming style (also C and C++)
▪ Helps users to avoid mixing up values of different types
▪ (Some) type errors can be TypeError.java
public class TypeError {
caught at compile time public static void main( String[] args ) {
int x = 3;
▪ More efficient code execution String y = "abc";
System.out.println(x / y);
}
type_error.py
}
x = 3
shell
y = 'abc'
print('program running...') > javac TypeError.java
print(x / y) | javac TypeError.java
| TypeError.java:5: error: bad operand types for
Python shell
binary operator '/'
| program running... | System.out.println(x / y);
... | ^
| ----> 4 print(x / y) | first type: int
| TypeError: unsupported operand type(s) for | second type: String
/: 'int' and 'str' | 1 error
Basic Java types BigIntegerTest.java
import java.math.*; // import everything
// import java.math.BigInteger; // alternativ
public class BigIntegerTest {
Type Values public static void main( String[] args ) {
boolean true or false BigInteger x = new BigInteger("2");
while (true) {
byte 8 bit integer // BigIntegers are immutable
char character (16-bit UTF) x = x.multiply(x);
// java.math.BigInteger.toString()
short 16 bit integer System.out.println(x);
}
int 32 bit integer }
long 64 bit integer }
shell
float 32 bit floating bout
| 4
double 64 bit floating point | 16
class BigInteger arbitrary precision integers | 256
| 65536
class String strings | 4294967296
| 18446744073709551616
| 340282366920938463463374607431768211456
| ...
ConcatenateArrayLists.java
import java.util.*; // java.util contains ArrayList
Java arrays public class ConcatenateArrayList {
public static void main( String[] args ) {
// ArrayList is a generic container
▪ The size of a builtin Java array can not ArrayList<String> a = new ArrayList<String>();
be modified when first created.
If you need a bigger array you have to ArrayList<String> b = new ArrayList<String>();
instantiate a new array. ArrayList<String> c = new ArrayList<String>();
a.add("A1"); // in Python .append
a.add("A2");
▪ Or better use a standard collection b.add("B1");
class like ArrayList
c.addAll(a); // in Python .extend
c.addAll(b);
▪ ArrayList is a generic class (type of for (String e : c) { // foreach over iterator
content is given by <element type>; System.out.println(e);
generics available since Java 5, 2004)
}
}
▪ The for-each loop was introduced in }
Java 5 shell
| A1
| A2
| B1
Tired of writing all these types...
▪ In Java 7 (2011) the “diamond operator” <> was introduced for type
inference for generic instance creation to reduce verbosity
▪ In Java 10 (2018) the var keyword was introduced to type infer variables
ArrayListTest.java
import java.util.*; // java.util contains ArrayList
public class ArrayListTest {
public static void main( String[] args ) {
// ArrayList is a generic container
ArrayList<String> a = new ArrayList<String>(); // Full types
List<String> b = new ArrayList<String>(); // ArrayList is subclass of class List
ArrayList<String> c = new ArrayList<>(); // <> uses type inference
List<String> d = new ArrayList<>(); // <> and ArrayList subclass of List
var e = new ArrayList<String>(); // use var to infer type of variable
var v = Math.floor(1.5); // not obvious what type v is (double)
}}
Functions.java
public class Functions {
Function arguments private static int f(int x) {
return x * x;
}
private static int f(int x, int y) {
return x * y;
▪ Must declare the number of }
arguments and their types, and private static String f(String a, String b) {
return a + b; // string concatenation
the return type }
▪ The argument types are part of public static void main( String[] args ) {
System.out.println(f(7));
the signature of the function System.out.println(f(3, 4));
System.out.println(f("abc", "def"));
▪ Several functions can have the }
functions.py
same name, but different type }
def f(x, y=None):
signatures shell
if y == None:
| 49 y = x
| 12 if type(x) is int:
| abcdef return x * y
▪ Python keyword arguments, else:
return x + y
* and ** do not exist in Java print(f(7), f(3, 4), f('abc', 'def'))
AClass.java
class Rectangle {
Class private int width, height; // declare attributes
// constructor, class name, no return type
public Rectangle(int width, int height) {
this.width = width;
▪ Constructor = method with this.height = height;
name equal to class name }
(no return type) public Rectangle(int side) {
width = side; // same as this.width = side
▪ this = referes to current height = side;
object (Python “self”) }
▪ Use private / public public int area() {
return width * height;
on attributes / methods to }
give access outside class }
public class AClass {
▪ Use new name(arguments) public static void main( String[] args ) {
to create new objects Rectangle r = new Rectangle(6, 7);
System.out.println(r.area());
}
▪ There can be multiple }
shell
constructors, but with
distinct type signatures | 42
Inheritance.java
class BasicRectangle {
Inheritance // protected allows subclass to access attributes
protected int width, height;
public BasicRectangle(int width, int height) {
this.width = width; this.height = height;
▪ Java supports single }
}
inheritance using class Rectangle extends BasicRectangle {
extends public Rectangle(int width, int height) {
// call constructor of super class
▪ Attributes and methods super(width, height);
}
that should be public int area() {
accessible in a subclass }
return width * height;
must be declared }
protected (or public) public class Inheritance {
public static void main( String[] args ) {
▪ Constructors are not Rectangle r = new Rectangle(6, 7);
System.out.println(r.area());
inherited but can be }
called using super }
shell
| 42
Generic class GenericPair.java
class Pair<element> {
private element x, y;
▪ Class that is public Pair(element x, element y) {
parameterized by one this.x = x; this.y = y;
}
or more types element first() { return x; }
(comma separated) element second() { return y; }
}
▪ Primitive types cannot
public class GenericPair {
be type parameters public static void main( String[] args ) {
var p = new Pair<Integer>(6, 7);
▪ Instead use wrappers, System.out.println(p.first() * p.second());
like Integer for int }
}
shell
| 42
Interface RectangleInterface.java
interface Shape {
▪ Java does not support public int area(); // method declaration
}
multiple inheritance like
class Rectangle implements Shape {
Python private int width, height;
▪ But a class can implement // constructor, class name, no return type
public Rectangle(int width, int height) {
an arbitrary number of this.width = width; this.height = height;
interfaces }
▪ An interface specifices a set public int area() {
return width * height;
of attributes and methods a }
class must have }
public class RectangleInterface {
▪ The type of a variable can public static void main( String[] args ) {
be an interface, and the Shape r = new Rectangle(6, 7);
System.out.println(r.area());
variable can hold any object }
where the class is stated to }
implement the interface
AbstractRectangle.java
Abstract classes abstract class Shape {
abstract public int circumference();
abstract public int area();
public double fatness() {
// convert int from area() to double before /
▪ Abstract class = class that cannot return (double)area() / circumference();
be instantiated, labeled }
}
abstract class Rectangle extends Shape {
private int width, height;
// constructor, class name, no return type
public Rectangle(int width, int height) {
▪ Abstract method = method this.width = width; this.height = height;
declared without definition, }
public int area() {
labeled abstract, return width * height;
must be in abstract class }
public int circumference() {
return 2 * (width + height);
}
}
▪ An abstract class can be
public class AbstractRectangle {
extended to a non-abstract class public static void main( String[] args ) {
by providing the missing method Shape r = new Rectangle(6, 7);
System.out.println(r.fatness());
definitions }
}
Default methods DefaultInterface.java
interface Shape {
public int circumference();
in interfaces public int area();
default public double fatness() {
// convert int from area() to double before /
return (double)area() / circumference();
▪ Before Java 8 all methods in an }
}
interface were abstract (no definition) class Rectangle implements Shape {
private int width, height;
// constructor, class name, no return type
public Rectangle(int width, int height) {
▪ Since Java 8 interfaces can have this.width = width; this.height = height;
default methods with definition }
public int area() {
return width * height;
}
public int circumference() {
▪ The distinction between abstract return 2 * (width + height);
classes and interfaces gets blurred }
}
• a class can only extend one abstract class public class DefaultRectangle {
• a class can implement more interfaces public static void main( String[] args ) {
Shape r = new Rectangle(6, 7);
⇒ multiple “inheritance” is possible in Java System.out.println(r.fatness());
}
}
Multiple MultipleInheritance.java
interface A {
Inheritance }
default public void sayA() { System.out.println("say A"); }
default public void sayHi() { System.out.println("A say's Hi"); }
interface B {
▪ Class C implements both default public void sayB() { System.out.println("say B"); }
interfaces A and B default public void sayHi() { System.out.println("B say's Hi"); }
}
▪ Inherits default methods class C implements A, B {
sayA and sayB @Override // (optional) requests compiler to
// check if sayHi exists in supertype
public void sayHi() {
▪ Cannot inherit sayHi, System.out.println("C say's Hi");
since in both A and B. (new A(){}).sayHi(); // instantiate an anonymous class
}
Must be overriden in C public void test() {
▪ Can use @override to sayA();
sayB();
enforce compiler to check if sayHi();
} Shell output
method exists in super class } say A
▪ new A(){} creates an public class MultipleInheritance {
public static void main( String[] args ) {
say B
C say's Hi
instance of an anonymous new C().test(); A say's Hi
}
class (extending or }
implementing A)
Lambda expression
▪ Lambda expressions are possible since Java 8
▪ Syntax : argument -> expression
LambdaPrinting.java
import java.util.*; // ArrayList
public class LambdaPrinting {
public static void main(String[] args) {
var elements = new ArrayList<Integer>();
for (int i = 1; i <= 3; i++)
elements.add(i);
elements.forEach(e -> System.out.println(e));
};
}
LambdaPrinting.java
1
2
3