javonet:如何在泛型类上创建NNull

时间:2016-09-27 16:52:13

标签: java .net generics java-native-interface javonet

我正在评估javonet从java调用C#dll。我认为它对我的上下文更合适(jni4net通用失败,JnBridge不导出我的所有类型)

我想在复杂泛型上调用一个带有null实例的方法。

System.Func<MyType<MySubType>, MyOtherType, MyAnotherType>

我试着打电话没有通用但javonet找不到方法。

new NNull("System.Func")

我试着回复,但javonet再次找不到方法。

new NNull("System.Func`3[MyType`1[MySubType],MyOtherType,MyAnotherType]")

我找不到调用NNull的通用方法?有没有?

感谢提前获得任何帮助; o)

1 个答案:

答案 0 :(得分:0)

如果只有一个方法具有匹配的参数数量(没有重载),那么您可以轻松传递“null”。

但是因为Javonet invoke(String, Object...)方法需要方法名称和任意数量的参数,如果你想传递单个参数null,你必须调用obj.invoke(“MethodName”,new Object [] {null});所以Java知道你传递单个参数null而不是null数组,这意味着根本没有参数。

在.NET方面你的情况:

public class ObjA
{
    public void MethodA(Func<MyType<MySubType>, MyOtherType, MyAnotherType>  arg)
    {
        Console.WriteLine("Called MethodA");
    }
}

public class MyType<T>
{

}
public class MySubType
{

}

public class MyOtherType
{

}

public class MyAnotherType
{

}

要使用Javonet从Java调用它,您只需:

    NObject objA = Javonet.New("ObjA");
    objA.invoke("MethodA",new Object[] {null});

只有当另一个方法具有匹配的参数数量时,才需要NNull type当.NET无法从传递哪个方法的null中扣除。例如:

public void MethodA(Func<String> arg1);
public void MethodA(Func<int> arg1);

多次重载

另一方面,如果您有多个具有相同参数数量的方法的重载,并且想要传递null而不是复制参数,那么必须与纯.NET相同,您必须将null转换为期望的类型:

public class ObjA
{
    public void MethodA(Func<MyType<MySubType>, MyOtherType, MyAnotherType> arg, int arg2)
    {
        Console.WriteLine("Called MethodA with args: Func<MyType<MySubType>, MyOtherType, MyAnotherType> arg, int arg2");
    }
    public void MethodA(Func<MyOtherType> arg, int arg2)
    {
        Console.WriteLine("Called MethodA with args: Func<MyOtherType> arg, int arg2");
    }
}

在.NET中,您可以调用:

MethodA((Func<MyType<MySubType>, MyOtherType, MyAnotherType>)null, 0);

您仍然可以使用此处提供的Javonet 1.4hf26-SNAPSHOT版本在Java中完成相同的操作: http://download.javonet.com/1.4/javonet-1.4hf26-SNAPSHOT.jar

不是正式发售,但是稳定,可以使用。该补丁包括将NType作为参数传递给NNull对象的可能性。在这种情况下,您将能够使用Javonet泛型类型创建语法构造复杂泛型类型,如下例所示:

    NType myAnotherType = Javonet.getType("MyAnotherType");
    NType myOtherType = Javonet.getType("MyOtherType");
    NType mySubType = Javonet.getType("MySubType");
    NType myType = Javonet.getType("MyType`1",mySubType);
    NType func = Javonet.getType("Func`3",myType,myOtherType,myAnotherType);

    NObject objA = Javonet.New("ObjA");
    objA.invoke("MethodA",new NNull(func),0);