gianluca.aguzzi@unibo.it
angelo.filaseta@unibo.it
Questo materiale è ampiamente basato su quello realizzato dai Prof. Mirko Viroli e Roberto Casadei, che ringrazio.
Ogni errore riscontratovi è esclusiva responsabilità degli autori di questo documento.
Everything is an object
// Creo un oggetto String, e lo assegno al nome s
// questo oggetto stringa rappresenta la sequenza vuota di caratteri
String s = new String();
// In generale si crea un oggetto con l'operatore "new"
// Accetta 0,1 o più argomenti, a seconda del tipo: valori primitivi (numeri), string literals, o oggetti
String s2 = new String("prova");
Point2D p = new Point2D(10.5, 20.3);
Object o = new Object();
String s = new String("prova");
// Un caso ad-hoc di Java, equivalente a:
// String s2 = new String("casa");
String s2 = "casa";
// Definisco il nome s4, ma non lo inizializzo
String s4;
// ora assegno s4, da qui in poi è utilizzabile
s4 = "auto";
// Il nome i è assegnato al valore primitivo 5
int i = 5;
Assomigliano molto a quelli del C, ma hanno dimensioni fissate
Type name | Size (bits) | Minimum | Maximum |
---|---|---|---|
boolean | – | – | – |
char | 16 | \u0000 |
\uFFFF |
byte | 8 | $-128$ | $128$ |
short | 16 | $-2^{15}$ | $2^{15}-1$ |
int | 32 | $-2^{31}$ | $2^{31}-1$ |
long | 64 | $-2^{63}$ | $2^{63}-1$ |
float | 32 | IEEE754 | IEEE754 |
double | 64 | IEEE754 | IEEE754 |
void | – | – | – |
boolean
possono valere true
o false
BigDecimal
, BigInteger
) gestiscono numeri di dimensione/precisione arbitraria// assegnamenti con tipi primitivi
int i = 5;
double d = 145e-20;
boolean b = true;
// assegnamenti con classi
Object o = new Object();
String s = "altra stringa";
Point2D p = new Point2D(10.4, 20.3);
// assegnamento da/a variabile
int other = i;
Point2D q = p;
// assegnamento a null
Object on = null;
var
: local variable type inference (Java 10+)// assegnamenti con tipi primitivi
var i = 5;
var d = 145e-20;
var b = true;
// assegnamenti con classi
var o = new Object();
var s = "altra stringa";
var p = new Point2D(10.4, 20.3);
// assegnamento da/a variabile
var other = i;
var q = p;
// assegnamenti con tipi primitivi: contengono VALORI!
var i = 5;
var d = 145e-20;
var b = true;
// assegnamenti con classi contengono RIFERIMENTI!
var o = new Object();
var s = "altra stringa";
var p = new Point2D(10.4, 20.3);
var other = i; // VALORE!
var q = p; // Stesso RIFERIMENTO!
Object on = null; // Riferimento speciale al valore null
È anche il nome del tipo
Campi (fields)
Metodi (methods)
class A { // A è il nome della classe
... // qui si riporta il suo contenuto
}
class AltroEsempioDiClasse { // Nota il PascalCase
...
}
// codice cliente
A obj1 = new A(); // creo un oggetto di A, con nome obj1
A obj2 = new A(); // creo un altro oggetto di A
AltroEsempioDiClasse obj3 = new AltroEsempioDiClasse();
A obj4; // variabile obj4 non inizializzata
obj4 = new A(); // ok
obj4 = new AltroEsempioDiClasse(); // NO!! Errore semantico
var
!0
per i tipi numericifalse
per i booleaninull
per le classiobject.field
class A {
int i;
int j = 2;
Object o;
}
A obj = new A();
int a = obj.i; // a varrà 0
int b = obj.j; // b varrà 2
obj.i = 10; // modifico lo stato di obj
int d = obj.i; // d varrà 10
obj.o = new Object(); // riassegno obj.o
A obj2 = new A();
obj.i = obj2.i; // quanto varrà ora obj.i?
class Point3D {
double x; // Nota, l'ordine dei campi è irrilevante
double y;
double z;
}
Point3D a = new Point3D(); // Creo due punti, di nome a e b
Point3D b = new Point3D();
a.x = 10.0; // Imposto lo stato di a
a.y = 20.0;
a.z = 30.0;
b.x = a.x * 2; // Imposto lo stato di b
b.y = a.y * 2; // .. a partire da quello di a
b.z = a.z * 2;
int mod2a = a.x * a.x + a.y * a.y + a.z * a.z;
int mod2b = b.x * b.x + b.y * b.y + b.z * b.z;
boolean aGreater = (mod2a > mod2b); // false
object.method(arguments)
object
object
è chiamato il receiver del messaggio (o dell’invocazione)class Adder {
int total;
void add(int a){ // input "int a"
total = total + a;
}
int getValue(){ // intestazione funzione
return total; // corpo funzione
}
}
Adder adder = new Adder();
int v = adder.total; // vale 0
adder.add(10); // modifico adder
adder.add(20); // modifico adder
int v2 = adder.total; // vale 30
int v3 = adder.getValue(); // vale 30
this
this
class Adder {
int total;
void add(int a){ // input "int a"
this.total = this.total + a;
}
int getValue(){ // intestazione funzione
return this.total; // corpo funzione
}
}
class Point3D { // Class declaration
double x; // 3 campi
double y;
double z;
void build(double a, double b, double c){
this.x = a;
this.y = b;
this.z = c;
}
double getNormSquared(){
return this.x * this.x + this.y * this.y + this.z * this.z;
}
boolean equal(Point3D q){ // true if two points are equal
return this.x == q.x && this.y == q.y && this.z == q.z;
}
}
// codice cliente
Point3D p = new Point3D(); // Create a new point p
p.build(10.0, 20.0, 30.0); // set up the point
Point3D q = new Point3D(); // create a new point q
q.build(10.0, 20.0, 31.0); // set up point q
double m2 = p.getNormSquared(); // get the squared norm of m2
boolean samePoint = p.equal(q); // chiedo a p se è uguale a q
main
main
è un punto d’accesso di un programmamain
Il main
deve avere la seguente dichiarazione:
public static void main(String[] args)
tre concetti che spiegheremo in dettaglio nel prosieguo:
public
indica il fatto che debba essere visibile “a tutti”static
indica che non è un metodo dell’oggetto, ma della classeString[]
indica il tipo “array di stringhe”name1.name2.name3
java.lang
, java.util
, java.io
java.base
, java.desktop
, java.sql
, java.xml
java.base
contiene i package principali che useremojava.*
)import
, da usare all’inizio del sorgente
import java.util.Date;
import java.util.*;
import java.lang.*;
java.util.Date now = new java.util.Date();
java.util.Date
System.out.println
System
è una classe nel package java.lang
out
è un suo campo che rappresenta lo standard output
static
o, ossia uguale per ogni istanza di System
println
è un metodo che accetta una String
a e la stampa+
concatena stringhe a valori// This class should be into a file named Hello.java
class Hello {
public static void main(String[] args){
System.out.println("Hello World!");
}
}
Hello.java
javac Hello.java
Hello.class
java Hello
Hello
, e ne esegue il main
Hello
, non il file Hello.class
import java.util.Date;
import java.util.Random;
// java.lang.System non va importata
class PrintingObjects{
public static void main(String[] args){
// Date
Date d = new Date();
System.out.println("Today: " + d);
System.out.println("Milliseconds since 1/1/1970: " + d.getTime());
// Random number generator
Random r = new Random();
System.out.println("Random number: " + r.nextInt());
System.out.println("Another random: " + r.nextInt());
System.out.println("A random in 0..99: " + r.nextInt(100));
// System properties
String javaVersion = System.getProperty("java.version");
String osname = System.getProperty("os.name");
String usrdir = System.getProperty("user.dir");
System.out.println("Running Java " + javaVersion + " in " + osname + " from " + usrdir);
}
}
class A {
int i;
void print(){
System.out.println("Sono un oggetto della classe A");
System.out.println("Il mio valore di i è: " + this.i);
}
}
class Print {
public static void main(String[] args) {
A obj = new A();
obj.i = 12;
obj.print();
}
}
main
:
java Print
class Point3D {
double x;
double y;
double z;
void build(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
double getNormSquared() {
return this.x * this.x + this.y * this.y + this.z * this.z;
}
boolean equal(Point3D other) {
return this.x == other.x && this.y == other.y && this.z == other.z;
}
}
class UsePoint3D{
public static void main(String[] args) {
Point3D p = new Point3D();
p.build(10.0, 20.0, 30.0);
Point3D q = new Point3D();
q.build(10.0, 20.0, 31.0);
System.out.println("p's squared norm: " + p.getNormSquared());
System.out.println("Are p and q the same point? " + p.equal(q));
}
}
UsePoint3D.java
serve la classe Point3D
, il file Point3D.java
va compilato primajavac UsePoint3D.java Point3D.java
javac *.java
main
java UsePoint3D