Поиск подходящего конструктора в java::new

This commit is contained in:
Victor 2019-10-03 20:36:38 +03:00
parent a5c8842dad
commit 483c7c1242
2 changed files with 26 additions and 8 deletions

View File

@ -3,6 +3,7 @@ package com.annimon.ownlang.modules.java;
import com.annimon.ownlang.lib.*; import com.annimon.ownlang.lib.*;
import com.annimon.ownlang.modules.Module; import com.annimon.ownlang.modules.Module;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -156,17 +157,13 @@ public final class java implements Module {
return new ClassValue(clazz.asSubclass( ((ClassValue)args[0]).clazz )); return new ClassValue(clazz.asSubclass( ((ClassValue)args[0]).clazz ));
} }
private Value isAssignableFrom(Value... args) { private Value isAssignableFrom(Value[] args) {
Arguments.check(1, args.length); Arguments.check(1, args.length);
return NumberValue.fromBoolean(clazz.isAssignableFrom( ((ClassValue)args[0]).clazz )); return NumberValue.fromBoolean(clazz.isAssignableFrom( ((ClassValue)args[0]).clazz ));
} }
private Value newInstance(Value... args) { private Value newInstance(Value[] args) {
try { return findConstructorAndInstantiate(args, clazz.getConstructors());
return new ObjectValue(clazz.newInstance());
} catch (InstantiationException | IllegalAccessException ex) {
return NULL;
}
} }
private Value cast(Value... args) { private Value cast(Value... args) {
@ -293,6 +290,21 @@ public final class java implements Module {
return NULL; return NULL;
} }
private static Value findConstructorAndInstantiate(Value[] args, Constructor<?>[] ctors) {
for (Constructor<?> ctor : ctors) {
if (ctor.getParameterCount() != args.length) continue;
if (!isMatch(args, ctor.getParameterTypes())) continue;
try {
final Object result = ctor.newInstance(valuesToObjects(args));
return new ObjectValue(result);
} catch (InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException ex) {
// skip
}
}
return null;
}
private static Function methodsToFunction(Object object, List<Method> methods) { private static Function methodsToFunction(Object object, List<Method> methods) {
return (args) -> { return (args) -> {
@ -312,7 +324,7 @@ public final class java implements Module {
return null; return null;
}; };
} }
private static boolean isMatch(Value[] args, Class<?>[] types) { private static boolean isMatch(Value[] args, Class<?>[] types) {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
final Value arg = args[i]; final Value arg = args[i];

View File

@ -36,6 +36,12 @@ def testInvokeMethodSameName() {
assertEquals("text", data.getText()) assertEquals("text", data.getText())
} }
def testNonDefaultConstructor() {
StringBuilder = newClass("java.lang.StringBuilder")
sb = StringBuilder.`new`("text")
assertEquals("text", sb.toString())
}
def createObject() { def createObject() {
dataClass = newClass("interop.Data") dataClass = newClass("interop.Data")