4

There are some cases when we can create an instance without invoking a constructor of instance class. Any ideas what are these cases (Non Reflection API)?

barbara
  • 3,111
  • 6
  • 30
  • 58
  • Hi, could you edit and provide some code where you're finding this error? – Yann Aug 22 '14 at 13:13
  • this isnt possible becasue the constructor is what makes an object. – rush2sk8 Aug 22 '14 at 13:14
  • i don't have any idea. how could that be allowed to happen? – Jason Hu Aug 22 '14 at 13:14
  • Maybe you think about invoking static methods which actually call the constructor like `Sets.newHashSet()` with Guava? – Arnaud Denoyelle Aug 22 '14 at 13:14
  • The example you are looking can be found on https://code.google.com/p/objenesis/, when here's no public constructor, you want to bypass the constructor code, or set final fields – user3487063 Aug 22 '14 at 13:17
  • You can create a `String` without ecplicitly invoking a constructor, using a literal. – Keppil Aug 22 '14 at 13:17
  • Could you clarify on what you mean by invoking a constructor of this class? Because, as pointed out already at least one constructor in a classes' hierarchy (Object's constructor for example) will **ALWAYS** run, even when deserializing objects. – Rudi Kershaw Aug 22 '14 at 13:23

4 Answers4

8

Here's a sure way to break your system, but at least it won't invoke the constructor. Use Unsafe#allocateInstance(Class)

import java.lang.reflect.Field;
import sun.misc.Unsafe;

public class Example {
    private String value = "42";
    public static void main(String[] args) throws Exception {
        Example instance = (Example) unsafe.allocateInstance(Example.class);
        System.out.println(instance.value);
    }

    static Unsafe unsafe;
    static {
        try {

            Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
            singleoneInstanceField.setAccessible(true);
            unsafe = (Unsafe) singleoneInstanceField.get(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

which prints

null

indicating that the Example default constructor wasn't invoked.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • 1
    Going through Unsafe is just nasty ;) – Kayaman Aug 22 '14 at 13:22
  • 1
    Reflection is usually considered bad, Unsafe is just evil. – Kayaman Aug 22 '14 at 13:23
  • Interesting to note: if `value` is declared `final`, it **will** be initialized and then `"42"` will be printed. – icza Aug 22 '14 at 13:28
  • 1
    @icza Not exactly. If you print it out with `instance.value`, it will print `"42"`, because it's a constant expression and was replaced at compile time. But if you retrieve it dynamically with a `Field` instance, it will actually be `null`. – Sotirios Delimanolis Aug 22 '14 at 13:30
  • @icza Similarly, if you declared it `final` and initialized it in a constructor, you would again see it `null`. – Sotirios Delimanolis Aug 22 '14 at 13:30
  • @SotiriosDelimanolis You're right, it's just a compiler optimization (although a false one in this case... even the compiler assumes a constructor will be called). – icza Aug 22 '14 at 13:34
  • @barbara To clarify, this uses Reflection to get the `Unsafe` instance, but it doesn't use reflection to create the `Example` instance. – tcooc Aug 22 '14 at 21:15
  • Reflection is not bad. Lots of libraries have a legitimate use for it. Writing a plugin system is one use. Unsafe should be avoided like the plague if you want high quality stable software. If it is a personal project or some sort of way out in left field project then do whatever it takes. – markbernard Aug 22 '14 at 22:21
4

Two "common" cases involving non-constructor based object creation are deserialization and clone().

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • Can you elaborate on how they don't use a constructor? Every instance has to be created through a constructor as far as I know, all these do is hide it. – Jeroen Vannevel Aug 22 '14 at 13:18
  • @JeroenVannevel No they don't hide it. It's JVM magic, the constructor is never called (which can be easily tested). – Kayaman Aug 22 '14 at 13:20
  • @JeroenVannevel Isn't clone implemented by a native method? http://stackoverflow.com/questions/6825982/how-does-clone-work-under-the-hood – Michał Schielmann Aug 22 '14 at 13:20
  • 6
    @barbara What do you mean it's not the "correct" answer? Either you are saying this isn't right (then you should explain why) or you know the answer to your own question and are wasting peoples time. – Andrew_CS Aug 22 '14 at 13:22
  • Ah, I wasn't aware about `clone()`'s special case. As to deserialization I figured a default constructor was invoked and reflection used to fill its values, but I never explicitly looked into it. – Jeroen Vannevel Aug 22 '14 at 13:24
  • @Andrew_CS About wasting other's time: not eactly: http://stackoverflow.com/help/self-answer – icza Aug 22 '14 at 13:31
  • 1
    @icza That would be fine if the OP did that. – Andrew_CS Aug 22 '14 at 13:33
1

The only cases that I can imagine are serialization and JNI.

With serialization, you create a new object by deserializing the whole object state from an input stream. No constructor is invoked in this case.

With JNI, there is the AllocObject function, which allocates the space for a new object, also without calling a constructor.

EDIT: A call to clone() may be considered as another case, but this depends on how the method is implemented.

Marco13
  • 53,703
  • 9
  • 80
  • 159
0

There are 4 ways of creating an instance of an Object

1) Through constructor using new keyword -The constructor should be accessible

2) Through serialization/deserialization-The class should be Serializable;

3) Through clone() method -The method should implement the marker interface Cloneable

4) Through reflection-You can access the constructor and create an instance without using the new keyword.The best thing about Reflection is that it can be used to instantiate Objects for private Constructors ,provided one does not mess up with SecurityManager

Kumar Abhinav
  • 6,565
  • 2
  • 24
  • 35