Итак, вот в чем проблема. Я пытаюсь использовать отражение в Java, чтобы определить тип «представления» для вывода на лист Excel через объявления упорядоченного метода. (упорядоченно численно)Ошибка Spooky Java Reflection
, и теоретически это должно работать нормально, и это точно.
Проблема в том, что отражающий метод, по-видимому, случайно решает работать иногда, а не другие. Он не бросает исключение, он находит имена методов без каких-либо проблем, но как только он попадает в логическую проверку для того, запускается метод с соответствующим тегом, он иногда останавливается при j = 5. Вот код метод уточнение:
public boolean objectWriter(List<Object> input, String sheetName, int startingRow, String tag){
ArrayList<Object> myList = new ArrayList<>();
jxl.write.Number number;
Label label;
//This is just an internal counter since we're using a for-each loop.
int j;
try{
for (int i = 0; i < input.size(); i++){
j = 0;
//we want to iterate over all of the available methods in the given class with reflection
for (Method m: input.get(i).getClass().getMethods()){
//Check to see if the method name has our requested tag, plus the appropriate counter
//tacked on, and ZERO parameters, in our case.
myLog.debug("this is our boolean check: " + m.getName().startsWith((tag + j)));
if (m.getName().startsWith((tag + j))){
myLog.debug("m.getname inside: " + m.getName());
//Invoke the method, give it's return value to r (return)
final Object r = m.invoke(input.get(i));
//Since we defined in the requirements of this class that it must be a string
//those types of methods returned, this works just fine, just case it to
//String (Since String extends object) and call it a day.
if (isNumeric((String)r)){
//if it's a number, make a number object out of it.
number = new jxl.write.Number(j, startingRow + i
, Double.parseDouble((String)r)
, buildNumberFormat((String)r));
myList.add(number);
}else{
label = new Label(j,startingRow + i,(String)r);
myList.add(label);
}
j++;
}
}
}
}catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex){
myLog.error("There was an error working through the point class with reflection.", ex);
return false;
}
boolean successfulWrite = myExcelWriter.writeInformation(myList, sheetName);
myExcelWriter.resizeColumns(18, sheetName);
return successfulWrite;
}
Итак, как вы можете видеть выше, он рефлекторно ищет вызывающий определенный «тег» в именах методов, а также ряд. так что, если я был метод что-то вроде:
public String get0(){}
public String get1(){}
public String get2(){}
и т.д. и т.п., и я дал этот метод тег «получить» было бы вытащить все три из этих методов в указанном порядке. Кроме того, он определяется в требованиях использования этого конкретного метода для возвращаемых значений для всех, как строк, так что это не проблема, я уверен. странная часть, я не могу понять, почему логический контроль на линии if (m.getName().startsWith((tag + j)))
бы начать неудачу при у = 5 ИНОГДА
Во всяком случае, если у кого есть какие-либо идеи, я действительно ценю это. Я довольно застрял здесь.
Следует также отметить, что j = 5 каждый раз будет использоваться для предложения данных, которое я дал ему. Что выделяется для меня как нечто большее, чем совпадение, но я не вижу в этом ничего плохого.
EDIT
Стоит также ничего такого, что вероятность этого работает точно так, как ожидалось (вытаскивая все правильно перечисленных методов, и т.д.) значительно увеличивает (близко к 99% рабочий), если я запустить операцию на 'm' перед булевой проверкой. Например, как я распечатываю это логическое выражение непосредственно перед фактическим утверждением? что заставило его работать почти каждый раз. Но это, безусловно, не может быть решением.
EDIT # 2 В соответствии с просьбой, я пошел вперед и переместил Println в журнал отладки, это урезанная версия, но она по существу повторяет узор в 29 раз, также интересно, мне кажется, что если я посылаю выход на мой регистратор, а не на консоль, что вышеупомянутая вероятность успеха идет вниз к тому, что она без него ... странно ...
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,881 DEBUG [root] this is our boolean check: false
09:02:45,882 DEBUG [root] this is our boolean check: false
09:02:45,882 DEBUG [root] this is our boolean check: false
09:02:45,882 DEBUG [root] this is our boolean check: false
09:02:45,882 DEBUG [root] this is our boolean check: false
09:02:45,882 DEBUG [root] this is our boolean check: true
09:02:45,882 DEBUG [root] m.getname inside: xGet0Label
09:02:45,882 DEBUG [root] this is our boolean check: true
09:02:45,882 DEBUG [root] m.getname inside: xGet1MD
09:02:45,882 DEBUG [root] this is our boolean check: true
09:02:45,882 DEBUG [root] m.getname inside: xGet2Easting
09:02:45,882 DEBUG [root] this is our boolean check: true
09:02:45,882 DEBUG [root] m.getname inside: xGet3Northing
09:02:45,882 DEBUG [root] this is our boolean check: true
09:02:45,882 DEBUG [root] m.getname inside: xGet4TVD
09:02:45,882 DEBUG [root] this is our boolean check: true
09:02:45,882 DEBUG [root] m.getname inside: xGet5Date
09:02:45,882 DEBUG [root] this is our boolean check: false
09:02:45,882 DEBUG [root] this is our boolean check: false
09:02:45,882 DEBUG [root] this is our boolean check: false
09:02:45,882 DEBUG [root] this is our boolean check: false
09:02:45,882 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,883 DEBUG [root] this is our boolean check: false
09:02:45,884 DEBUG [root] this is our boolean check: false
09:02:45,884 DEBUG [root] this is our boolean check: false
09:02:45,884 DEBUG [root] this is our boolean check: false
09:02:45,884 DEBUG [root] this is our boolean check: false
09:02:45,884 DEBUG [root] this is our boolean check: true
09:02:45,884 DEBUG [root] m.getname inside: xGet0Label
09:02:45,884 DEBUG [root] this is our boolean check: true
09:02:45,884 DEBUG [root] m.getname inside: xGet1MD
09:02:45,884 DEBUG [root] this is our boolean check: true
09:02:45,884 DEBUG [root] m.getname inside: xGet2Easting
09:02:45,884 DEBUG [root] this is our boolean check: true
09:02:45,884 DEBUG [root] m.getname inside: xGet3Northing
09:02:45,884 DEBUG [root] this is our boolean check: true
09:02:45,884 DEBUG [root] m.getname inside: xGet4TVD
09:02:45,884 DEBUG [root] this is our boolean check: true
09:02:45,884 DEBUG [root] m.getname inside: xGet5Date
Нам будет сложно помочь вам с частью кода, но эта часть кода содержит вещи, которые нам действительно не нужны. Было бы намного проще помочь вам, если бы вы могли предоставить короткую, но полную программу, демонстрирующую проблему. Кроме того, учитывая, что у вас есть ведение журнала, это поможет, если вы покажете журналы ... –
Работая спорадически, я поставил бы под сомнение проблемы с потоками. У вас нет синхронизации по этому методу. myExcelWriter выглядит как общий, изменяемый элемент данных. Если да, посмотрите, является ли это основной причиной. – duffymo
@duffymo Я согласен, это похоже на проблему с потоками, но это все работает с потоком основного приложения (javafx application). Если java не искроет новый поток для рефлексивного вызова, о котором я не знал, я не вижу, что это проблема. Jon skeet - к сожалению, это относительно нетривиальная задача придумать пример поддержки, который имеет те же характеристики. Вероятно, этот метод содержит около 2000 строк кода поддержки. Возможно, у меня может быть некоторое время спустя, чтобы попытаться взломать что-то вместе, чтобы воспроизвести это поведение в небольшом масштабе. – WillBD