How to return 2 variables of a function

Asked

Viewed 3,475 times

3

I am accessing a webservice, that has as return:

listProdutos[] -> List of all products or null when there are no products

When you lose access for some reason, you make an exception, in which case I need to return a second variable (flag) to let me know if this problem occurred or not:

Sample code:

    Public listProdutos[] boolean getProdutosWS(String prod){
    boolean flag=false
    try{
       listProdutos[] produtos = ws.getProdutos(prod)
       flag=true
       return produtos, flag;
    }catch(RemoteException ex){
       return null, flag=false;

    }
}

How to solve this problem?

  • Reserve the return position 0 for the flag.

  • What is the class structure listProdutos?

  • consists of 3 strings || constructors || get’s and set’s (you can tell!?)

  • 2

    If there is an exception, you should propagate it, this is not the right way to deal with it. If you want to insist I believe that the best way is to create a class just for this (since Java does not give many facilities) whose members will be this list of products and the flag, then in return you break up the class, ie, take each of the members and use as you like (play in variable, use in if, etc..).

  • @bigown I’ve been researching this and I’ve seen this option, but it seemed a little strange(create a class just for that!?) could you explain better that of propagating the exception? I tried to catch where I wanted but could not

  • 1

    @jsantos1991 I agree with you that it is strange but it is the solution if you want to insist on the error. At least in Java I see no other way to solve this. I insist that you must resolve this by letting the exception overflow into the method that knows how to treat the problem properly. What you’re trying to do is even stranger. See that answer that I gave and goes on all the links of her and the others you follow to learn more about exception (worth even what is not about Java).

  • @jsantos1991 You are not required to propagate communication exception. Carefully note this recommendation that you "should" propagate it. The way you are trying to do it is not necessarily a mistake.

  • @jsantos1991 read everything I’ve given you and then you tell me if you gain anything dealing with the exception before the moment you can do something with it and turn it into flag. If you win something real, if you can show that you have a plausible justification, go ahead, otherwise you’re doing over Engineering. Never treat an exception when you can’t do anything useful with it. This is a basic rule of exception.

Show 3 more comments

4 answers

6


If there is an exception, you should propagate it and let another method deal with the problem, this is not the right way to deal with it. You’ll have to deal with the problem, do it right or wrong.

If you want to insist, I believe that the best way is to create a class just for this (since Java does not give many facilities) whose members will be this list of products and the flag, then in return you break up the class, ie, take each of the members and use as you like (play in variable, use in if, etc..).

Note that I disagree with each line of this solution but it would be something more or less like this (the codes are not ready for use, it’s just a general idea):

public class Resultado {
    public boolean flag; //não faça isto, fiz só para simplificar
    public listProdutos[] produtos; //prefira usar métodos de acesso get e set
    public Resultado(listProdutos[] produtos, boolean flag) {
        this.produtos = produtos;
        this.flag = flag;
    }
}

public Resultado getProdutosWS() {
    try{
        listProdutos[] produtos = ws.getProdutos(prod)
        return new Resultado(produtos, true);
    }catch(RemoteException ex){
        return new Resultado(null, false);
    }
}

public static main() {
    Resultado lista = getProdutosWS();
    if (lista.flag) {
        System.out.println(lista.produtos[0]); //isto é só um exemplo de uso, nada que seja útil
    }
}

The more I look at this the more I find it strange. I think you should treat the exception, for this example, at main, something like:

public AlgumMetodoConsumidor(TipoDoWS ws, TipoDoProd prod) {
    try {
        listProdutos[] lista = ws.getProdutos(prod)();
        System.out.println(lista); //isto é só um exemplo de uso, nada que seja útil
    } catch (RemoteException ex) {
        //regra básica das exceções: você lida aqui com o problema porque é
        //aqui que você consegue lidar com ele.
        System.out.println("deu erro");
    }
}

Alternative to not having to create a specific class for this. The advantage would be that the class Resultado would be used for any site that needs to return a flag in addition to another return:

