c#的makegenerictype的java等价物,用于创建未知泛型类型的示例

m2xkgtsf  于 2021-07-06  发布在  Java
关注(0)|答案(3)|浏览(341)

我很久没有接触过java了。但是给定以下c#语法,是否可以在java中创建泛型类型的未知示例?

public void Send(object message)
{
    Type requestType = message.GetType();
    ReceiverWrapper receiverInstance = (ReceiverWrapper)
            Activator.CreateInstance(typeof(ReceiverWrapper<>).MakeGenericType(requestType));

    // do something with the receiver...
}

所以我们的想法是 Object message 属于类型 Message1 . 我想创建一个 ReceiverWrapper<Message1> .
我不想在方法签名-ala中使用泛型 public <T> void Send(T message) 我已经在java中理解了这一点。我很好奇我们是否可以从对象中提取类型信息并基于该类型创建泛型。

lhcgjxsq

lhcgjxsq1#

这里有几件事需要解释,首先var不是泛型类型。var将在编译时被实际类型替换,所以如果您想使用泛型,您可能不应该使用var。

public <T> void Send(T message)
{
    ReceiverWrapper<T> receiverInstance = new ReceiverWrapper<>();

// do something with the receiver...
}

我不太清楚你想用它做什么,但像这样的东西?

zynd9foi

zynd9foi2#

“…是否可以在java中创建泛型类型的未知示例?”
对。这是可能的。但是只有在某些前提条件可以保证的情况下(参见代码中的注解)。
我用下面的片段概述了这项技术的要点。工作实验可以在线运行…

{
    ...
    Optional< Object > parameterizedType ...

    TypeVariable< ? > typeVars[ ] ...

    /* Precondition #1: target MUST be a generic class */
    if( typeVars.length == 0 ){ throw new NotAGenericTypeException( ); }

    /* Precondition #2: target MUST expose a constructor that's declared to take arguments
     * whose type is that of those declared in the generic class's type parameter section */
    if( isConstructorCompatible ( target, typeVars ) ){

        try{ 
            parameterizedType = Optional.of( target.getClass( ).getConstructors( )[0].newInstance( typeArgs ) );
        } catch( ReflectiveOperationException roe ){ roe.printStackTrace( ); }
    }

    return parameterizedType;
}

·····所以 Object message 属于类型 Message1 . 我想创建一个 ReceiverWrapper<Message1> …“
尽管你的问题 Send(Object) 方法返回 void ,为了使我的概念证明更易于测试,我的实验实现返回了一个参数化类型的示例…

...
public Optional< Object > send( Object message ){ 
    return parameterizer.parameterize( ReceiverWrapper.class, message );    
}
...

用法示例…

...
/* Set up a test of @Andez's use case  */
Object sos = new Message( "Friends of space, how are you all? Have you eaten yet? Come visit us if you have time." );

/* The class under test */
ProofOfConcept voyager = new ProofOfConcept( );

/* Exercise the method under test */
Optional< Object > type  voyager.send( sos );

/* Prepare the outcome of the parameterization done in the previous voyager.send( ) call */
ReceiverWrapper< Message > oumuamua = type.map( raw -> (ReceiverWrapper< Message >)raw ).orElseThrow( AssertionError::new );

/* Leverage the compiler's type checking */
Message fromSpace = oumuamua.getMessage( );

/* Verify that the expected type returned by send( ) is the type of the type argument */
assert ((Object)fromSpace) instanceof Message : "EXPERIMENT FAILED";
...

实验结果…

Message [ payload: Friends of space, how are you all? Have you eaten yet? Come visit us if you have time. ]
             EXPERIMENT SUCCESSFUL

他们说这不可能:)

idv4meu8

idv4meu83#

我想创建一个 ReceiverWrapper<Message1> .
在java中没有这样的东西。只是 ReceiverWrapper . java泛型主要是编译时工件。例如,如果您有一个类型为 List<String> 你可以通过反射来确定,但是一个对象不是 ArrayList<String> ,这只是 ArrayList .

相关问题