Created
February 5, 2017 17:17
-
-
Save lynxluna/8add3b8d3db7ab8fcea0e9d51795d430 to your computer and use it in GitHub Desktop.
Allocating Instance without calling constructor, just like you're doing with malloc()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.Field; | |
import java.lang.reflect.Method; | |
final class InstanceFactory <T> { | |
public T unsafeAllocate(final Class<?> clazz) { | |
final Class<?> unsafeClass = Class.forName("sun.misc.Unsafe"); | |
final Field f = unsafeClass.getDeclaredField("theUnsafe"); | |
f.setAccessible(true); | |
final Object unsafe = f.get(null); | |
final Method allocateInstance = unsafeClass.getMethod("allocateInstance", Class.class); | |
return (T) allocateInstance.invoke(unsafe, clazz); | |
} | |
} | |
// Usage on Immutable Class | |
final class Person { | |
private final String name; | |
private final String address; | |
public Person(final String newName, final String newAddress) { | |
name = newName; | |
address = newAddress; | |
} | |
public final String getName() { | |
return name; | |
} | |
public final String getAddress() { | |
return address; | |
} | |
public final String toString() { | |
return name + " --- " + address; | |
} | |
} | |
public class Main { | |
public static void main(final String[] args) { | |
// allocate | |
final Class<Person> clazz = Person.class; | |
final InstanceFactory<Person> factory = new InstanceFactory(); | |
final Person p = factory.unsafeAllocate(clazz); | |
// reflectively fill the fields | |
final Field nameField = clazz.getDeclaredField("name"); | |
nameField.setAccessible(true); | |
nameField.set(p, "Didiet"); | |
nameField.setAccessible(false); | |
final Field addressField = clazz.getDeclaredField("address"); | |
addressField.setAccessible(true); | |
addressField.set(p, "Jakarta"); | |
addressField.setAccessible(false); | |
System.out.println(p); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment