views:

703

answers:

4

I have an Android application (java) that was working fine when compiled with the Android 1.6 SDK using the following code from the android.provider.Contacts class:

Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL;

When the 2.0 SDK came out, the android.provider.Contacts class was depreciated and replaced with android.provider.ContactsContract. In order to get one program to work on both 1.6 and 2.0, I compiled under 1.6 with the following change:

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) {           
}

Since I was compiling under 1.6, I could not import android.provider.ContactsContract since it is a class known only to 2.0. Is this considered reflection and to what degree?

Added Comment: After reading the "Reflection" chapter of "The Java Programming Language" (which I should have done first), I mostly now understand what you can do with reflection but a concise definition of reflection is not easy to come by. Your answers have helped to clarify what prompted my question - that once a class has been reflected on, and an instance of the class created using reflection, you can interact with the instance as if the class was new'ed.

Here is my meager attempt at a concise definition that is far from perfect and I am sure I will need to revise as I learn more:

Reflection is the indirect, dynamic inquiry, manipulation or invocation of class objects using class objects contained in java.lang.reflect or the Class or Package classes that requires initially accessing the class using a fully qualified string name.

+5  A: 

I believe that is the very definition of Java reflection (more on Android reflection for multiple-version compatibility). I'm not sure what you mean by "to what degree"; it just is.

Daniel Lew
right - either it is or it isn't. In this case, it is.
nont
By to what degree I mean is that all there is to reflection? JasperE says my example is only one form implying there is more to reflection than simply "dynamically asking for the availability of a method".
fupsduck
Well, there are more things one can do with reflection as necessary, such as creating objects or invoking methods. You could also use reflection just to discover what member variables and class methods a Class has.
Daniel Lew
The "Java reflection" link you provided is what I used to make the program change. I just had a hard time extracting a concise definition of reflection from it.
fupsduck
+4  A: 

Dynamically asking for the availability of a method is a form of reflection, yes.

JesperE
So bottom-line, anytime you access objects using their fully-qualified names it is reflection but there are other forms of reflection?
fupsduck
Nop. Reflection is accessing type objects from strings or other value-types. It is, if you can hold the name of the class or method in a string variable and get it. It's reflection because the compiler doesn't know/check the value of that var.
helios
Or maybe reflection = accessing type information at runtime.
helios
Well, you can use reflection to invoke methods or create objects too. It's all under the umbrella of reflection, what you have above is one aspect of it.
Daniel Lew
+1  A: 

It's reflection.

If CONTENT_FILTER_URI is a final static field, then you should use get(null) instead of get(baseUri) because you are not invoking an object.

Edit

I was a bit confused by your code. As I understand your snippet, first you assign Contacts.Phones.CONTENT_FILTER_URL to URL baseUri, then you reflect the CONTENT_FILTER_URI field on the PhoneLookup class and read that fields value from the URL instance stored in baseUri - just to assign the value to baseUri again !? Typo or room for improvement?

Andreas_D
The way I understand it is that the initial assignment is needed when the program runs under 1.6 and the reflected assignment is needed when running under 2.0. Since an exception gets thrown under 2.0 the initial assignment prevails when running under 1.6.
fupsduck
Type - the exception gets thrown under 1.6 not 2.0 because the android.provider.ContactsContract class does not exist under 1.6.
fupsduck
Type - above = Typo in first comment.
fupsduck
+1  A: 

This is a very good article on strategies, reflection and other more sophisticated things, for using new APIs while remaining compatible with older platforms:

http://android-developers.blogspot.com/2009/04/backward-compatibility-for-android.html

hackbod