Путаница в наследовании - значение "this" при печати в конструкторе

У меня есть следующий код.

class Test {
    int i = 0;

    Test() {
        System.out.println(this);
        System.out.println(this.i);
    }

}

public class Demo extends Test {
    int i = 10;

    Demo() {
        super();
        System.out.println("calling super");
        System.out.println(this);
        System.out.println(this.i);    
    }

    public static void main(String[] args) throws IOException {    
        Demo d = new Demo();    
    }
}

O/P : [email protected]
0
calling super
[email protected]
10

Когда я запускаю программу и печатаю значение "this", как в конструкторе суперкласса, так и в конструкторе дочернего класса, значение этого (адресное местоположение) отображается как childClassName @someValue.. Мой вопрос: почему я не получаю значение теста, т.е. Test @someVal (класс Super), когда я печатаю значение "this" в суперклассе. ASAIK, класс Super также будет иметь место/место в памяти, поэтому, почему я не получая Test @someValue в первом SOP...

PS: Я знаю, что переменные ссылаются на ссылочный тип (LHS), и методы вызываются на основе типа объекта (RHS)..

Ответ 1

Когда я запускаю программу и печатаю значение "this", как в конструкторе суперкласса, так и в конструкторе дочернего класса, значение этого (адресное местоположение)...

Вывод System.out.println(this) по умолчанию Object#toString - не адрес экземпляра в памяти. Это просто имя класса и хэш-код экземпляра, не более того. Из документация:

Метод toString для класса Object возвращает строку, состоящую из имени класса, объектом которого является экземпляр объекта, символа at-sign `@'и шестизначного шестнадцатеричного представления хеш-кода объекта, Другими словами, этот метод возвращает строку, равную значению:

getClass().getName() + '@' + Integer.toHexString(hashCode())

Это правда, что hashCode документация говорит

Обычно это выполняется путем преобразования внутреннего адреса объекта в целое число...

но он также говорит

... но этот метод реализации не требуется языком программирования Java TM.

... и, конечно же, JVM может свободно перемещать экземпляры в памяти по мере необходимости, но не имеет права изменять hashCode.


... почему я не получил значение Test i.e, Test @someVal (Super class), когда я печатаю значение "this" в суперклассе.

Существует один экземпляр. Этот экземпляр относится к подклассу. Когда вы выполняете System.out.println(this), неважно, выполняете ли вы это в базовом классе или подклассе, это все тот же экземпляр объекта, который вы используете. У этого объекта есть функции, которые он получает из подкласса, а также функции, которые он наследует от суперкласса, но не существует двух отдельных экземпляров; есть один экземпляр с комбинированным набором функций. super не является ссылкой на объект, хотя он немного похож на него; это синтаксический механизм для конкретного запроса компилятору использовать функцию, которую экземпляр наследует от суперкласса, а не эквивалентную функцию экземпляра (в случае, если они разные).

Ответ 2

Демо - это композиция из 3 классов: сама, Test и Object. Но экземпляр Demo - это один объект, в памяти он состоит из полей его суперкласса + его собственных полей: Test.i + Demo.i (у объекта нет полей).