Ciao allora ho la seguente classe(che di per sè non ha molto,ma è a livello didattico):

codice:
class Vehicle{
private int velocità=100;
private int gradi=90;
private String nomeproprietario;
private static int veicolosuccessivo=10;
private int numerodiogniveicolo=5;
Vehicle veicolo=null;
  Vehicle(){
}
Vehicle(String nomeproprietario){
    this.nomeproprietario=nomeproprietario;
    
}
public int getnumerodiogniveicolo(){
    return numerodiogniveicolo;
}
public int getvelocità(){
    return velocità;
}
public int getgradi(){
    return gradi;
}
public int getveicolosuccessivo(){
    return veicolosuccessivo;
}
public String getnomeproprietario(){
    return nomeproprietario;
}
public void  setveicolosuccessivo(int nuovoveicolo){
    this.veicolosuccessivo=nuovoveicolo;
}
public  void setnomeproprietario(String nuovonome){
    this.nomeproprietario=nuovonome;
}
@Override
public String toString(){
    String s="il nome del proprietario è: "+nomeproprietario;
    if(veicolo!=null){
        s+=" la macchina va a "+velocità+"\n"+veicolo.toString();
    }
    return s;
}
}
poi da main:

codice:
class TestVeicolo{
public static void main(String[] args){
Vehicle v=new Vehicle();
Vehicle v1=new Vehicle("elena");
Vehicle v2=new Vehicle("fabio");
v2.veicolo=v1;
v1.setnomeproprietario("davide");
System.out.println(v1.getnomeproprietario());
System.out.println(v);
System.out.println(v1);
System.out.println(v2);
}
}
Adesso il compilatore mi stampa:
il nome del proprietario è: null
il nome del proprietario è: davide
il nome del proprietario è: fabio la macchina va a 100
il nome del proprietario è: davide

Perchè??
non dovrebbe stamparmi :
davide
il nome del proprietario è: null
il nome del proprietario è: fabio la macchina va a 100
il nome del proprietario è: fabio

Poi perchè su v1.getnomeproprietario() il compilatore invoca direttamente il meto toString?