这是否被认为是反射,程度如何?

6

我有一个Android应用程序(Java),在使用Android 1.6 SDK编译时,以下来自android.provider.Contacts类的代码可以正常工作:

Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL;

当2.0 SDK发布时,android.provider.Contacts类被弃用并替换为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编程语言》中的“反射”章节(我本应该先这样做),我现在大部分理解了反射可以做什么,但是对于反射的简洁定义并不容易得到。您的答案有助于澄清我的问题 - 一旦对类进行了反射,并使用反射创建了类的实例,则可以像新建类一样与实例交互。
这是我关于反射的简明定义的微薄尝试,远非完美,我相信我需要在学习更多后进行修订:
反射是使用java.lang.reflect中包含的类对象或Class或Package类中包含的类对象间接动态查询、操作或调用类对象,需要最初使用完全限定的字符串名称访问类。

3
请注意,尽管该URI已在2.0中被弃用,但该功能应该仍然存在于一段时间的框架中(虽然有时Android对“弃用”这个词有自己的解释)。 - Christopher Orr
您说得对,该功能仍然存在,只是在2.0版本下无法正常工作。所请求的联系人未被检索到。我记不清它是否每次返回无联系人或“我的联系人卡片”联系人。 - fupsduck
与其依赖于ClassNotFound异常,你可以通过环境属性主动检查你的代码运行在哪个版本的Android上,并切换调用返回BaseURI的子函数。 - Scott Markwell
我尝试过这样做,但是我必须在1.6下编译才能使一个应用程序在1.6和2.0上运行。因此,在2.0上运行时,android.provider.ContactsContract类不可直接使用(因为它是在1.6中编译的)。这就是为什么我不得不使用反射的原因。 - fupsduck
4个回答

6

通过“程度”我指的是反射的全部内容吗?JasperE表示,我的例子只是一种形式,这意味着反射并不仅仅是“动态地询问方法是否可用”。 - fupsduck
嗯,使用反射可以做更多的事情,例如创建对象或调用方法。您还可以仅使用反射来发现类具有哪些成员变量和类方法。 - Dan Lew
你提供的“Java反射”链接是我用来改变程序的。但是从中提取出简明的反射定义让我有些困难。 - fupsduck

4
动态地查询方法的可用性是一种反射形式。

总之,每当您使用完全限定名称访问对象时,它就是反射,但还有其他形式的反射吗? - fupsduck
反射是从字符串或其他值类型访问类型对象。如果您可以将类或方法的名称保存在字符串变量中并获取它,则称为反射。这是反射,因为编译器不知道/检查该变量的值。 - helios
你也可以使用反射来调用方法或创建对象。这都属于反射的范畴,你上面所说的只是其中的一个方面。 - Dan Lew

1

这是反射。

如果CONTENT_FILTER_URI是一个final static字段,那么你应该使用get(null)而不是get(baseUri),因为你没有调用对象。

编辑

我对你的代码有点困惑。据我理解你的片段,首先你将Contacts.Phones.CONTENT_FILTER_URL赋值给URL baseUri,然后在PhoneLookup类上反射CONTENT_FILTER_URI字段,并从存储在baseUri中的URL实例中读取该字段的值 - 只是为了再次将该值分配给baseUri!?是打字错误还是有改进的空间?


我理解的方式是,在程序运行于1.6版本时需要初始赋值,而在2.0版本下运行时需要反射赋值。由于在2.0版本下会抛出异常,因此在1.6版本下运行时初始赋值将占优势。 - fupsduck
类型 - 异常在1.6下被抛出而不是2.0,因为android.provider.ContactsContract类在1.6下不存在。 - fupsduck
以上类型 = 第一条评论中的打字错误。 - fupsduck

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接