Интересно, может ли кто-нибудь рассказать мне, как работает приведение? Я понимаю, когда я должен это делать, но не совсем понимаю, как это работает. В примитивных типах данных я разбираюсь частично, но когда дело доходит до приведения объектов, я не понимаю, как это работает.
Как объект с типом Object может быть просто внезапно приведен, скажем, к MyType (просто пример), а затем получить все методы?
Переведено автоматически
Ответ 1
Приведение в Java - это не волшебство, вы сообщаете компилятору, что объект типа A на самом деле относится к более конкретному типу B, и, таким образом, получаете доступ ко всем методам в B, которых у вас не было бы в противном случае. Вы не выполняете никакого волшебства или преобразования при выполнении приведения, вы, по сути, говорите компилятору: "Поверьте мне, я знаю, что делаю, и я могу гарантировать вам, что этот объект в этой строке на самом деле является <Insert приведенным типом here>". Например:
Objecto="str"; Stringstr= (String)o;
Вышесказанное прекрасно, не волшебство, и все в порядке. Объект, хранящийся в o, на самом деле является строкой, и поэтому мы можем привести к строке без каких-либо проблем.
Это может пойти не так двумя способами. Во-первых, если вы выполняете приведение между двумя типами в совершенно разных иерархиях наследования, компилятор поймет, что вы ведете себя глупо, и остановит вас.:
Stringo="str"; Integerstr= (Integer)o; //Compilation fails here
Во-вторых, если они находятся в одной иерархии, но все еще являются недопустимым приведением, то во время выполнения будет выдано ClassCastException:
Numbero=newInteger(5); Doublen= (Double)o; //ClassCastException thrown here
По сути, это означает, что вы нарушили доверие компилятора. Вы сказали ему, что можете гарантировать, что объект имеет определенный тип, но это не так.
Зачем вам нужно приведение? Ну, для начала вам это нужно только при переходе от более общего типа к более конкретному. Например, Integer наследуется от Number, поэтому, если вы хотите сохранить Integer как Number, то это нормально (поскольку все целые числа являются числами.) Однако, если вы хотите пойти другим путем, вам нужно приведение - не все числа являются целыми числами (а также целыми числами, которые у нас есть Double, Float, Byte, Long и т.д.), И даже если в вашем проекте или JDK есть только один подкласс, кто-то может легко создать другой и распространить его, так что у вас нет гарантии, даже если вы думаете, что это единственный очевидный выбор!
Что касается использования для приведения, вы все еще видите необходимость в нем в некоторых библиотеках. До Java-5 это широко использовалось в коллекциях и различных других классах, поскольку все коллекции работали над добавлением объектов и последующим приведением результата, который вы получали обратно из коллекции. Однако с появлением дженериков большая часть использования для приведения исчезла - его заменили дженерики, которые предоставляют гораздо более безопасную альтернативу, без потенциальных ClassCastExceptions (фактически, если вы используете дженерики чисто и они компилируются без предупреждений, у вас есть гарантия, что вы никогда не получите ClassCastException .)
Ответ 2
На самом деле приведение работает не всегда. Если объект не является instanceof классом, к которому вы его приводите, вы получите ClassCastException во время выполнения.
Ответ 3
Предположим, вы хотели привести a String к a File (да, это не имеет никакого смысла), вы не можете привести это напрямую, потому что File класс не является дочерним и не родительским для String класса (и компилятор жалуется).
Но вы могли бы привести свои String к Object, потому что a String - это an Object (Object является родительским). Затем вы могли бы привести этот объект к File, потому что файл - это Object.
Итак, все ваши операции "законны" с точки зрения набора текста во время компиляции, но это не означает, что это будет работать во время выполнения!
Filef= (File)(Object) "Stupid cast";
Компилятор разрешит это, даже если это не имеет смысла, но это приведет к сбою во время выполнения с этим исключением:
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.io.File
Ответ 4
Приведение ссылки будет работать, только если это instanceof этот тип. Вы не можете приводить случайные ссылки. Кроме того, вам нужно прочитать больше на Casting Objects.
например
Stringstring="String";
Objectobject= string; // Perfectly fine since String is an Object
StringnewString= (String)object; // This only works because the `reference` object is pointing to a valid String object.