4y4z
Участник
Offline
Младший саппорт
|
|
« : 21-07-2008 19:59 » |
|
Итак есть класс: public class PostfixCalculator { private Vector postfixVector = null; private Integer result = 0; /** Создает новые экземпляры класса PostfixCalculator * * @param postfixVector объект класса <code>java.util.Vector</code>, * содержащий массив исходных данных в постфиксной форме. */ public PostfixCalculator(Vector postfixVector) { this.postfixVector = postfixVector; } /** Вычисляет значение выражения. * @return результат вычислений */ public Integer calculate() { //Integer result; Stack stack = new Stack(); PostfixElement temp = null; for(int i = 0; i < postfixVector.size(); i++) //здесь компилятор выдает ошибку NullPointerException { temp = (PostfixElement)postfixVector.get(i); if(temp.isNumber()) stack.push(temp); if(temp.isOperator()) { Integer y = ((PostfixElement)stack.pop()).getNumber(); Integer x = ((PostfixElement)stack.pop()).getNumber(); Integer res = solveOperation(x,y,temp.getOperatorType()); stack.push(new PostfixElement(res.toString(), 0)); } } result = ((PostfixElement)stack.pop()).getNumber(); return result; } /* Вычисляет результат каждой операции */ private Integer solveOperation(Integer x, Integer y, int operatorType) { Integer result=0; switch(operatorType) { case PostfixElementType.PLUS : result = x+y; break; case PostfixElementType.MINUS : result = x-y; break; case PostfixElementType.MULTIPLICATION : result = x*y; break; case PostfixElementType.DIVISION : result = x/y; break; } return result; }
}
Предполагаю что компилятор ругается именно на размер вектора как на нулевой. но класс в качестве параметра получает непустой вектор и соответственно его (вектора) размер ненулевой. Или не так? Как определить причину исключения?
|
|
|
Записан
|
Ищу работу. (разработка/тестирование/отладка)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 22-07-2008 03:26 » |
|
4y4z, требуется уточнение: всё же исключение после запуска программы или ошибка при компиляции ? И текст ошибки тоже в студию
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #2 : 22-07-2008 03:27 » |
|
ещё вот источник исключения может быть:
case PostfixElementType.DIVISION : result = x/y; break;
|
|
|
Записан
|
|
|
|
4y4z
Участник
Offline
Младший саппорт
|
|
« Ответ #3 : 22-07-2008 07:51 » |
|
Итак вот код класса Resulter, который использует предыдущий класс:
package jCalcClasses; import java.io.*; import java.util.*;
public class Resulter {
public static void main(String[] args)throws IOException { String inputFileName = "C:\\input.txt"; String outputFileName = "C:\\output.txt"; BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(inputFileName))); while(input.ready()){ String s; while((s = input.readLine())!= null){ StringTokenizer st = new StringTokenizer(s, "+-/*1234567890"); if(st.hasMoreTokens()){ BufferedWriter output = new BufferedWriter( new OutputStreamWriter(new FileOutputStream( outputFileName, true))); output.write(s + "=can't calculate"); output.newLine(); output.close(); } else { ConvertToPostfix stroka = new ConvertToPostfix(s); Vector virazh = stroka.convertToPostfix(); PostfixCalculator resultat = new PostfixCalculator(virazh); int znachenie = resultat.calculate(); // вот здесь Эклипс ругается при запуске на выполнение BufferedWriter output = new BufferedWriter( new OutputStreamWriter(new FileOutputStream( outputFileName, true))); output.write(s + "="+znachenie); output.newLine(); output.close(); } } } }
}
а вот и текст ошибки: Exception in thread "main" java.lang.NullPointerException at jCalcClasses.PostfixCalculator.calculate(PostfixCalculator.java:22) (1 комент см .выше в коде) at jCalcClasses.Resulter.main(Resulter.java:31)(2 комент см. выше в коде)
|
|
|
Записан
|
Ищу работу. (разработка/тестирование/отладка)
|
|
|
Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« Ответ #4 : 22-07-2008 09:04 » |
|
Алексей1153++, NullPointerException - он run-time, так что при компиляции возникать не может. 4y4z, наименование исключения говорит само за себя: в строке происходит обращение к ссылке на null. в той строке, в которой возникает исключение в твоем коде, ссылкой на null может быть только postfixVector. вероятно метод convertToPostfix() класса ConvertToPostfix возвращает null.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 22-07-2008 16:13 » |
|
Falsehood, так неизвестно ещё было, когда ошибка у автора возникла Вот я и предположил. А кроме того - эта ошибка ещё себя проявит, если оставить как x/y
|
|
|
Записан
|
|
|
|
4y4z
Участник
Offline
Младший саппорт
|
|
« Ответ #6 : 22-07-2008 18:44 » |
|
class ConvertToPostfix { private Vector postfixVector = null; private Vector infixVector = null; String infixStr; /** Создает новые экземпляры класса PostfixConverter * * @param str строка, содержащая выражение в инфиксной форме */ public ConvertToPostfix(String str) { infixStr = str; } /** Преобразует строку, записанную в инфиксной форме * в массив объектов PostfixElement в постфиксной форме. * * @return ссылку на объект класса <code>java.util.Vector</code>, * содежащий массив объектов PostfixElement в постфиксной форме. * * @exception IllegalArgumentException если была попытка * создать массив объектов с отрицательной длиной * * @exception UnrecognizableElementException если невозможно * распознать новый элемент * * @exception IncorrectTypeException если была попытка вызвать * один из методов класса PostfixElement, который недопустим для * данного экземпляра класса. Например, к экземпляру класса PostfixElement * не может быть применена функция getNumber(), если он содержит оператор.*/ public Vector convertToPostfix() throws IllegalArgumentException { infixVector = new Vector(10, 5); return postfixVector; } /* Преобразует строку, записанную в инфиксной форме в массив объектов PostfixElement в инфиксной форме */ private void parseStr(String str) { StringTokenizer st = new StringTokenizer(infixStr, "+-*/", true); PostfixElement currentElement = null; PostfixElement previousElement = null; int tokenIndex = 0; int curIndex = 0; boolean firstElement = true; while(st.hasMoreTokens()) { String currentToken = st.nextToken(); tokenIndex = str.indexOf(currentToken, curIndex); currentElement = new PostfixElement(currentToken, tokenIndex); if(firstElement) { if(currentElement.isOperator() && ((currentElement.getOperatorType() == PostfixElementType.MINUS) || (currentElement.getOperatorType() == PostfixElementType.PLUS))) currentToken += st.nextToken(); tokenIndex = str.indexOf(currentToken, curIndex); currentElement = new PostfixElement(currentToken, tokenIndex); firstElement = false; } infixVector.add(currentElement); curIndex = tokenIndex + currentToken.length(); previousElement = currentElement; } } /* Преобразует массив объектов PostfixElement, записанный в инфиксной форме в массив объектов PostfixElement в постфиксной форме.*/ private void convert() throws IllegalArgumentException { postfixVector = new Vector(infixVector.size()); int curIndex = 0; PostfixElement curElement = null; Stack s = new Stack(); s.push(new PostfixElement("(", 0)); infixVector.add(new PostfixElement(")", 0)); while(s.isEmpty() == false) { curElement = (PostfixElement)infixVector.get(curIndex); curIndex++; if(curElement.isNumber()) { postfixVector.add(curElement); continue; } if(curElement.isOperator()) { while(true) { PostfixElement peekOperator = (PostfixElement)s.peek(); if(peekOperator.getOperatorPriority() >= curElement.getOperatorPriority()) postfixVector.add(s.pop()); else break; } s.push(curElement); continue; } } }
/* Удаляет пробелы из строки str. Возвращает строку без пробелов */ private String removeSpaces(String str) { StringTokenizer st = new StringTokenizer(str); StringBuffer temp = new StringBuffer(str.length()); while(st.hasMoreTokens()) { temp.append(st.nextToken()); } return temp.toString(); } /*Используется для отладки. На работу программы не влияет.*/ public String VectorDump(String name) { StringBuffer retValue = new StringBuffer(); Iterator vectorIterator = null; if(name.equals("infix")) vectorIterator = infixVector.iterator(); if(name.equals("postfix")) vectorIterator = postfixVector.iterator(); if(vectorIterator != null) while(vectorIterator.hasNext()) { retValue.append(vectorIterator.next() + " "); } return retValue.toString(); }
}
вот класс, который создает вектор, размер которого вроде как ноль. но он (вектор) в классе ConvertToPostfix создается непустым. или я не прав?. 4y4z, оборачивай код тегами [code]...[/code] - и читаться будет лучше, и искажений в тексте можно будет не бояться.
|
|
« Последнее редактирование: 22-07-2008 19:14 от RXL »
|
Записан
|
Ищу работу. (разработка/тестирование/отладка)
|
|
|
4y4z
Участник
Offline
Младший саппорт
|
|
« Ответ #7 : 22-07-2008 19:29 » |
|
=) Спасибо за подсказку по поводу тегов. Совсем вылетело из головы. Собственно все классы, код которых приведен, отвечают за расчет выражения записанного в строку с использованием ОПН. Вышеупомянутый класс как раз и отвечает за превращение в постфиксное выражение. Причем при создании экземпляра Эклипс не выдает ошибки, а вот при Run выдает ошибку, которая указана в теме.
|
|
|
Записан
|
Ищу работу. (разработка/тестирование/отладка)
|
|
|
4y4z
Участник
Offline
Младший саппорт
|
|
« Ответ #8 : 22-07-2008 19:30 » |
|
Falsehood, так неизвестно ещё было, когда ошибка у автора возникла Вот я и предположил. А кроме того - эта ошибка ещё себя проявит, если оставить как x/y то есть необходимо выполнить перехват исключений?
|
|
|
Записан
|
Ищу работу. (разработка/тестирование/отладка)
|
|
|
RXL
|
|
« Ответ #9 : 22-07-2008 19:40 » |
|
4y4z, если потенциально y может иметь нулевое значение, то ошибка рано или поздно себя проявит.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 22-07-2008 21:42 » |
|
4y4z, исключение не надо - число целое, перед делением проверь на 0, если да - результат бесконечности (~максимальное значение для типа)
|
|
|
Записан
|
|
|
|
4y4z
Участник
Offline
Младший саппорт
|
|
« Ответ #11 : 23-07-2008 05:51 » |
|
Возвращаясь к вектору, который мы получаем с помощью класса ConvertToPostfiх: ConvertToPostfix stroka = new ConvertToPostfix(s); Vector virazh = stroka.convertToPostfix(); // Собственно вот он и есть этот вектор. Он то у меня непустой. PostfixCalculator resultat = new PostfixCalculator(virazh); int znachenie = resultat.calculate(); // вот здесь Эклипс ругается при запуске на выполнение Есть еще какие-нибудь предположения у более опытных участников форума?
|
|
|
Записан
|
Ищу работу. (разработка/тестирование/отладка)
|
|
|
Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« Ответ #12 : 23-07-2008 11:11 » |
|
4y4z, int znachenie = resultat.calculate(); // вот здесь Эклипс ругается при запуске на выполнение
как именно ругается? если все так же, NullPointerException-ом, там ничего другого и быть не может: public Vector convertToPostfix() throws IllegalArgumentException { infixVector = new Vector(10, 5); return postfixVector; }
возвращает null сразу после создания, этот null передается в конструктор PostfixCalculator и используется в методе calculate() в форуме можно очень долго спрашивать где ошибка в твоем коде. гораздо эффективней вставить вывод значений переменных в консоль в некоторых контрольных точках.
|
|
« Последнее редактирование: 23-07-2008 11:19 от Falsehood »
|
Записан
|
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #13 : 20-10-2008 08:47 » |
|
Есть еще два очень дельных совета. Везде, где _может_ возникнуть NPE и он не желателен - делай проверку if (object == null) {/*do something default*/}
А вообще - чаще пиши UnitTest, они тебе очень сильно облегчат жизнь!!! Даже в самых сложных тестах всегда быстрее разобраться, чем в кажущейся тривиальной программе
|
|
|
Записан
|
|
|
|
Вахмурка
Помогающий
Offline
Пол:
Программист
|
|
« Ответ #14 : 22-10-2008 11:16 » |
|
Самое интересное что механизм исключений был для того и придуман, что бы не делать множества проверок в программе. Я неоднакратно успешкно искал глюки в программах только руководствуясь распечаткой стека в консоли. Почему сдесь так не сделать? А вот тесты вещь полезная.
|
|
|
Записан
|
Программа – это мысли спрессованные в код.
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #15 : 22-10-2008 12:04 » |
|
Может, ты напишешь стек сюда? Если ты не хочешь решать эту проблему самостоятельно
|
|
|
Записан
|
|
|
|
npak
|
|
« Ответ #16 : 22-10-2008 14:36 » |
|
4y4z, что вам не понятно? У вас черным по серому написано в методе convertToPostfix() Глядим на вторую строку и видим private Vector postfixVector = null;
Что написали, то и получили.
|
|
|
Записан
|
|
|
|
4y4z
Участник
Offline
Младший саппорт
|
|
« Ответ #17 : 23-10-2008 05:49 » |
|
Да я в принципе уже через отладку все сам просмотрел и исправил, но то что в последние два дня столько полезных советов получил все равно спасибо. Тему можно закрыть, всем спасибо.
|
|
|
Записан
|
Ищу работу. (разработка/тестирование/отладка)
|
|
|
|