Retorno de função não se concatena com String

Criei uma objeto para manipular uma pilha, mas tento contenar o o retorno da funçao Desempilha com uma variável de tipo String e essa apenas retorna um valor null.
Este é meu código.

package notacaopolonesa2;


class pilha{
    int max = 10, topo = 0;
       
    String[] elem = new String[max];
    
    boolean cheia(){
        if( topo == max )return true;
        else return false;
    }
    
    boolean vazia(){
        if( topo == 0 )return true;
        else return false;
    }
    
    //empilha um valor como uma string
    void empilha(String x){
        elem[topo] = x;
        topo = topo + 1;
        
    }
    
    //desempilha a quantidade de elementos solicitados
    String desempilha(int x){
        String retorno = elem[topo];
        topo = topo - x;
        return retorno;
        
    }
    
    void mostrapilha(){
      if(this.vazia()==true) System.out.println("Pilha vazia..");
      else{
        for(int i = topo-1; i >= 0; i--){
            System.out.print(elem[i]);
        }
      }
    }
}
/**
 *
 * @author jubei
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        
        pilha NovaPilha = new pilha();
        String expressao = new String();
        String resultado = new String();
        
        
        expressao = "2+3";
        
        for(int i = 0;i<expressao.length();i++){
            
           if(expressao.charAt(i)=='+'){
               NovaPilha.empilha(String.valueOf(expressao.charAt(i)));
           }
        }
        
        NovaPilha.mostrapilha();
        resultado = resultado + (NovaPilha.desempilha(1));
        System.out.print(resultado);
    }

}

Agradeço a atenção.

Cuidado - topo está apontando para o topo da pilha, ou para um elemento depois? O método “desempilha” aparentemente está pegando um elemento depois do topo da pilha (olhe o método “empilha”).

mudei o codigo do empilha, mas continua dando problema.

package notacaopolonesa2;


class pilha{
    int max = 10, topo = 0;
       
    String[] elem = new String[max];
    
    boolean cheia(){
        if( topo == max )return true;
        else return false;
    }
    
    boolean vazia(){
        if( topo == 0 )return true;
        else return false;
    }
    
    //empilha um valor como uma string
    void empilha(String x){
        topo = topo + 1;
        elem[topo] = x;
        
        
    }
    
    //desempilha a quantidade de elementos solicitados
    String desempilha(int x){
        String retorno = elem[topo];
        topo = topo - x;
        return retorno;
        
    }
    
    void mostrapilha(){
      if(this.vazia()==true) System.out.println("Pilha vazia..");
      else{
        for(int i = topo-1; i >= 0; i--){
            System.out.print(elem[i]);
        }
      }
    }
}
/**
 *
 * @author jubei
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        
        pilha NovaPilha = new pilha();
        String expressao = new String();
        String resultado = new String();
        
        
        expressao = "2+3";
        
        for(int i = 0;i<expressao.length();i++){
            
           if(expressao.charAt(i)=='+'){
               NovaPilha.empilha(String.valueOf(expressao.charAt(i)));
           }
        }
        
        //NovaPilha.mostrapilha();
        resultado = resultado + (NovaPilha.desempilha(1));
        System.out.print(resultado);
    }

}

Qual é o erro que dá?

Poste o erro que poderemos ajudar…

package notacaopolonesa2;


class pilha{
    int max = 100, topo = 0;
       
    String[] elem = new String[max];
    
    boolean cheia(){
        if( topo == max )return true;
        else return false;
    }
    
    boolean vazia(){
        if( topo == 0 )return true;
        else return false;
    }
    
    //empilha um valor como uma string
    void empilha(String x){
        topo = topo + 1;
        elem[topo] = x;
        
        
    }
    
    //desempilha a quantidade de elementos solicitados
    String desempilha(int x){
        String retorno = elem[topo];
        topo = topo - x;
        return retorno;
        
    }
    
    void mostrapilha(){
      if(this.vazia()==true) System.out.println("Pilha vazia..");
      else{
        for(int i = topo; i >= 0; i--){
            System.out.print(elem[i]);
        }
      }
    }
}
/**
 *
 * @author jubei
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        
        pilha NovaPilha = new pilha();
        String expressao = new String();
        String resultado = new String();
        
        
        expressao = "2+3";
        
        for(int i = 0;i<expressao.length();i++){
            
           if(expressao.charAt(i)=='+'){
               NovaPilha.empilha(String.valueOf(expressao.charAt(i)));
           }
           else{
               resultado = resultado + NovaPilha.desempilha(i);
           }
               
        }
        
      // NovaPilha.mostrapilha();
        resultado = resultado + (NovaPilha.desempilha(1));
        System.out.println(resultado);
    }

}

init:
deps-jar:
Compiling 1 source file to C:\Users\jubei\Documents\NetBeansProjects\NotacaoPolonesa2\build\classes
compile-single:
run-single:
Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: -1
at notacaopolonesa2.pilha.desempilha(Main.java:34)
at notacaopolonesa2.Main.main(Main.java:80)
Java Result: 1
CONSTRUÍDO COM SUCESSO (tempo total: 0 segundos)

Vc chegou a fazer um teste de mesa com o seu código? O erro é bem simples.
São feitas 3 iterações no seu for(int i = 0; i < expressao.length(); i++). Depois de cada iteração o sistema fica assim:

1ª desempilha : topo = 0 : elem[topo] = null; 2ª empilha : topo = 1 : elem[topo] = +; 3ª desempilha : topo = 0 : elem[topo] = null;

Daí vc vai e chama o método desempilha de novo em resultado = resultado + novaPilha.desempilha(1), e aqui acontece o teu erro, pq o seu topo foi definido como 0 na última iteração, passando 1 agora vc transforma ele em -1, tentando com isso pegar uma posição inexistente no array elem[].