2017-01-21 7 views
2

Это Котлин эквивалент Java кода с использованием InvocationHandler:Почему Котлин бросить IllegalArgumentException при использовании прокси

override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any { 
    println("before httprequest--->" + args) 
    val ret = method!!.invoke(obj, args) 
    println("after httprequest--->") 
    return ret 
} 

Java код:

public Object invoke(Object o, Method method, Object[] args) throws Throwable { 
    System.out.println("jdk--------->http" + args); 
    Object result=method.invoke(target, args); 
    System.out.println("jdk--------->http"); 
    return result; 
} 

В обоих случаях args равна нулю, но если я бегу it, Kotlin код Предоставляется исключение

Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments 

Что такое th Причина этого в том, что Kotlin использует стандартный Java-класс?

+0

'неправильное количество аргументов': вы рассматривали аргументы в любом случае? Можете ли вы «утверждать» длину массива перед вызовом? – 9000

+0

Привет @ 9000, оба аргумента «args» имеют значение null перед оператором печати – WenChao

ответ

5

Когда вы передаете args в method!!.invoke(obj, args) в Котлин, это фактически единственный аргумент типа массива, а по умолчанию он не разлагается на элементы как отдельные аргументы.

Для достижения такого поведения вместо использования spread operator: *args

val ret = method!!.invoke(obj, *args) 

С помощью этого синтаксиса, args будет передаваться таким же образом, как и в Java переменной длины. Например, следующие строки кода эквивалентны:

someVarargsFunction("a", "b", "c", "d", "e") 
someVarargsFunction("a", "b", *arrayOf("c", "d"), "e") 

Примечание: если метод не имеет никаких параметров, args будет null, и распространение его в Котлин приведет в NullPointerException. В качестве обходного пути используйте *(args ?: arrayOfNulls<Any>(0)), а в описанном угловом корпусе выбирается правая часть и делится на ноль аргументов.


Моя реализация пример прокси:

interface SomeInterface { 
    fun f(a: Int, b: Int): Int 
} 

val obj = object : SomeInterface { 
    override fun f(a: Int, b: Int) = a + b 
} 

val a = Proxy.newProxyInstance(
     SomeInterface::class.java.classLoader, 
     arrayOf(SomeInterface::class.java)) { proxy, method, args -> 
    println("Before; args: " + args?.contentToString()) 
    val ret = method!!.invoke(obj, *(args ?: arrayOfNulls<Any>(0))) 
    println("After; result: $ret") 
    ret 
} as SomeInterface 

println(a.f(1, 2)) 

И выход:

Before; args: [1, 2] 
After; result: 3 
3 
+0

Спасибо за знание, однако, если я просто заменю args на «null», я получаю такое же Исключение? Любые мысли по этому поводу? – WenChao

+0

Spread массив из одного нуля: '* arrayOfNulls (1)' –

+0

@EugenPechanec же результат :( – WenChao