четверг, 5 марта 2015 г.

Кривая Java

Всё-таки Java - кривой язык. Вот взять пример:

package y;

public class A {
    public final B b = new B();
}

class B {
    public int f() {
        return 0;
    }

}

Т.е. я объявил класс A, в котором есть публичное поле класса B, но B виден только в пакете y.

Теперь если попробовать взять поле b из экземпляра класса A, то начнутся сюрпризы. Такой код успешно компилируется и работает:

package x;

import y.A;

public class Main {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.b); // печатает y.B@15db9742
    }

}

Дальше - веселье. Если позвать у b любой метод, то будет ошибка компиляции:

package x;

import y.A;

public class Main {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.b.f()); // Ошибка: The type B is not visible
    }

}

Причём даже если позвать метод toString(), который точно есть у всех объектов, то всё равно будет ошибка компиляции!

package x;

import y.A;

public class Main {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.b.toString()); // Ошибка: The type B is not visible
    }

}

Но несмотря на это, такой код уже работает:
package x;

import y.A;

public class Main {
    public static void main(String[] args) {
        A a = new A();
        Object b = a.b;
        System.out.println(b.toString()); // печатает y.B@15db9742
    }
}

Короче, пипец, товарищи.