public class Resultado {
    public boolean flag; //não faça isto, fiz só para simplificar
    public Resultado(boolean flag) {
        this.flag = flag;
    }
}

public Resultado getProdutosWS(Resultado resultado) {
    try{
        listProdutos[] produtos = ws.getProdutos(prod)
        resultado.flag = true;
        return produtos;
    }catch(RemoteException ex){
        resultado.flag = false;
        return null;
    }
}

public static main() {
    Resultado resultado;
    listProdutos[] lista = getProdutosWS(resultado);
    if (resultado) {
        System.out.println(lista[0]); //isto é só um exemplo de uso, nada que seja útil
    }
}

I put in the Github for future reference.

On the other hand I do not know if it would not be enough to check whether the list is null. Of course, it depends on the situation.

  • Propagating or not the exception is a design decision - it is not possible to make a single recommendation that meets all cases. When a method delivers data obtained from a webservice, it is very common not to want to propagate communication exception. In these cases, this method can choose to simply return an empty collection. The use of the success flag is also not ruled out.

  • @Caffé you’re right but in this case what I wanted to do was really propagate the exception, I had tried to do it but without success, but with the links of the bigown fortunately I realized the meaning of the Throws so I added to the function header, and where I would receive the return as I already do the try...catch I no longer need to receive both values

  • @bigown if you can post an example of the use of throws or how to propagate the exception could mark your answer as sure, I already have my problem working is just for your answer to be complete...

  • 1

    @jsantos1991 already do, let me just finish a little thing here. Although I have already put the second example which is more or less what you need. Why if we eliminate the flag unnecessary, it seems that the whole method getProdutosWS becomes unnecessary.

  • @bigown yes I understand what you mean, and actually it is, in a way, because this way I can separate all communication from the webservice with the rest of the program (possibly it’s wrong) but it’s how I know how to do... I just wanted to make it clear that the solution was to add the Throws in the function and deal with the exception at the top level

  • In fact the Throws helps you be required to deal with the caller method but it is not mandatory. Have you tried it without using it? I’m not saying take it out, just add the information you can do without the clause Throws. Java culture is to use where useful.

Show 1 more comment

4

In Java, when you want a function to return multiple values, you must:

  • add these values to an object and then return them
  • or change an object that is passed to the function

In your case, you need to clearly define a class mostrar that might have needed fields.

public class Mostrar {
    private boolean flag = false;
    private List<String> produtos = null;

}

then returns your object

return new Teste(flag, produtos) ;

3

Not an answer per se. But a suggestion question. Here’s mine:

class ListProdutos{
    private boolean isFlag = false;
    public boolean getIsFlag(){ return isFLag; }
    // Construtor sobrecarregado definindo um objeto flag.
    // Supondo que o seu outro construtor tem parâmetros.
    // Esse construtor não faz mais nada, apenas define o flag. 
    public ListProdutos(){
        isFlag = true;
    }
     //Resto da classe...
}

The solution itself would be to create a field isFLag and overload a constructor to create an object flag.

Assuming there can be several types of error, you can later add a field public String flag; with the description of the error.

  • But then you change the context of the product list to address a code design problem.

3

It is not possible to have more than one return in a Java method. In . Net we use output parameters, but Java does not have this either.

You will have to create a different design for your solution.

One option is to retouch a complex object:

// encontre um nome mais significativo 
// para esta classe e seus atributos
class Resultado {

    Produto[] listProdutos;
    boolean requestSucesso;
}

Public listProdutos[] getProdutosWS(String prod){
    Resultado resultado = new Resultado();
    try{
        resultado.listProdutos[] produtos = ws.getProdutos(prod)
        resultado.requestSucesso = true;
        return resultado;
    }catch(RemoteException ex){
        resultado.requestSucesso = false;
        return resultado;
    }
}

Another option is not to make the exception treatment there but in the consumer of getProdutosWS. In this case, the consumer does not check a flag but only believes that if there was no exception, the method returned what it needed.

And a third option is to implement two methods in this class currently publishes the getProdutosWS. One method indicates success in the request and another method returns the products.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.