简体   繁体   中英

how to init an instance in a java generic method

I have this code:

    public <V> V getPropertiesByObject(V sample) throws TimeoutException {
//settings fields using reflaction
        return sample;
    }

which I call like this:

MyClass a = getPropertiesByObject(new MyClass());

only because I don't know how to construct an instance otherwise.

I would prefer:

public <V> V getPropertiesByObject(Class<V> sample) throws TimeoutException {
//how to create a new V instance?
    return result;
}

Is there a way to refactor my original code?

You can use reflection - here's a basic implementation that shows one way:

public <V> V getPropertiesByObject(Class<V> clazz, Object... params) throws TimeoutException {
    Class<?>[] paramClasses = new Class<?>[params.length];
    for (int i =0; i < params.length; i++)
        paramClasses[i] = params[i].getClass(); 
    V result = clazz.getConstructor(paramClasses).newInstance((Object[])params);
    return result;
}

The parameter params , which may be empty, are the parameters to pass to the constructor corresponding to those parameters. This code won't handle null values. Here's how you might call it:

String str = getPropertiesByObject(String.class); // blank String
Integer i = getPropertiesByObject(Integer.class, "1"); // 1

If V has a parameterless constructor, you can use Class<V>::newInstance() .

public <V> V getPropertiesByObject(Class<V> sample) throws TimeoutException {
    V result = sample.newInstance();
    // stuff on V
    return result;
}

Of course, you will use it like this: MyClass a = getPropertiesByObject(MyClass.class)

If you have to specify some parameters, you can do something like:

public <V> V getPropertiesByObject(Class<V> sample, Object... params) throws TimeoutException {
    V result = sample.newInstance();
    result.param0 = params[0];
    result.param1 = params[1];
    // etc  
    return result;
}

But in both case, MyClass must have a parameterless constructor. If you can't edit MyClass , you should use the Bohemian's answer using Constructor .

So you want to create a method that can create an instance of ANY possible class and set ANY possible fields to the instance?

This is quite hard. Frameworks like GSON have the same issue and they either require that you have a no-argument constructor in the beans used, or provide a way to create instances for a certain class (see Is default no-args constructor mandatory for Gson? ).

Else for your specific case - if you know the set of classes that you are going to instantiate then you can implement a factory class that creates instances based on a class object with some kind of if-else-if-else... structure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM