Интересно, может ли кто-нибудь сказать мне, как работает кастинг? Я понимаю, когда мне следует это сделать, но не совсем понимаю, как это работает. Я частично разбираюсь в примитивных типах данных, но когда дело доходит до приведения объектов, я не понимаю, как это работает.
Как можно внезапно привести объект с типом Object к, скажем, MyType
(просто пример), а затем получить все методы?
Ответы:
Приведение в Java - это не волшебство, это вы сообщаете компилятору, что объект типа A на самом деле имеет более конкретный тип B, и таким образом получаете доступ ко всем методам на B, которых у вас не было бы иначе. Вы не выполняете никаких магических действий или преобразований при выполнении кастинга, вы, по сути, говорите компилятору: «поверьте мне, я знаю, что делаю, и я могу гарантировать вам, что этот объект в этой строке на самом деле является <Insert cast введите здесь>. " Например:
Object o = "str"; String str = (String)o;
Вышесказанное нормально, не волшебство и все хорошо. Объект, хранящийся в o, на самом деле является строкой, и поэтому мы можем без проблем преобразовать ее в строку.
Есть два пути, по которым это может пойти не так. Во-первых, если вы выполняете приведение между двумя типами в совершенно разных иерархиях наследования, компилятор поймет, что вы ведете себя глупо, и остановит вас:
String o = "str"; Integer str = (Integer)o; //Compilation fails here
Во-вторых, если они находятся в той же иерархии, но по-прежнему имеют недопустимое приведение, тогда во время выполнения
ClassCastException
будет брошено:Number o = new Integer(5); Double n = (Double)o; //ClassCastException thrown here
По сути, это означает, что вы нарушили доверие компилятора. Вы сказали, что можете гарантировать, что объект относится к определенному типу, но это не так.
Зачем нужен кастинг? Что ж, для начала вам это понадобится только при переходе от более общего типа к более конкретному. Например,
Integer
наследуется отNumber
, поэтому, если вы хотите сохранитьInteger
как a,Number
тогда это нормально (поскольку все целые числа являются числами). Однако, если вы хотите пойти другим путем, вам потребуется приведение - не все числа являются целыми числами (также как целое число мы имеемDouble
,Float
,Byte
,Long
и т.д.) и даже если есть только один подкласс в вашем проекте или JDK, кто - то может легко создать еще и распространять это, так что вы не имеете никакой гарантии , даже если вы думаете , что это единственный, очевидный выбор !Что касается использования приведения, вы все еще видите необходимость в нем в некоторых библиотеках. До Java-5 он активно использовался в коллекциях и различных других классах, поскольку все коллекции работали над добавлением объектов и последующим приведением результата, который вы получили обратно из коллекции. Однако с появлением дженериков большая часть использования приведения типов исчезла - они были заменены дженериками, которые обеспечивают гораздо более безопасную альтернативу, без потенциала для ClassCastExceptions (фактически, если вы используете дженерики чисто и он компилируется без предупреждений, у вас есть гарантия, что вы никогда не получите ClassCastException.)
источник
Double.valueOf(gpsLastLoc.getLatitude()).getClass().getSimpleName()
. В любом случае вам никогда не нужно динамически получать класс примитива, поскольку, еслиgetLatitude()
возвращается двойной примитив, вы всегда знаете, что он будет повышаться доDouble
объекта.На самом деле кастинг не всегда работает. Если объект не является
instanceof
классом, к которому вы его приводите, вы получитеClassCastException
во время выполнения.источник
Предположим, вы хотите преобразовать a
String
в aFile
(да, это не имеет никакого смысла), вы не можете преобразовать его напрямую, потому чтоFile
класс не является дочерним и не родительским дляString
класса (и компилятор жалуется).Но вы можете преобразовать свой
String
вObject
, потому что aString
являетсяObject
(Object
родительским). Затем вы можете преобразовать этот объект в объектFile
, потому что файл является файломObject
.Таким образом, все ваши операции являются «законными» с точки зрения типизации во время компиляции, но это не означает, что они будут работать во время выполнения!
File f = (File)(Object) "Stupid cast";
Компилятор допустит это, даже если это не имеет смысла, но он выйдет из строя во время выполнения с этим исключением:
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.io.File
источник
Приведение ссылки будет работать, только если она относится к
instanceof
этому типу. Вы не можете использовать случайные ссылки. Кроме того, вам нужно больше узнать оCasting Objects
.например
String string = "String"; Object object = string; // Perfectly fine since String is an Object String newString = (String)object; // This only works because the `reference` object is pointing to a valid String object.
источник
Правильный путь таков:
Этот метод
cast()
- гораздо более безопасная альтернатива приведению во время компиляции.источник