Proof of concept: how to dynamically select an available constructor using reflection in Java

I am developing a conceptual concept of (de-) serialization, ideally able to serialize any object and collect information about the class itself. I started implementing it with Reflection so that:

  • Access to type hierarchy (Superclasses, Interfaces, etc.)
  • Find all the fields of this object and get all the values ​​in these fields

Serialization is the "easy" part, and can be achieved by applying this rule recursively to the object until I find null or primitive types. Now that I'm stuck: deserialization.

Starting with a simple object, the string "Hello World", I have this serialization:

<object type="java.lang.String">
    <primitive name="count" type="int" value="11 />
    <primitive name="hash" type="int" value="0" />
    <primitive name="offset" type="int" value="0" />
    <array name="value" basetype="char">
        <value>H</value>
        <value>e</value>
        <value>l</value>
        ...
        <value>r</value>
        <value>l</value>
        <value>d</value>
    </array>
</object>

, String , Reflection, . , :

<object class="some-class-with-no-default-constructor">
    <object name="some-attrib-name" class="attrib-1-class">
    <primitive name="size" type="int" value="5" />
...
</object>

, . , , "null" , - , ?

: " " "- , ?". , .

.


EDIT

, , , , Unsafe.

public final class A {
    private final Object o;
    private A(final Object o) { if (o == null) throw new Error(); this.o = o; }
    public static A a() { return new A(new Object()); }
    public Object getO() { return o; }
}

, , , ( , , ), :

private static Unsafe getUnsafe() throws Exception {
    Field vDeclaredField = Unsafe.class.getDeclaredFields()[0];
    vDeclaredField.setAccessible(true);
    Unsafe vUnsafe = (Unsafe) vDeclaredField.get(null);
    vDeclaredField.setAccessible(false);
    return vUnsafe;
}

public static void main(String[] args) throws Exception {
    A objectA = (A) getUnsafe().allocateInstance(A.class);

    Field fieldO = A.class.getDeclaredField("o");
    boolean oldAccessibilityValue = fieldO.isAccessible();
    fieldO.setAccessible(true);
    Object objectOParameter = Arrays.asList(1,2,3,4); //could be any object
    fieldO.set(objectA, objectOParameter);
    fieldO.setAccessible(oldAccessibilityValue); //I personally prefer setting it to old value

    assert(objectOParameter.equals(objectA.getO()));
}

? , , - , SecurityManager?

+3
3

.

, :

public final class A {
    private final Object o;
    private A(final Object o) { if (o == null) throw new Error(); this.o = o; }
    public static A a() { return new A(new Object()); }
    public Object getO() { return o; }
}

, , , , null.

-, ( ) final, , ( - , , - SecurityManager, ).

, private ( , , ). , setAccessible(true) , .

, , , , (de) .

- . , . .


, " Java", API "sun.misc.Unsafe", Sun, . , .

, , , .. getDeclaredField ( "o" ). , , .

.

, , :

class StockQuoteProvider {
    private QuoteCache cache;
    private Thread quoteCacheUpdater;
    public StockQuoteProvider() {
        this.quoteCacheUpdater = ... // sets up a Thread that will use sockets to connect to Yahoo stock quote provider and update the cache periodically
        this.quoteCacheUpdater.start();
    }
    public Quote getQuote(final String symbol) { return ... }
}

Thread? ? , -, , ? ?! . .

,

. ( edit: , ). , :

// Represents a range of integers, {a, a+1, ..., b}, in which a < b.
class Range {
  private final Object lock = new Object();
  private int a;
  private int b;
  Range(final int a, final int b) { setAB(a, b); }
  final int[] getAB() { synchronized(lock) { return new int[]{a, b}; } }
  final void setAB(final int a, final int b) {
    if (!(a < b)) { throw new IllegalArgumentException("Invalid range"); }
    synchronized(lock) { this.a = a; this.b = b; }
  }
  @Override public String toString() {
    int[] ab = getAB();
    int a = ab[0];
    int b = ab[1];
    return a + " < " + b;
  }
}

, , ? , int [] , , , a b .

, . "" , "a >= b".

, , . , OP 2 : "Object serialize (Object o)" "Object deserialize (Object o)", . , :

public class Test {
  public static Range r = null;
  public static void Main(final String[] args) {
    final Thread t1 = new Thread(new Runnable() {
      @Override void run() { r = deserialize(serialize(new Range(1, 3)); }
    });

    final Thread t2 = new Thread(new Runnable() {
      @Override void run() { System.out.println(r); }
    });

    t1.start();
    t2.start();
}

? , null, r T2. ( , ), , T2 r. , JVM Range . , "0 < 0" , T2 a b, "1 < 0" ( a), "0 < 3" "1 < 3" . Java, ( , 5 ).

, , . , ( - , (?) -), ... , ?

...

. ( setAccessible(true)), ( sun.misc.Unsafe) (class Range), , (class StockQuoteProvider). 4 , , Java - .

, , , . , .

.

+4

" " ?

, . , , , , JavaBeans, .

- - (, xml) , , , .

0

, , .

Objenesis.

.

0

All Articles