Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: решениепроблемы с NullPointerException  (Прочитано 33776 раз)
0 Пользователей и 1 Гость смотрят эту тему.
4y4z
Участник

ru
Offline 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;
    }

}


Предполагаю что компилятор ругается именно на размер вектора как на нулевой. но класс в качестве параметра получает непустой вектор и соответственно его (вектора) размер ненулевой. Или не так? Как определить причину исключения?
Записан

Ищу работу. (разработка/тестирование/отладка)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 22-07-2008 03:26 » 

4y4z, требуется уточнение: всё же исключение после запуска программы или ошибка при компиляции ? И текст ошибки тоже в студию
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 22-07-2008 03:27 » 

ещё вот источник исключения может быть:

case PostfixElementType.DIVISION : result = x/y; break;
Записан

4y4z
Участник

ru
Offline Offline
Младший саппорт


« Ответ #3 : 22-07-2008 07:51 » new

Итак вот код класса 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
Молодой специалист

ru
Offline Offline
Пол: Женский
не может быть


« Ответ #4 : 22-07-2008 09:04 » 

Алексей1153++, NullPointerException - он run-time, так что при компиляции возникать не может.
4y4z, наименование исключения говорит само за себя: в строке происходит обращение к ссылке на null. в той строке, в которой возникает исключение в твоем коде, ссылкой на null может быть только postfixVector. вероятно метод convertToPostfix() класса ConvertToPostfix возвращает null.
Записан

Славная трава...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 22-07-2008 16:13 » 

Falsehood, так неизвестно ещё было, когда ошибка у автора возникла Улыбаюсь Вот я и предположил. А кроме того - эта ошибка ещё себя проявит, если оставить как x/y
Записан

4y4z
Участник

ru
Offline 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
Участник

ru
Offline Offline
Младший саппорт


« Ответ #7 : 22-07-2008 19:29 » 

=) Спасибо за подсказку по поводу тегов. Совсем вылетело из головы. Собственно все классы, код которых приведен, отвечают за расчет выражения записанного в строку с использованием ОПН. Вышеупомянутый класс как раз и отвечает за превращение в постфиксное выражение. Причем при создании экземпляра Эклипс не выдает ошибки, а вот при Run  выдает ошибку, которая указана в теме.
Записан

Ищу работу. (разработка/тестирование/отладка)
4y4z
Участник

ru
Offline Offline
Младший саппорт


« Ответ #8 : 22-07-2008 19:30 » 

Falsehood, так неизвестно ещё было, когда ошибка у автора возникла Улыбаюсь Вот я и предположил. А кроме того - эта ошибка ещё себя проявит, если оставить как x/y
то есть необходимо выполнить перехват исключений?
Записан

Ищу работу. (разработка/тестирование/отладка)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 22-07-2008 19:40 » 

4y4z, если потенциально y может иметь нулевое значение, то ошибка рано или поздно себя проявит.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 22-07-2008 21:42 » 

4y4z, исключение не надо - число целое, перед делением проверь на 0, если да - результат бесконечности (~максимальное значение для типа)
Записан

4y4z
Участник

ru
Offline 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
Молодой специалист

ru
Offline 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 » Записан

Славная трава...
.
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 20-10-2008 08:47 » 

Есть еще два очень дельных совета.
Везде, где _может_ возникнуть NPE и он не желателен -  делай проверку if (object == null) {/*do something default*/}

А вообще - чаще пиши UnitTest, они тебе очень сильно облегчат жизнь!!! Даже в самых сложных тестах всегда быстрее разобраться, чем в кажущейся тривиальной программе
Записан
Вахмурка
Помогающий

ru
Offline Offline
Пол: Мужской
Программист


WWW
« Ответ #14 : 22-10-2008 11:16 » 

 Самое интересное что механизм исключений был для того и придуман, что бы не делать множества проверок в программе. Я неоднакратно  успешкно искал глюки в программах только руководствуясь распечаткой стека в консоли. Почему сдесь так не сделать?     А вот тесты вещь полезная.
Записан

Программа – это мысли спрессованные в код.
.
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 22-10-2008 12:04 » 

Может, ты напишешь стек сюда? Если ты не хочешь решать эту проблему самостоятельно
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 22-10-2008 14:36 » 

4y4z, что вам не понятно? У вас черным по серому написано в методе convertToPostfix()
Код:
        return postfixVector;

Глядим на вторую строку и видим
Код:
private Vector postfixVector = null;

Что написали, то и получили.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
4y4z
Участник

ru
Offline Offline
Младший саппорт


« Ответ #17 : 23-10-2008 05:49 » 

Да я в принципе уже через отладку все сам просмотрел и исправил, но то что в последние два дня столько полезных советов получил все равно спасибо. Тему можно закрыть, всем спасибо.
Записан

Ищу работу. (разработка/тестирование/отладка)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines