У меня есть приложение Android (Java), который хорошо работал при компиляции с SDK Android 1.6 с помощью следующего кода от android.provider. Класс контактов:
Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL;
Когда 2,0 SDK вышли, android.provider. Класс контактов обесценивался и заменялся android.provider. ContactsContract. Чтобы заставить одну программу работать и над 1,6 и над 2.0, я скомпилировал под 1,6 со следующим изменением:
Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL;
…
try {
Class<?> c = Class.forName("android.provider.ContactsContract$PhoneLookup");
baseUri = (Uri) c.getField("CONTENT_FILTER_URI").get(baseUri);
}
catch (Exception e) {
}
Так как я компилировал под 1,6, я не мог импортировать android.provider. ContactsContract, так как это - класс, известный только 2,0. Это считают отражением и до какой степени?
Добавленный Комментарий: После чтения "Отражательной" главы "Языка программирования Java" (который я должен был сделать сначала), я главным образом теперь понимаю то, что можно сделать с отражением, но краткое определение отражения не легко появиться. Ваши ответы помогли разъяснить то, что запросило мой вопрос - что, после того как над классом размышляли, и экземпляр класса, созданного с помощью отражения, можно взаимодействовать с экземпляром, как будто класс был new'ed.
Вот моя скудная попытка краткого определения, которое совсем не прекрасно, и я уверен, что должен буду пересмотреть, поскольку я узнаю больше:
Отражение является косвенным, динамическим запросом, управлением или вызовом объектов класса с помощью объектов класса, содержавшихся в java.lang.reflect или классах Класса или Пакета, который требует первоначально доступа к классу с помощью полностью определенного имени строки.
Думаю, это и есть само определение Java reflection (more on Android reflection for multiple-version compatibility). Я не уверен, что ты имеешь в виду под "до какой степени", это просто так.
Динамический запрос о наличии метода - это форма отражения, да.
Это отражение.
Если CONTENT_FILTER_URI
является окончательным статическим полем, то вы должны использовать get(null)
вместо get(baseUri)
, потому что вы не вызываете объект.
Edit
Я был немного сбит с толку вашим кодом. Как я понял ваш фрагмент, сначала вы назначаете Contacts.Phones. CONTENT_FILTER_URL
к URL baseUri
, затем вы отражаете поле CONTENT_FILTER_URI
в классе PhoneLookup
и читаете, что значение полей из экземпляра URL
, хранящегося в baseUri
, - чтобы присвоить значение baseUri
снова ! ? Типограф или место для улучшения?
Это очень хорошая статья о стратегиях, рефлексии и других более сложных вещах, для использования новых API, оставаясь совместимым со старыми платформами:
http://android-developers.blogspot.com/2009/04/backward-compatibility-for-android.html