Почему пользовательские дети Number не наследуют автобокс? - PullRequest
4 голосов
/ 21 апреля 2019

Я понимаю, что пользовательский автобокс не поддерживается в Java, но я также заметил, что могу расширить объект Number. Так как сам объект числа, кажется, разрешает автобокс примитивов, это работает:

Number val = 5; //This compiles no problem

Если, однако, я расширяю Number и пытаюсь использовать дочерний тип, программа не может скомпилировать:

MyNumber num = 5; //This does not compile :(

Я понимаю, что это не разрешено и, вероятно, никогда не будет разрешено в Java, но какой механизм вызывает этот разрыв? Обрабатывается ли функциональность обертки Number где-то за пределами самого класса, или, возможно, существует какая-то особая инкапсуляция, предотвращающая создание пользовательской обертки?

Ответы [ 2 ]

5 голосов
/ 21 апреля 2019

5 - это целочисленный литерал. Таким образом, его тип int.

Так как он назначен переменной ссылочного типа (Number), он автоматически упаковывается в тип оболочки: java.lang.Integer. Затем это целое число присваивается переменной, и это действительно, поскольку Integer является числом: класс Integer расширяет класс Number.

Наоборот, Integer не расширяет MyNumber. Таким образом, присвоение Integer переменной типа MyNumber недопустимо: Integer не является MyNumber.

Так что это не имеет большого отношения к распаковке. Это связано с тем, что вы не можете сделать

MyNumber n = someInteger;

точно так же, как ты не можешь

MyNumber n = someString;

: типы просто не совместимы.

2 голосов
/ 21 апреля 2019

Автобокс - это просто оптимизация компилятора.

Фактический скомпилированный код оператора Integer i= 5; равен Integer i = Integer.valueOf(5);

, который не будет работать на пользовательских подклассах Number, так каккомпилятор не знает о них.Вы можете отменить код, используя свою IDE, или использовать javap, и убедитесь сами.

...