6

Do Android have any way to instantiate objects without calling any of its constructors?

In Java, Sun have sun.reflect.ReflectionFactory.getReflectionFactory().newConstructorForSerialization(), in .Net we have System.Runtime.Serialization.FormatterServices.GetUninitializedObject() but I was not able to find anything like that in the Android platform.

Vagaus
  • 4,174
  • 20
  • 31
  • 3
    I'd be really curious to hear what the use case is for something like that. – Rich Jun 25 '10 at 21:18
  • 1
    Is your goal to deserialize so to speak objects that only have non empty constructors? This is an interesting request. – Quintin Robinson Jun 25 '10 at 21:21
  • @Rich,Anthony, The reason is the same as the Serialization infrastructure. I work in a oodb and as soon as we instantiate the object we set its fields so calling constructors is at least waste of time/resources. In the worst cases we may have no viable constructor to use (all available constructors may throw when called with null/default values for its parameters) – Vagaus Jun 25 '10 at 21:24
  • @Quintin Robinson: basically we don't care if the class has any constructor at all. If possible it'd be better to just bypass calling any constructor. – Vagaus Jun 25 '10 at 21:26

4 Answers4

5

After looking into Android source code we found a way to achieve this by using ObjectInputStream#newInstance() static method.

private Object newInstanceSkippingConstructor(final Class clazz) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,     InvocationTargetException {

    Method newInstance = ObjectInputStream.class.getDeclaredMethod("newInstance", Class.class, Class.class);
    newInstance.setAccessible(true);
    return newInstance.invoke(null, clazz, Object.class);

}
Vagaus
  • 4,174
  • 20
  • 31
  • Is this now out of date? I am using API 19 and there is no ObjectInputStream.newInstance(Class, Class) method as far as I can tell. Is there an alternative? – Johnus Oct 15 '14 at 04:00
  • 1
    Hey, looking in Android source code looks like this method indeed got removed. Since I am not working with this code anymore I don't know if there's some alternative. The code in ObjectInputStream relies on Class.newInstance(), which based on the documentation, does calls ctors. – Vagaus Oct 16 '14 at 12:48
2

You can do this from native code with the JNI AllocObject function. See the JNI Spec. Calling out to native code is going to be more expensive than calling a no-op constructor, but probably cheaper than calling a constructor that throws an exception.

I don't know if there's another way to do it. Nothing is leaping out at me.

fadden
  • 51,356
  • 5
  • 116
  • 166
0

I don't believe so, however the Android platform does contain the Java Reflection API in java.lang.reflect.* so anything that is possible using the Java Reflection API is possible in Android

chrisbunney
  • 5,819
  • 7
  • 48
  • 67
  • Indeed, I noticed that package but as I said, I could not find anything to achieve my goal :( – Vagaus Jun 25 '10 at 21:34
0

I found out a library that can handle OBJ init with constructor bypass http://objenesis.org/index.html And they have different methods for different APIs. There is a slight difference in their API 17 and 18+ impl as in the current suggested answer. Also Android N+ is using something called Unsafe that should be implemented by new JVMs http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

Dominik Mičuta
  • 357
  • 4
  • 13