In Java and Android, we often use reflection for compatibility purposes. The reflection provided by Java native is cumbersome and inconvenient to use. For example, if we want to call the static method get of UserManager, the native implementation is as follows

try {
 final Method m = UserManager.class.getMethod("get", Context.class);
 m.setAccessible(true);
 m.invoke(null, this);
} catch (NoSuchMethodException e) {
 e.printStackTrace();
} catch (IllegalAccessException e) {
 e.printStackTrace();
} catch (InvocationTargetException e) {
 e.printStackTrace();
}
Copy the code

It’s easy to implement. the

  • You need to determine the Method name and parameters to get the corresponding Method object
  • Set the Method object’s assessible to true
  • Call the invoke method and pass in the corresponding argument
  • Catch a string of exceptions that might be thrown

Could reflection be easier? Sure, it would be a lot easier.

This is what I want to introduce in this article, jOOR(Java Object Oriented Reflection), which is a simple encapsulation of the Java.lang.Reflect package that makes it more straightforward and convenient to use.

With jOOR, the above code can be shortened to one line.

Reflect.on(UserManager.class).call("get", getApplicationContext());
Copy the code

Rely on

  • JOOR has no dependencies.
  • To use jOOR, you just need to add these two files (reflectException. Java and reflectException. Java) to the project.

The API is introduced

Reflect

  • Reflect.on wraps a Class or object to Reflect on. The value of the Class can be Class or the full Class name (including the package name information).
  • Reflect.create is used to call the constructor of the previous class, with two overloads, one with and one without arguments
  • Reflect.call method call, passing in the method name and parameters, and calling GET if there is a return value
  • Reflect.get gets (field and method return) values and performs type conversions. It is often used in combination with call and field
  • Reflect.field gets the value associated with the property, which requires a call to get
  • Reflect.set Sets attribute correlation.

ReflectException

Introducing reflectExceptions prevents us from catching too many exceptions and reduces the amount of vertical code, making the code much cleaner. ReflectException is thrown, and the following exception may have occurred.

  • ClassNotFoundException
  • IllegalAccessException
  • IllegalArgumentException
  • InstantiationException
  • InvocationTargetException
  • NoSuchMethodException
  • NoSuchFieldException
  • SecurityException

In addition, a ReflectException is an unchecked exception. It is grammatically unnecessary to explicitly catch an exception, but you need to consider whether to explicitly catch an exception based on the actual situation.

Use the sample

Create an instance

String string = Reflect.on(String.class).create("Hello World").get();
Copy the code

Access attributes (public, protected, package, private)

1

char pathSeparatorChar = Reflect.on(File.class).create("/sdcard/droidyue.com").field("pathSeparatorChar").get();
Copy the code

Modify properties (Final properties can also be modified)

1

String setValue = Reflect.on(File.class).create("/sdcard/drodiyue.com").set("path", "fakepath").get("path");
Copy the code

Calls the method (public, protected, package, private)

ArrayList arrayList = new ArrayList();
arrayList.add("Hello");
arrayList.add("World");
int value = Reflect.on(arrayList).call("hugeCapacity", 12).get();
Copy the code

Realize the principle of

Reflect is essentially a wrapper around native Java Reflect, masking extraneous details.

In the case of the Fields method, the internal implementation can be seen as calling the reflection-related code provided by Java natively.

public Map fields() { Map result = new LinkedHashMap(); Class type = type(); do { for (Field field : type.getDeclaredFields()) { if (! isClass ^ Modifier.isStatic(field.getModifiers())) { String name = field.getName(); if (! result.containsKey(name)) result.put(name, field(name)); } } type = type.getSuperclass(); } while (type ! = null); return result; }Copy the code

The base address

That’s all. I hope jOOR can help you with your daily development.