Allexj
Allexj

Reputation: 1487

Error using generic return type (incompatible types: cannot be converted to T)

public class Main{
    private MyQueue queue = null;
    private MyStack stack = null;
    private MyList list = null;

    public static void main(String args[]){
        Main m = new Main();
        m.run();
    }
    
    public void run(){
        // only one data structure is not null.
        // for example, let's suppose that it's queue
        this.queue = new MyQueue();
        
        int intToAdd = 6;   // I want to add this number
        this.selectStruct().insert(intToAdd);       // I want to invoke the "insert" method of the current data structure in use
    }
    
    private <T> T selectStruct(){       // this should check with data structure is in use (so which of them is not null) and then return the reference
        if (this.queue!=null){
            return this.queue;
        }
        if (this.stack!=null){
            return this.stack;
        }
        if (this.list!=null){
            return this.list;
        }
    }
}

I want to use this method called selectStruct to select the current data structure in use and return the reference. And from this reference then call insert that invokes the correct insert method of the correct class.

The problem is that I have several errors. I have never used generics, so I'm a bit confused.

$ javac Main.java
Main.java:22: error: incompatible types: MyQueue cannot be converted to T
                        return this.queue;
                                   ^
  where T is a type-variable:
    T extends Object declared in method <T>selectStruct()
Main.java:25: error: incompatible types: MyStack cannot be converted to T
                        return this.stack;
                                   ^
  where T is a type-variable:
    T extends Object declared in method <T>selectStruct()
Main.java:28: error: incompatible types: MyList cannot be converted to T
                        return this.list;
                                   ^
  where T is a type-variable:
    T extends Object declared in method <T>selectStruct()
Main.java:17: error: cannot find symbol
                this.selectStruct().insert(intToAdd);
                                   ^
  symbol:   method insert(int)
  location: class Object
4 errors

Upvotes: 1

Views: 1105

Answers (2)

haoyu wang
haoyu wang

Reputation: 1377

When you declare a method with a type parameter T (like private <T> T selectStruct()), you are saying that the user of this method can choose any type they want to use this method.

So in the body of selectStruct, you don't know which type the caller will use, and of course you can not return any specific type. That's why your every return clause like return this.queue; will produce an error.

Upvotes: 2

Michael Chatiskatzi
Michael Chatiskatzi

Reputation: 245

Let MyQueue, MyStack, and MyList implement the same interface containing the methods you want all your data structures to implement, e.g:

public interface IDataStructure {
    void insert(int intToAdd);
}

Your classes should then look like this:

public class MyQueue implements IDataStructure{

    @Override
    public void insert(int intToAdd) {
        // TODO 
    }

}

public class MyStack implements IDataStructure{

    @Override
    public void insert(int intToAdd) {
        // TODO 
    }

}

public class MyList implements IDataStructure{

    @Override
    public void insert(int intToAdd) {
        // TODO 
    }

}

Finally, you can modify your selectStruct() method to return an IDataStructure:

private IDataStructure selectStruct() {
    if (this.queue != null) {
        return this.queue;
    }
    if (this.stack != null) {
        return this.stack;
    }
    if (this.list != null) {
        return this.list;
    }
    return null;
}

Upvotes: 4

Related Questions