带有varargs的Java反射调用方法
我在计算用户传递的参数数量以及将参数长度与预期计数进行比较时遇到了反射问题。如果满足此要求,则使用方法调用程序的带有varargs的Java反射调用方法,java,reflection,methods,invoke,variadic-functions,Java,Reflection,Methods,Invoke,Variadic Functions,我在计算用户传递的参数数量以及将参数长度与预期计数进行比较时遇到了反射问题。如果满足此要求,则使用方法调用程序的对象[]{incomminingarguments}(varargs)参数继续执行该方法 在我的LogicGates类中有一个名为compute()的方法。该方法需要2到3个参数。第一个参数是gate,接下来的1或2是输入,具体取决于gate采用的输入 目前,具有签名的方法: compute(gate:GATE,a:boolean,b:boolean):boolean 正确执行,但如
对象[]{incomminingarguments}
(varargs)参数继续执行该方法
在我的LogicGates
类中有一个名为compute()
的方法。该方法需要2到3个参数。第一个参数是gate,接下来的1或2是输入,具体取决于gate采用的输入
目前,具有签名的方法:
compute(gate:GATE,a:boolean,b:boolean):boolean
正确执行,但如果我使用
compute(gate:GATE,<VARARGS>:boolean):boolean
GateTest.java
public class GateTest {
public static void main(String[] args) {
StringBuffer[] rows = newStringBufferArray(6, "");
for (LogicGates.GATE g : LogicGates.GATE.values()) {
if (g.operands == 2)
rows = fillTable(g, rows, repeat(' ', 3));
}
for (StringBuffer row : rows) {
System.out.println(row);
}
}
private static final StringBuffer[] fillTable(final LogicGates.GATE gate,
StringBuffer[] buffer, String delimiter) {
int l = buffer.length - 1;
String name = gate.name();
String pad = repeat('-', name.length() + 1);
buffer[0].append(String.format(" A | B | %s %s", name, delimiter));
buffer[1].append(String.format("---+---+-%s%s", pad, delimiter));
for (byte b = 3; b >= 0; --b)
buffer[l - b].append(fillRow(gate, intToBool(b >> 1),
intToBool(b & 1), delimiter));
return buffer;
}
private static final String fillRow(final LogicGates.GATE gate, boolean a,
boolean b, String delimiter) {
return String.format(" %c | %c | %c%s %s", boolToChar(a),
boolToChar(b),
boolToChar(LogicGates.compute(gate, a, b)),
repeat(' ', gate.name().length() - 1), delimiter);
}
public static final StringBuffer[] newStringBufferArray(int size,
String initialValue) {
if (initialValue == null)
initialValue = "";
StringBuffer[] bufferArr = new StringBuffer[size];
for (int i = 0; i < size; i++)
bufferArr[i] = new StringBuffer(initialValue);
return bufferArr;
}
private static final String repeat(char ch, int count) {
StringBuilder sb = new StringBuilder();
while (sb.length() < count)
sb.append(ch);
return sb.toString();
}
private static final char boolToChar(final boolean bool) {
return bool ? 'T' : 'F';
}
private static final boolean intToBool(final int input) {
return intToBool((byte) input);
}
private static final boolean intToBool(final byte input) {
if (input < 0 || input > 1)
throw new IllegalArgumentException("Input must be 0 or 1");
return input == 1;
}
}
import java.lang.reflect.Method;
import java.util.Arrays;
@SuppressWarnings("unused")
public final class LogicGates {
public static enum GATE {
NOT("not", "Negation", 1), // .
AND("and", "Logical conjunction", 2), // .
OR("or", "Logical disjunction", 2), // .
NAND("nand", "Logical NAND", 2), // .
NOR("nor", "Logical NOR", 2), // .
XOR("xor", "Exclusive disjunction", 2), // .
XNOR("xnor", "Logical biconditional", 2), // .
XNOR_NAND("xnorNand", "XNOR using only NAND gates.", 2), // .
XNOR_NOR("xnorNor", "XNOR using only NOR gates.", 2), // .
IF_THEN("ifThen", "Material implication.", 2), // .
THEN_IF("thenIf", "Converse implication.", 2); // .
private String methodName, description;
int operands;
private GATE(String methodName, String description, int operands) {
this.methodName = methodName;
this.description = description;
this.operands = operands;
}
protected String methodName() {
return methodName;
}
protected int operands() {
return operands;
}
}
private LogicGates() {
throw new AssertionError();
}
private static final boolean not(boolean a) {
return !a;
}
private static final boolean and(final boolean a, final boolean b) {
return a && b;
}
private static final boolean or(final boolean a, final boolean b) {
return a || b;
}
private static final boolean nand(final boolean a, final boolean b) {
return not(and(a, b));
}
private static final boolean nor(final boolean a, final boolean b) {
return not(or(a, b));
}
private static final boolean xor(final boolean a, final boolean b) {
return or(and(a, not(b)), and(not(a), b));
}
private static final boolean xnor(final boolean a, final boolean b) {
return or(and(a, b), nor(a, b));
}
private static final boolean xnorNand(final boolean a, final boolean b) {
return nand(nand(nand(a, nand(a, b)), nand(b, nand(a, b))),
nand(nand(a, nand(a, b)), nand(b, nand(a, b))));
}
private static final boolean xnorNor(final boolean a, final boolean b) {
return nor(nor(a, nor(a, b)), nor(b, nor(a, b)));
}
private static final boolean ifThen(final boolean a, final boolean b) {
return or(and(a, b), not(a));
}
private static final boolean thenIf(final boolean a, final boolean b) {
return or(a, nor(a, b));
}
public static final boolean compute(GATE gate, boolean... values) {
boolean result = false;
if (values.length != gate.operands())
throw new IllegalArgumentException(String.format(
"%s gate requires %d inputs.", gate.name(), gate.operands));
try {
Class<?> c = Class.forName(LogicGates.class.getName());
Method method = null;
if (gate.operands() == 2)
method = c.getDeclaredMethod(gate.methodName(), boolean.class,
boolean.class);
else if (gate.operands() == 1) {
method = c.getDeclaredMethod(gate.methodName(), boolean.class);
} else {
method = null;
}
boolean[] args = Arrays.copyOfRange(values, 0, values.length);
result = (boolean) method.invoke(c, new Object[] { args });
} catch (Exception e) {
System.out.println(e.getMessage() + " " + e.getCause());
}
return result;
}
public static final boolean compute(GATE gate, boolean a, boolean b) {
boolean result = false;
try {
Class<?> c = Class.forName(LogicGates.class.getName());
Method method = null;
if (gate.operands() == 2)
method = c.getDeclaredMethod(gate.methodName(), boolean.class,
boolean.class);
else if (gate.operands() == 1) {
method = c.getDeclaredMethod(gate.methodName(), boolean.class);
} else {
method = null;
}
result = (boolean) method.invoke(c, a, b);
} catch (Exception e) {
System.out.println(e.getMessage() + " " + e.getCause());
}
return result;
}
}
public class ReflectTest {
private enum Gate {
NOT(SimpleGate.class),
AND(SimpleGate.class),
OR(SimpleGate.class),
XOR(SimpleGate.AdvancedGate.class);
private Class<?> clazz;
private Gate(Class<?> clazz) { this.clazz = clazz; }
public Class<?> clazz() { return clazz; }
}
public static boolean compute(Gate gate, Boolean... input) {
return (Boolean) Reflect.call(gate.clazz(),
gate.name().toLowerCase(), (Object[]) input);
}
public static void main(String[] args) {
Boolean not = compute(Gate.NOT, false);
Boolean and = compute(Gate.AND, true, true);
Boolean or = compute(Gate.OR, true, false);
Boolean xor = compute(Gate.XOR, true, false);
if (not && and && or && xor)
System.out.println("PASS");
else
System.out.println("FAIL");
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public abstract class Reflect {
public static final Object call(Class<?> clazz, String methodName, Object... varArgs) {
try {
Object invokee = null;
String className = clazz.getName();
int argc = varArgs.length;
Class<?>[] classList = new Class[argc];
StringBuffer varArgsStr = new StringBuffer();
for (int i = 0; i < argc; i++) {
Object argv = varArgs[i];
classList[i] = argv.getClass();
varArgsStr.append(argv.toString());
if (i < argc - 1) varArgsStr.append(',');
}
System.out.printf(">> Invoking %s.%s(%s)\n", className,methodName, varArgsStr);
Class<?> target = Class.forName(className);
Method method = target.getDeclaredMethod(methodName, classList);
int childIndex = className.indexOf('$');
if (childIndex > -1) {
String wrappingClassName = className.substring(0, childIndex);
Class<?> wrapper = Class.forName(wrappingClassName);
Object wrapperInstance = wrapper.newInstance();
Constructor<?> con = target.getDeclaredConstructor(wrapper);
invokee = con.newInstance(wrapperInstance);
} else {
boolean isStatic = Modifier.isStatic(method.getModifiers());
invokee = isStatic ? target : target.newInstance();
}
return method.invoke(invokee, varArgs);
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
}
public class SimpleGate {
public Boolean not(Boolean a) { return !a; }
public static Boolean and(Boolean a, Boolean b) { return a && b; }
public static Boolean or(Boolean a, Boolean b) { return a || b; }
public class AdvancedGate {
public Boolean xor(Boolean a, Boolean b) {
return or(and(not(a),b),and(a,not(b)));
}
}
}
公共类网关测试{
公共静态void main(字符串[]args){
StringBuffer[]行=newStringBufferArray(6,“”);
对于(LogicGates.GATE g:LogicGates.GATE.values()){
if(g.操作数==2)
行=填充表(g,行,重复(“”,3));
}
用于(StringBuffer行:行){
系统输出打印项次(行);
}
}
专用静态最终StringBuffer[]填充表(最终逻辑门.GATE门,
StringBuffer[]缓冲区,字符串分隔符){
int l=buffer.length-1;
字符串名称=gate.name();
字符串填充=重复('-',name.length()+1);
缓冲区[0]。追加(String.format(“A | B |%s%s”,名称,分隔符));
缓冲区[1]。追加(String.format(“--+--+-%s%s”,填充,分隔符));
对于(字节b=3;b>=0;--b)
缓冲区[l-b].append(填充行(gate,intToBool(b>>1)),
intToBool(b&1),分隔符);
返回缓冲区;
}
专用静态最终字符串填充行(最终逻辑门.GATE门,布尔值a,
布尔值(b,字符串分隔符){
返回字符串.format(“%c |%c |%c%s%s”,boolToChar(a),
布尔塔尔查(b),
boolToChar(LogicGates.compute(gate,a,b)),
重复(“”,gate.name().length()-1),分隔符);
}
公共静态最终StringBuffer[]newStringBufferArray(整数大小,
字符串初始值){
if(initialValue==null)
initialValue=“”;
StringBuffer[]bufferArr=新的StringBuffer[大小];
对于(int i=0;i1)
抛出新的IllegalArgumentException(“输入必须为0或1”);
返回输入==1;
}
}
LogicGates.java
public class GateTest {
public static void main(String[] args) {
StringBuffer[] rows = newStringBufferArray(6, "");
for (LogicGates.GATE g : LogicGates.GATE.values()) {
if (g.operands == 2)
rows = fillTable(g, rows, repeat(' ', 3));
}
for (StringBuffer row : rows) {
System.out.println(row);
}
}
private static final StringBuffer[] fillTable(final LogicGates.GATE gate,
StringBuffer[] buffer, String delimiter) {
int l = buffer.length - 1;
String name = gate.name();
String pad = repeat('-', name.length() + 1);
buffer[0].append(String.format(" A | B | %s %s", name, delimiter));
buffer[1].append(String.format("---+---+-%s%s", pad, delimiter));
for (byte b = 3; b >= 0; --b)
buffer[l - b].append(fillRow(gate, intToBool(b >> 1),
intToBool(b & 1), delimiter));
return buffer;
}
private static final String fillRow(final LogicGates.GATE gate, boolean a,
boolean b, String delimiter) {
return String.format(" %c | %c | %c%s %s", boolToChar(a),
boolToChar(b),
boolToChar(LogicGates.compute(gate, a, b)),
repeat(' ', gate.name().length() - 1), delimiter);
}
public static final StringBuffer[] newStringBufferArray(int size,
String initialValue) {
if (initialValue == null)
initialValue = "";
StringBuffer[] bufferArr = new StringBuffer[size];
for (int i = 0; i < size; i++)
bufferArr[i] = new StringBuffer(initialValue);
return bufferArr;
}
private static final String repeat(char ch, int count) {
StringBuilder sb = new StringBuilder();
while (sb.length() < count)
sb.append(ch);
return sb.toString();
}
private static final char boolToChar(final boolean bool) {
return bool ? 'T' : 'F';
}
private static final boolean intToBool(final int input) {
return intToBool((byte) input);
}
private static final boolean intToBool(final byte input) {
if (input < 0 || input > 1)
throw new IllegalArgumentException("Input must be 0 or 1");
return input == 1;
}
}
import java.lang.reflect.Method;
import java.util.Arrays;
@SuppressWarnings("unused")
public final class LogicGates {
public static enum GATE {
NOT("not", "Negation", 1), // .
AND("and", "Logical conjunction", 2), // .
OR("or", "Logical disjunction", 2), // .
NAND("nand", "Logical NAND", 2), // .
NOR("nor", "Logical NOR", 2), // .
XOR("xor", "Exclusive disjunction", 2), // .
XNOR("xnor", "Logical biconditional", 2), // .
XNOR_NAND("xnorNand", "XNOR using only NAND gates.", 2), // .
XNOR_NOR("xnorNor", "XNOR using only NOR gates.", 2), // .
IF_THEN("ifThen", "Material implication.", 2), // .
THEN_IF("thenIf", "Converse implication.", 2); // .
private String methodName, description;
int operands;
private GATE(String methodName, String description, int operands) {
this.methodName = methodName;
this.description = description;
this.operands = operands;
}
protected String methodName() {
return methodName;
}
protected int operands() {
return operands;
}
}
private LogicGates() {
throw new AssertionError();
}
private static final boolean not(boolean a) {
return !a;
}
private static final boolean and(final boolean a, final boolean b) {
return a && b;
}
private static final boolean or(final boolean a, final boolean b) {
return a || b;
}
private static final boolean nand(final boolean a, final boolean b) {
return not(and(a, b));
}
private static final boolean nor(final boolean a, final boolean b) {
return not(or(a, b));
}
private static final boolean xor(final boolean a, final boolean b) {
return or(and(a, not(b)), and(not(a), b));
}
private static final boolean xnor(final boolean a, final boolean b) {
return or(and(a, b), nor(a, b));
}
private static final boolean xnorNand(final boolean a, final boolean b) {
return nand(nand(nand(a, nand(a, b)), nand(b, nand(a, b))),
nand(nand(a, nand(a, b)), nand(b, nand(a, b))));
}
private static final boolean xnorNor(final boolean a, final boolean b) {
return nor(nor(a, nor(a, b)), nor(b, nor(a, b)));
}
private static final boolean ifThen(final boolean a, final boolean b) {
return or(and(a, b), not(a));
}
private static final boolean thenIf(final boolean a, final boolean b) {
return or(a, nor(a, b));
}
public static final boolean compute(GATE gate, boolean... values) {
boolean result = false;
if (values.length != gate.operands())
throw new IllegalArgumentException(String.format(
"%s gate requires %d inputs.", gate.name(), gate.operands));
try {
Class<?> c = Class.forName(LogicGates.class.getName());
Method method = null;
if (gate.operands() == 2)
method = c.getDeclaredMethod(gate.methodName(), boolean.class,
boolean.class);
else if (gate.operands() == 1) {
method = c.getDeclaredMethod(gate.methodName(), boolean.class);
} else {
method = null;
}
boolean[] args = Arrays.copyOfRange(values, 0, values.length);
result = (boolean) method.invoke(c, new Object[] { args });
} catch (Exception e) {
System.out.println(e.getMessage() + " " + e.getCause());
}
return result;
}
public static final boolean compute(GATE gate, boolean a, boolean b) {
boolean result = false;
try {
Class<?> c = Class.forName(LogicGates.class.getName());
Method method = null;
if (gate.operands() == 2)
method = c.getDeclaredMethod(gate.methodName(), boolean.class,
boolean.class);
else if (gate.operands() == 1) {
method = c.getDeclaredMethod(gate.methodName(), boolean.class);
} else {
method = null;
}
result = (boolean) method.invoke(c, a, b);
} catch (Exception e) {
System.out.println(e.getMessage() + " " + e.getCause());
}
return result;
}
}
public class ReflectTest {
private enum Gate {
NOT(SimpleGate.class),
AND(SimpleGate.class),
OR(SimpleGate.class),
XOR(SimpleGate.AdvancedGate.class);
private Class<?> clazz;
private Gate(Class<?> clazz) { this.clazz = clazz; }
public Class<?> clazz() { return clazz; }
}
public static boolean compute(Gate gate, Boolean... input) {
return (Boolean) Reflect.call(gate.clazz(),
gate.name().toLowerCase(), (Object[]) input);
}
public static void main(String[] args) {
Boolean not = compute(Gate.NOT, false);
Boolean and = compute(Gate.AND, true, true);
Boolean or = compute(Gate.OR, true, false);
Boolean xor = compute(Gate.XOR, true, false);
if (not && and && or && xor)
System.out.println("PASS");
else
System.out.println("FAIL");
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public abstract class Reflect {
public static final Object call(Class<?> clazz, String methodName, Object... varArgs) {
try {
Object invokee = null;
String className = clazz.getName();
int argc = varArgs.length;
Class<?>[] classList = new Class[argc];
StringBuffer varArgsStr = new StringBuffer();
for (int i = 0; i < argc; i++) {
Object argv = varArgs[i];
classList[i] = argv.getClass();
varArgsStr.append(argv.toString());
if (i < argc - 1) varArgsStr.append(',');
}
System.out.printf(">> Invoking %s.%s(%s)\n", className,methodName, varArgsStr);
Class<?> target = Class.forName(className);
Method method = target.getDeclaredMethod(methodName, classList);
int childIndex = className.indexOf('$');
if (childIndex > -1) {
String wrappingClassName = className.substring(0, childIndex);
Class<?> wrapper = Class.forName(wrappingClassName);
Object wrapperInstance = wrapper.newInstance();
Constructor<?> con = target.getDeclaredConstructor(wrapper);
invokee = con.newInstance(wrapperInstance);
} else {
boolean isStatic = Modifier.isStatic(method.getModifiers());
invokee = isStatic ? target : target.newInstance();
}
return method.invoke(invokee, varArgs);
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
}
public class SimpleGate {
public Boolean not(Boolean a) { return !a; }
public static Boolean and(Boolean a, Boolean b) { return a && b; }
public static Boolean or(Boolean a, Boolean b) { return a || b; }
public class AdvancedGate {
public Boolean xor(Boolean a, Boolean b) {
return or(and(not(a),b),and(a,not(b)));
}
}
}
import java.lang.reflect.Method;
导入java.util.array;
@抑制警告(“未使用”)
公共最终类逻辑门{
公共静态枚举门{
不(“不”,“否定”,1),/。
和(“AND”,“逻辑连词”,2),//。
或(“或”,“逻辑析取”,2),//。
NAND(“NAND”,“逻辑NAND”,2),/。
NOR(“NOR”,“逻辑NOR”,2),/。
异或(“异或”,“独占析取”,2),/。
XNOR(“XNOR”,“逻辑双条件”,2),/。
XNOR_NAND(“xnorNand”,“仅使用与非门的XNOR.”,2),//。
XNOR_NOR(“xnorNor”,“仅使用或非门的XNOR.”,2),//。
如果(如果),那么("如果","实质含义",2),。
然后如果(“thenIf”,“逆向含义”,2);/。
私有字符串methodName,description;
整数操作数;
专用门(字符串方法名、字符串描述、整数操作数){
this.methodName=methodName;
this.description=描述;
this.operands=操作数;
}
受保护的字符串methodName(){
返回方法名;
}
受保护的整数操作数(){
返回操作数;
}
}
专用逻辑门(){
抛出新的断言错误();
}
私有静态最终布尔值非(布尔值a){
返回!a;
}
私有静态最终布尔and(最终布尔a,最终布尔b){
返回a&b;
}
专用静态最终布尔or(最终布尔a,最终布尔b){
返回a | | b;
}
专用静态最终布尔nand(最终布尔a,最终布尔b){
不返回(和(a,b));
}
专用静态最终布尔nor(最终布尔a,最终布尔b){
不返回(或(a,b));
}
专用静态最终布尔异或(最终布尔a,最终布尔b){
返回或(和(a,不是(b))和(不是(a),b));
}
专用静态最终布尔xnor(最终布尔a,最终布尔b){
返回或(和(a,b),或(a,b));
}
专用静态最终布尔值xnorNand(最终布尔值a,最终布尔值b){
返回nand(nand(nand(a,nand(a,b)),nand(b,nand(a,b)),
nand(nand(a,nand(a,b)),nand(b,nand(a,b));
}
专用静态最终布尔xnorNor(最终布尔a,最终布尔b){
返回nor(nor(a,nor(a,b)),nor(b,nor(a,b)));
}
私有静态最终布尔值ifThen(最终布尔值a,最终布尔值b){
返回或(和(a,b),而不是(a));
}
私有静态最终布尔值thenIf(最终布尔值a,最终布尔值b){
返回或(a,或(a,b));
}
公共静态最终布尔计算(门、门、布尔值){
布尔结果=假;
if(values.length!=gate.operans())
抛出新的IllegalArgumentException(String.format(
“%s门需要%d个输入。”,gate.name(),gate.operans));
试一试{