Кастинг в Java не волшебный, вы говорите компилятору, что объект типа A на самом деле имеет более специфический тип B и, таким образом, получает доступ ко всем методам на B, которых вы не имели бы в противном случае. Вы не выполняете какой-либо магии или конверсии при выполнении кастинга, вы, по сути, говорите компилятору: «Поверьте мне, я знаю, что я делаю, и я могу гарантировать, что этот объект в этой строке на самом деле является & lt; Insert тип литья здесь & gt ;. " Например:
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
как Number
, тогда это нормально (поскольку все целые числа - это числа). Однако, если вы хотите пойти наоборот, нужен листинг - не все числа являются целыми (как и Integer, мы имеем Double
, Float
, Byte
, Long
и т. д.). И даже если в вашем проекте или JDK есть только один подкласс, кто-то может легко создать другое и распространить его, поэтому у вас нет гарантии, даже если вы считаете, что это единственный очевидный выбор!
Что касается использования для кастинга, вы по-прежнему видите необходимость в нем в некоторых библиотеках. Предварительная Java-5 использовалась в коллекциях и других классах, поскольку все коллекции работали над добавлением объектов, а затем выдавали результат, который вы получили из коллекции. Однако с появлением дженериков большая часть использования для кастинга ушла - его заменили дженерики, которые обеспечивают гораздо более безопасную альтернативу, не имея возможности для ClassCastExceptions (на самом деле, если вы используете дженерики чисто и компилируются без предупреждений, у вас есть гарантия, что вы никогда не получите исключение ClassCastException.)
Вы можете использовать этап агрегатного конвейера $geoNear
для создания расстояния от запрашиваемой точки:
db.new_stores.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -81.093699, 32.074673 ]
},
"maxDistance": 500 * 1609,
"spherical": true,
"distanceField": "distance",
"distanceMultiplier": 0.000621371
}}
]).pretty()
Это позволяет указать "distanceField"
, который будет производить другое поле в выходных документах, содержащих расстояние от запрашиваемой точки. Вы также можете использовать "distanceMultiplier"
для применения любого преобразования на выходное расстояние по мере необходимости (т. Е. Метров до миль и отмечая, что все расстояния GeoJSON возвращаются в метрах)
Существует также geoNear
] с аналогичными параметрами, но он, конечно, не возвращает курсор в качестве вывода.