Java i this

0

O co chodzi w kodzie poniżej

public class MyThisTest {
	private int a;
	
	public MyThisTest() {
		this(42); //zainicjowanie zmiennej a wartościa 42???
	}
	public MyThisTest(int a) {
		this.a = a; //przypisanie zmiennej po lewej stronie wartości 42???
	}
	public void frobnicate() {
		int a = 1;
		
		System.out.println(a);
		System.out.println(this.a);
		System.out.println(this);
	}
}

To this trochę ciężkie do zrozumienia, czy moje spostrzeżenia są prawidłowe?? Bo

this.a = a;

nic nam nie daje jak przekażemy przy inicjowaniu klasy konstruktorowi parametry...

0

Podczas wywołania domyślnego konstruktora MyThisTest() wywołuje on sobie inny konstruktor MyThisTest(int a) a jako parametr a przekazuje wartość 42. this służy tutaj właśnie do wywołania innego konstruktora z tej samej klasy.

2

Java wspiera coś takiego jak method overloading. Polega to na tym, że możesz zadeklarować sobie nieskończoną ilość metod o tej samej nazwie tak długo, jak różnią się one parametrami. Java podczas wywołania wybierze sobie tą najbardziej pasującą.

Konstruktor to też jakby nie patrzeć metoda. Ty akurat masz dwa konstruktory.

MyThisTest t1 = new MyThisTest(); // zostanie wywołany pierwszy konstruktor, bezargumentowy public MyThisTest()
MyThisTest t2 = new MyThisTest(12); // zostanie wywołany drugi konstruktor public MyThisTest(int a)

W Javie z wnętrza jednego konstruktora możesz wywołać inny używając this(). Zasada działania jest taka jak wyżej, w zależności od przekazanych argumentów Java wybierze najbardziej pasujący konstruktor.

Skoro to już wiemy, to co się tutaj dzieje?

MyThisTest t1 = new MyThisTest();
// 1. zostanie wywołany bezargumentowy konstruktor public MyThisTest()
// 2. z wnętrza tego konsturktora manualnie wywołujesz inny robiąc this(42);
// 3. typ (42) argumentu pasuje do konstruktora  public MyThisTest(int a); więc on zostanie wywołany i ustawi wartość a = 42;

// W Twoim przypadku można powiedzieć, że to wywołanie:
MyThisTest t1 = new MyThisTest();
// robi to samo co to:
MyThisTest t1 = new MyThisTest(42);

Selection_025.png

Fiddle

class Main {
    public static void main(String[] args) {
        Triangle t1 = new Triangle(10);
        System.out.println(t1 + "\n\n");
        Triangle t2 = new Triangle(10, 5);
        System.out.println(t2);
    }
}

class Triangle {
    private double base;

    private double height;

    public Triangle(double base) {
        this(base, base * Math.sqrt(3) / 2.0);
        System.out.println("Hello z Triangle(double base)");
    }

    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
        System.out.println("Hello z Triangle(double base, double height)");
    }
    
    public String toString() {
        return "Base: " + base + " Height: " + height;
    }
}
0

Odnośnie komentarzy
this(42); //zainicjowanie zmiennej a wartościa 42??? -> woła drugi konstruktor z wartością 42 dzięki czemu nie masz w domyślnym konstruktorze przupisania do pola a
this.a = a; //przypisanie zmiennej po lewej stronie wartości 42??? this.a - pole klasy, a - zmienna tymczasowa, to jest dużo czytelniejsze jakbyś miał a = a ( pytanie które to które, aczkolwiek z tego co wiem legalne ).
oczywiście o ile dobrze zrozumiałem Twoje pytanie / spostrzeżenie tutaj bardziej chodzi o czytelność ( swoją drogą kompilator i tak traktuje a w frobnicate jako this.a)

1

jak używasz Eclipse to przytrzymaj CTRL i naciśnij lewym przyciskiem myszy na np. **this(42) **lub this.a to wtedy zobaczysz do czego sie odwoluje i może łatwiej ci będzie zrozumieć o co chodzi z tym magicznym this w konstruktorach i nie tylko

0
public class MyThisTest {
	private int a;
	
	public MyThisTest() {
		this(42); //wywołanie kostruktora z parametrem
	}
	public MyThisTest(int a) {
		this.a = a; //przypisanie parametru a do pola o tej samej nazwie
	}
	public void frobnicate() {
		int a = 1;
		
		System.out.println(a);
		System.out.println(this.a);
		System.out.println(this);
	}
	public String toString() {
		return "A wynosi: " + a;
	}
}

Dobra to zadam jeszcze jedno pytanie na jakiej zasadzie w ostatnim println z frobnicate przez this jest wywoływana metoda toString

0

Wystarczy przeczytać kod źródłowy metody println. Wygląda on tak:

   public void println(Object x) {
       String s = String.valueOf(x);
       synchronized (this) {
           print(s);
           newLine();
       }
   }

Najważniejsze jest tutaj wywołanie valueOf. Jego implementacja wyglada tak:

   public static String valueOf(Object obj) {
       return (obj == null) ? "null" : obj.toString();
   }

Ponieważ przekazujesz obiekt (this) to sterowanie trafia do tej metody i w tym miejscu już jak na tacy widać że jest wywoływana metoda toString.

Trochę magii, ale dzięki temu nie musisz za każdym razem sam wywoływać toString, bo Java zrobi to za Ciebie :)

0

Dzięki za odpowiedź. To jeszcze dopytam gdzie znaleźć kody źródłowe funkcji. Mam w eclipse Java System Library, ale szukanie w tym to tragedia.

0

W katalogu ...JDKxxx jest plik `src.zip'

0

Możesz zainstalować jedyne i najlepsze IDE, którym Intellij Community Edition (CE jest darmowe). Tam wystarczy, że klikniesz z ctrl na nazwę metody i przeniesie cie do jej źródła (w sumie to możesz klikać na co tam chcesz, klasę, metodę, zmienną...)

1 użytkowników online, w tym zalogowanych: 0, gości: 1