#java #android
package objtransfering; public class ObjTransfering { public static void printEvrth(Object... args) { for (Object it : args) System.out.println(it); } public static void main(String[] args) { printEvrth(new Integer(1), new Double(5.00), new String("end.")); } } Все классы наследуют класс Object. К примеру, обёртка Integer наследует класс Number, а он, в свою очередь, Object. Выходит, у класса Integer есть поля и методы, которых нет у класса Object. Тогда почему принимая объекты типа Object метод System.out.println() различает в них Integer, Double и String? Разве у этих объектов не "отбросилась" та часть, которая отличает их от Object?
Ответы
Ответ 1
В исходном коде видно, что метод println() перегружен и принимает один из множества типов аргументов. Во время исполнения JVM определяет какой именно тип объекта передаётся по ссылке типа Object и вызывает соответствующий метод. При этом ООП обёртки над примитивами типа Integer или Double, да и остальные типы, наследующие Object могут иметь переопределённый метод toString(), коий и будет выведен в консоль. Обычно этот метод выводит имя класса и hashCode объекта. В случае же приведённых вами классов там иной код. Например Integer выводит только число. При этом, конечно же, никакая информация не теряется о конкретном типе объекта присвоенного ссылке. Единственное ограничение - вы не сможете вызвать методы конкретного класса, пока вы его не скастуете к его настоящему типу.Ответ 2
У класса Object есть метод toString() при использовании System.out.println() вызывается этот метод. В свою очередь toString() переопределен в классах Integer, Double и String, и у каждого из них своя реализация этого метода.Ответ 3
Если вы загляните внутрь данных объектов, то обнаружите такой волшебный метод, как toString. Этот метод служит для представления объекта в виде строки. У каждого класса реализация метода своя. К примеру у Integer такой код: public static String toString(int i, int radix) { if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; /* Use the faster version */ if (radix == 10) { return toString(i); } char buf[] = new char[33]; boolean negative = (i < 0); int charPos = 32; if (!negative) { i = -i; } while (i <= -radix) { buf[charPos--] = digits[-(i % radix)]; i = i / radix; } buf[charPos] = digits[-i]; if (negative) { buf[--charPos] = '-'; } return new String(buf, charPos, (33 - charPos)); } Как видим метод возвращает строку (грубо говоря) return new String(buf, charPos, (33 - charPos)); У других классов всё тоже самое. В любом классе можно тоже его реализовать. Можно написать там все что угодно, хоть return "hello, world"; А этот самый System.out.println неявно вызывает этот самый метод toString у объекта Добавлю пожалуй пример: import java.util.*; import java.lang.*; import java.io.*; /* Name of the class has to be "Main" only if the class is public. */ class Ideone { public static void main (String[] args) throws java.lang.Exception { Test test = new Test(); System.out.print(test); } public static class Test { public String toString() { return "Hello, world!"; } } } https://ideone.com/jLvbDM
Комментариев нет:
Отправить комментарий