tags:

views:

294

answers:

4

I've written a few bluetooth apps now, but I had never seen this particular approach until recently. In the example they use device.getClass().getMethod("createRfcommSocket", new Class[] { int.class }); which seems to me a long way of just saying BluetoothSocket bs = createRfcommSocket(....

What is the difference between their approach

Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
sock = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));

and mine

sock = createRfcommSocket(.....

Is there a reason to use one or the other?

Thank you

A: 

Yes, using getClass etc. is reflection.

The difference is that you get help from the IDE and the compiler in case you mistype the method name or make a similar mistake, while the authors of that code are on their own.

Maybe they are in a situation where the method to call just isn't available at compile time, which might be the case in the context of software that allows loading in new plugins at runtime. But in that case you wouldn't expect to see the method name and other details hardcoded into the code.

The literal text of your example just looks like poor programming to me.

reinierpost
It was a specific workaround for a bug or quirk in the Android OS, but generally it would indeed be poor programming.
mxrider
+1  A: 

Without knowing the exact details, one reason I can offer is that their approach has a sort of duck-typing about it. Regardless of the compile-time class of the object, so long as it has a method with the right signature, it can be invoked.

Now in general I think duck typing for the sake of it isn't a great idiom in Java. However, there might be other justifications for this approach. In particular, it means that this code won't have a compile-time dependency on the device's class. This can be one way out of circular dependencies, for example, and additional makes the compilation step more loosely coupled.

In a broader sense though, if your approach works then I don't see anything wrong with it. Using reflection is usually a workaround in essence for something that you can't do in a more idiomatic way.

Andrzej Doyle
+1  A: 

Beware that reflection makes it extremely easy to use implementation details of the platform that are not part of the SDK, since it is bypassing compile-time checking. There should never be a reason to use reflection like this to access a platform API, except for the case of backwards compatibility where you want your app to run on older versions of the platform that didn't have that API. And any time you are doing this, you should very carefully make sure that what you are accessing is actually part of the SDK.

hackbod
A: 

The answers on here are correct, but the specific reason for using reflection was as a workaround to issues surrounding createRfcommSocketToServiceRecord.

My reasons for doing it were from other people saying it was fixing their connection issues.

See here and here for more information. I think this bug has been fixed though, because createRfcommSocketToServiceRecord (without any workaround) is working fine on my Android OS 2.2 Nexus One.

mxrider