Я видел много вопросов с похожим заголовком в StackOverflow, но все эти ответы, похоже, предлагают метод getClass().getSimpleName() . Проблема в том, что я не хочу знать тип значения, который имеет переменная, меня интересует сам тип переменной. В следующем коде я хочу напечатать Object , а не String :
Учитывая, что тип переменной будет супер-типом значения, которое он имеет, я могу проверить, является ли это значение instanceof некоторого класса. Но instanceof вернет true для всех супер классов до тех пор, пока мы не достигнем Object в иерархии. Есть ли способ специально проверить тип переменной?
В этом случае в производственном коде могут быть не какие-либо практические примеры использования, но знание типа переменной может упростить использование дженериков. Рассмотрим этот метод:
Мы не знаем, какой тип компилятор возникает при вызове test с двумя разными аргументами. Возможно, было бы полезно распечатать замену T Мы знаем, что T будет заменен на наиболее специфический тип, который наследует тип аргументов при запуске программы. Но если бы я напечатал этот тип, я не могу.
Тип локальной переменной доступен только в отладочной информации.
- компилировать с помощью отладочной информации.
- прочитайте байтовый код для отладочной информации и определите, какой из них вы ищете.
ПРИМЕЧАНИЕ. Вы можете видеть эту информацию в своем отладчике во время выполнения без написания кода.
Однако гораздо более простое решение — написать программу, так что вам не нужно это знать. например, хранить данные в поле вместо локальной переменной.
Вы не сможете перейти от объекта к «переменной», которая его удерживает (по крайней мере, насколько я знаю). Итак, если ob в вашем примере является локальной переменной, вы не можете получить свой объявленный тип.
Учитывая, что на объект может указывать множество переменных разных объявленных типов данных, было бы странным стремлением разрешить «объявленный» тип объекта (это только мое мнение).
Пока объект существует, все, что имеет значение, — это его runtime, конкретный тип (который доступен через obj.getClass() ), что обеспечивает доступ к его иерархии типов.
Для объектов, хранящихся в полях члена класса (при условии, что вы знаете имя поля), вы можете получить объявленный тип поля:
Как я могу проверить, чтобы убедиться, что моя переменная — это int, array, double и т.д .
Изменить: Например, как я могу проверить, что переменная является массивом? Есть ли какая-то функция для этого?
10 ответов
Java является статически типизированным языком, поэтому компилятор выполняет большую часть этой проверки за вас. Как только вы объявите переменную определенного типа, компилятор будет гарантировать, что ей будут назначены только значения этого типа (или значения, которые являются подтипами этого типа).
Приведенные вами примеры (int, array, double) — это все примитивы, и их нет подтипов. Таким образом, если вы объявите переменную как int :
Вы можете быть уверены, что он будет содержать только значения типа int .
Однако, если вы объявили переменную List , возможно, она будет содержать подтипы List . Примеры их включают ArrayList , LinkedList и т. Д.
Если у вас есть переменная List , и вам нужно знать, является ли она ArrayList , вы можете сделать следующее:
Однако, если вы обнаружите, что думаете, что вам нужно сделать это, вы можете пересмотреть свой подход. В большинстве случаев, если вы следуете объектно-ориентированным принципам, вам не нужно это делать. Есть, конечно, исключения из каждого правила.
2 ufk [2011-01-03 16:17:00]
У меня есть следующий код:
как узнать тип переменной, переданной этой функции? например, как я могу узнать разницу, если пользователь выполнил эту функцию следующим образом:
в общем, я строю общие функции для работы с моей базой данных, и мне нужно использовать setLong/setInt/setString, зависит от того, какой тип переменной передается функции.
5 ответов
5 Решение T.J. Crowder [2011-01-03 16:19:00]
Вы можете использовать instanceof и/или getClass . Первые тесты против определенного класса, последний фактически дает вам объект Class ( String.class и т.д.) Для аргумента. Так, например:
Но для вашего конкретного случая вы можете использовать одну из версий PreparedStatement#setObject .
4 Bozho [2011-01-03 16:19:00]
- object.getClass() возвращает класс объекта. Вы можете использовать equals или isAssignableFrom(..) , чтобы сделать отражающие сравнения.
- вы можете использовать оператор instanceof для статических сравнений: if (object instanceof String)
В то время как они в порядке, вы должны избегать их использования в общем случае. Если вы заранее знаете, какие будут типы, которые пройдены, перегрузите методы: foo(Integer i) и foo(String s) . Если вы не знаете, вы можете использовать полиморфизм и двойную отправку. Просто сделайте, чтобы ваши объекты реализовали общий интерфейс:
if (экземпляр Integer) или if (экземпляр String)
1 James [2011-01-03 16:19:00]
Используйте ключевое слово instanceof
Если конечная цель — работать с базой данных, лучше не использовать Object для вашей функции, как это. Он не говорит никому, что законно передавать. Вместо этого я предлагаю использовать JDBC setObject (int parameterIndex, Object x, int targetSqlType) и указать вызывающему абоненту тип JDBC для вас:
То, что вы делаете с instanceof или getClass(), обычно является плохой практикой. Вы теряете важную информацию о типе, используя Object, а затем поворачиваетесь и жестко кодируете информацию типа в лестнице if. Лучше определить несколько методов для каждого типа, которые все называются одинаковыми. Поэтому, если у вас есть функция, которая может принимать 5 разных типов параметров, вы должны сделать следующее:
В этом примере я показал, как вы можете легко определить все типы, которые вы понимаете, как отдельные методы, отличающиеся только типом, и то, как вы можете централизовать некоторую логику преобразования в общей функции (convertThisValue()), чтобы вы могли поделиться некоторыми обработка между несколькими типами. Что лучше в этом подходе, вы используете Java-complier для обработки этой работы, чтобы вы соответствовали правильному методу с типом, который передал ему вызывающий. Нет необходимости в лестнице if, и компилятор будет жаловаться пользователю, если он не использует известный тип, который выступает против использования Object и его смерти во время выполнения.
В JDBC известные типы хорошо определены, поэтому вы можете легко создавать методы, которые знают, как обрабатывать каждый тип, понятный каждой базе данных JDBC. Также использование метода setObject() упрощает вашу работу.
Источник: