我遇到反射問題以計算用戶傳遞了多少個參數,並將參數的長度與預期計數進行比較。如果滿足此要求,則繼續執行方法調用程序的Object[] { incommingArguments }
(可變參數)參數。使用可變參數的Java反射調用方法
我在我的LogicGates
類中有一個名爲compute()
的方法。該方法需要2到3個參數。第一個參數是門,下一個1或2是輸入,取決於門的輸入。
目前,帶有簽名的方法:
compute(gate:GATE,a:boolean,b:boolean):boolean
正確執行,但如果我用
compute(gate:GATE,<VARARGS>:boolean):boolean
簽名,然後我的代碼中斷。我正在使用我在這裏找到的可變參數的邏輯:StackOverflow: Invoke method with an array parameter using reflection。
這兩種方法都可以在我的問題結尾的LogicGates.java底部找到。
輸出
A | B | AND A | B | OR A | B | NAND A | B | NOR A | B | XOR A | B | XNOR A | B | XNOR_NAND A | B | XNOR_NOR A | B | IF_THEN A | B | THEN_IF
---+---+----- ---+---+---- ---+---+------ ---+---+----- ---+---+----- ---+---+------ ---+---+----------- ---+---+---------- ---+---+--------- ---+---+---------
T | T | T T | T | T T | T | F T | T | F T | T | F T | T | T T | T | T T | T | T T | T | T T | T | T
T | F | F T | F | T T | F | T T | F | F T | F | T T | F | F T | F | F T | F | F T | F | F T | F | T
F | T | F F | T | T F | T | T F | T | F F | T | T F | T | F F | T | F F | T | F F | T | T F | T | F
F | F | F F | F | F F | F | T F | F | T F | F | F F | F | T F | F | T F | F | T F | F | T F | F | T
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;
}
}
LogicGates.java
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;
}
}
不變量參數得到的待遇作爲一個數組? – MadProgrammer
它們應該被自動轉換爲Object [],這是Sun(現在的Oracle)告訴我的向後兼容性。 –
「代碼中斷」是什麼意思? – chrylis