Java - Generics - Casting generic object in generic specified object doesn't work












1














I'm trying to resolve this apparently simple generic casting problem :



First, declaring this simple generic object :



public interface GenericObject<T> {}


Second, declaring this working interface :



public interface Generic { // I don't want to do Generic<T>

<T> void setGenericObject(GenericObject<T> obj);

}


Then, let's implements this interface :



public class GenericImpl implements Generic {

private GenericObject<String> genericObject; // This is needed

@Override
public <String> void setGenericObject(GenericObject<String> obj) {
genericObject = obj; // eclipse give me this error :
// Type mismatch: cannot convert from
// interfaces.GenericObject<String> to
// interfaces.GenericObject<java.lang.String>
}

}


How can I solve this error ?



Edit :



Actualy, the only way I have to solve this issue is to do this :



public class GenericImpl implements Generic {

private GenericObject<String> genericObject;

@SuppressWarnings("unchecked") // I don't realy like this
@Override
public <T> void setGenericObject(GenericObject<T> obj) {
genericObject = (GenericObject<String>) obj;
}

}









share|improve this question
























  • Sounds like an XY problem. <String> void is not doing what you think it's doing. You're defining a new generic type parameter using the identifier "String". It may as well say <FooBar> void. You should remove it. Only problem is that when you do, the method is not correctly overriding the method from the interface
    – Michael
    Nov 23 '18 at 13:46








  • 1




    The problem is that Generic specifies that any implementers should be able to implement setGenericObject for all values of T. Your implementation only works for strings, so it is not fulfilling the contract as defined by the interface. The best way to achieve what you want is to have Generic<T> and GenericImpl implements Generic<String> but you said you don't want to do that
    – Michael
    Nov 23 '18 at 13:48












  • plaese see stackoverflow.com/questions/7433279/…
    – chenzhongpu
    Nov 23 '18 at 13:53










  • Ok. @Michael Do you think there are any way to solve my problem without doing @SuppressWarning ?
    – MonkeyJLuffy
    Nov 23 '18 at 14:07


















1














I'm trying to resolve this apparently simple generic casting problem :



First, declaring this simple generic object :



public interface GenericObject<T> {}


Second, declaring this working interface :



public interface Generic { // I don't want to do Generic<T>

<T> void setGenericObject(GenericObject<T> obj);

}


Then, let's implements this interface :



public class GenericImpl implements Generic {

private GenericObject<String> genericObject; // This is needed

@Override
public <String> void setGenericObject(GenericObject<String> obj) {
genericObject = obj; // eclipse give me this error :
// Type mismatch: cannot convert from
// interfaces.GenericObject<String> to
// interfaces.GenericObject<java.lang.String>
}

}


How can I solve this error ?



Edit :



Actualy, the only way I have to solve this issue is to do this :



public class GenericImpl implements Generic {

private GenericObject<String> genericObject;

@SuppressWarnings("unchecked") // I don't realy like this
@Override
public <T> void setGenericObject(GenericObject<T> obj) {
genericObject = (GenericObject<String>) obj;
}

}









share|improve this question
























  • Sounds like an XY problem. <String> void is not doing what you think it's doing. You're defining a new generic type parameter using the identifier "String". It may as well say <FooBar> void. You should remove it. Only problem is that when you do, the method is not correctly overriding the method from the interface
    – Michael
    Nov 23 '18 at 13:46








  • 1




    The problem is that Generic specifies that any implementers should be able to implement setGenericObject for all values of T. Your implementation only works for strings, so it is not fulfilling the contract as defined by the interface. The best way to achieve what you want is to have Generic<T> and GenericImpl implements Generic<String> but you said you don't want to do that
    – Michael
    Nov 23 '18 at 13:48












  • plaese see stackoverflow.com/questions/7433279/…
    – chenzhongpu
    Nov 23 '18 at 13:53










  • Ok. @Michael Do you think there are any way to solve my problem without doing @SuppressWarning ?
    – MonkeyJLuffy
    Nov 23 '18 at 14:07
















1












1








1


1





I'm trying to resolve this apparently simple generic casting problem :



First, declaring this simple generic object :



public interface GenericObject<T> {}


Second, declaring this working interface :



public interface Generic { // I don't want to do Generic<T>

<T> void setGenericObject(GenericObject<T> obj);

}


Then, let's implements this interface :



public class GenericImpl implements Generic {

private GenericObject<String> genericObject; // This is needed

@Override
public <String> void setGenericObject(GenericObject<String> obj) {
genericObject = obj; // eclipse give me this error :
// Type mismatch: cannot convert from
// interfaces.GenericObject<String> to
// interfaces.GenericObject<java.lang.String>
}

}


How can I solve this error ?



Edit :



Actualy, the only way I have to solve this issue is to do this :



public class GenericImpl implements Generic {

private GenericObject<String> genericObject;

@SuppressWarnings("unchecked") // I don't realy like this
@Override
public <T> void setGenericObject(GenericObject<T> obj) {
genericObject = (GenericObject<String>) obj;
}

}









share|improve this question















I'm trying to resolve this apparently simple generic casting problem :



First, declaring this simple generic object :



public interface GenericObject<T> {}


Second, declaring this working interface :



public interface Generic { // I don't want to do Generic<T>

<T> void setGenericObject(GenericObject<T> obj);

}


Then, let's implements this interface :



public class GenericImpl implements Generic {

private GenericObject<String> genericObject; // This is needed

@Override
public <String> void setGenericObject(GenericObject<String> obj) {
genericObject = obj; // eclipse give me this error :
// Type mismatch: cannot convert from
// interfaces.GenericObject<String> to
// interfaces.GenericObject<java.lang.String>
}

}


How can I solve this error ?



Edit :



Actualy, the only way I have to solve this issue is to do this :



public class GenericImpl implements Generic {

private GenericObject<String> genericObject;

@SuppressWarnings("unchecked") // I don't realy like this
@Override
public <T> void setGenericObject(GenericObject<T> obj) {
genericObject = (GenericObject<String>) obj;
}

}






java generics methods generic-programming generic-method






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 13:53

























asked Nov 23 '18 at 13:41









MonkeyJLuffy

96112




96112












  • Sounds like an XY problem. <String> void is not doing what you think it's doing. You're defining a new generic type parameter using the identifier "String". It may as well say <FooBar> void. You should remove it. Only problem is that when you do, the method is not correctly overriding the method from the interface
    – Michael
    Nov 23 '18 at 13:46








  • 1




    The problem is that Generic specifies that any implementers should be able to implement setGenericObject for all values of T. Your implementation only works for strings, so it is not fulfilling the contract as defined by the interface. The best way to achieve what you want is to have Generic<T> and GenericImpl implements Generic<String> but you said you don't want to do that
    – Michael
    Nov 23 '18 at 13:48












  • plaese see stackoverflow.com/questions/7433279/…
    – chenzhongpu
    Nov 23 '18 at 13:53










  • Ok. @Michael Do you think there are any way to solve my problem without doing @SuppressWarning ?
    – MonkeyJLuffy
    Nov 23 '18 at 14:07




















  • Sounds like an XY problem. <String> void is not doing what you think it's doing. You're defining a new generic type parameter using the identifier "String". It may as well say <FooBar> void. You should remove it. Only problem is that when you do, the method is not correctly overriding the method from the interface
    – Michael
    Nov 23 '18 at 13:46








  • 1




    The problem is that Generic specifies that any implementers should be able to implement setGenericObject for all values of T. Your implementation only works for strings, so it is not fulfilling the contract as defined by the interface. The best way to achieve what you want is to have Generic<T> and GenericImpl implements Generic<String> but you said you don't want to do that
    – Michael
    Nov 23 '18 at 13:48












  • plaese see stackoverflow.com/questions/7433279/…
    – chenzhongpu
    Nov 23 '18 at 13:53










  • Ok. @Michael Do you think there are any way to solve my problem without doing @SuppressWarning ?
    – MonkeyJLuffy
    Nov 23 '18 at 14:07


















Sounds like an XY problem. <String> void is not doing what you think it's doing. You're defining a new generic type parameter using the identifier "String". It may as well say <FooBar> void. You should remove it. Only problem is that when you do, the method is not correctly overriding the method from the interface
– Michael
Nov 23 '18 at 13:46






Sounds like an XY problem. <String> void is not doing what you think it's doing. You're defining a new generic type parameter using the identifier "String". It may as well say <FooBar> void. You should remove it. Only problem is that when you do, the method is not correctly overriding the method from the interface
– Michael
Nov 23 '18 at 13:46






1




1




The problem is that Generic specifies that any implementers should be able to implement setGenericObject for all values of T. Your implementation only works for strings, so it is not fulfilling the contract as defined by the interface. The best way to achieve what you want is to have Generic<T> and GenericImpl implements Generic<String> but you said you don't want to do that
– Michael
Nov 23 '18 at 13:48






The problem is that Generic specifies that any implementers should be able to implement setGenericObject for all values of T. Your implementation only works for strings, so it is not fulfilling the contract as defined by the interface. The best way to achieve what you want is to have Generic<T> and GenericImpl implements Generic<String> but you said you don't want to do that
– Michael
Nov 23 '18 at 13:48














plaese see stackoverflow.com/questions/7433279/…
– chenzhongpu
Nov 23 '18 at 13:53




plaese see stackoverflow.com/questions/7433279/…
– chenzhongpu
Nov 23 '18 at 13:53












Ok. @Michael Do you think there are any way to solve my problem without doing @SuppressWarning ?
– MonkeyJLuffy
Nov 23 '18 at 14:07






Ok. @Michael Do you think there are any way to solve my problem without doing @SuppressWarning ?
– MonkeyJLuffy
Nov 23 '18 at 14:07














2 Answers
2






active

oldest

votes


















1














The real problem is that



public <String> void setGenericObject(GenericObject<String> obj)


where the String has nothing to do with the your intended java.lang.String. Here the String is just a type parameter whose name is String by accident.



Please refer to Is it possible to have an interface method defined with a generic return type and a concrete implementation define the return type?.






share|improve this answer





















  • Ok, I understand that my <String> tag is like <T>, but what do you propose to solve my problem ? And keep in mind that I don't want to do Generic<T>
    – MonkeyJLuffy
    Nov 23 '18 at 14:02



















0














Case 1:



If T is not used in Generic, then just use a wildcard.



class Generic {
List<?> list;
void set(List<?> list) {
this.list = list;
}
int size() {
return list.size(); // doesn't care about T
}
}




Case 2:



If T is only used as local variables, then declare <T> on the method



class Generic {
<T> void swapFirstAndSecond(List<T> list) {
T first = list.get(0), second = list.get(1);
list.set(1, first);
list.set(0, second);
}
}




Case 3:



If several fields and methods use the same type T, but the exact type of T is not important, then delacre <T> on the class



class Generic<T> {
List<T> list;
void set(List<T> list) {
this.list = list;
}
T getFirst() {
return list.get(0);
}
}




Case 4:



If T must be a specific type, like String, then don't declare type parameter <T>



class Generic {
List<String> list;
void set(List<String> list) {
this.list = list;
}
boolean isFirstContainsSecond() {
String first = list.get(0), second = list.get(1);
// call String.contains here, so T must be String
return first.contains(second);
}
}





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53447816%2fjava-generics-casting-generic-object-in-generic-specified-object-doesnt-wor%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    The real problem is that



    public <String> void setGenericObject(GenericObject<String> obj)


    where the String has nothing to do with the your intended java.lang.String. Here the String is just a type parameter whose name is String by accident.



    Please refer to Is it possible to have an interface method defined with a generic return type and a concrete implementation define the return type?.






    share|improve this answer





















    • Ok, I understand that my <String> tag is like <T>, but what do you propose to solve my problem ? And keep in mind that I don't want to do Generic<T>
      – MonkeyJLuffy
      Nov 23 '18 at 14:02
















    1














    The real problem is that



    public <String> void setGenericObject(GenericObject<String> obj)


    where the String has nothing to do with the your intended java.lang.String. Here the String is just a type parameter whose name is String by accident.



    Please refer to Is it possible to have an interface method defined with a generic return type and a concrete implementation define the return type?.






    share|improve this answer





















    • Ok, I understand that my <String> tag is like <T>, but what do you propose to solve my problem ? And keep in mind that I don't want to do Generic<T>
      – MonkeyJLuffy
      Nov 23 '18 at 14:02














    1












    1








    1






    The real problem is that



    public <String> void setGenericObject(GenericObject<String> obj)


    where the String has nothing to do with the your intended java.lang.String. Here the String is just a type parameter whose name is String by accident.



    Please refer to Is it possible to have an interface method defined with a generic return type and a concrete implementation define the return type?.






    share|improve this answer












    The real problem is that



    public <String> void setGenericObject(GenericObject<String> obj)


    where the String has nothing to do with the your intended java.lang.String. Here the String is just a type parameter whose name is String by accident.



    Please refer to Is it possible to have an interface method defined with a generic return type and a concrete implementation define the return type?.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 23 '18 at 13:57









    chenzhongpu

    2,24732451




    2,24732451












    • Ok, I understand that my <String> tag is like <T>, but what do you propose to solve my problem ? And keep in mind that I don't want to do Generic<T>
      – MonkeyJLuffy
      Nov 23 '18 at 14:02


















    • Ok, I understand that my <String> tag is like <T>, but what do you propose to solve my problem ? And keep in mind that I don't want to do Generic<T>
      – MonkeyJLuffy
      Nov 23 '18 at 14:02
















    Ok, I understand that my <String> tag is like <T>, but what do you propose to solve my problem ? And keep in mind that I don't want to do Generic<T>
    – MonkeyJLuffy
    Nov 23 '18 at 14:02




    Ok, I understand that my <String> tag is like <T>, but what do you propose to solve my problem ? And keep in mind that I don't want to do Generic<T>
    – MonkeyJLuffy
    Nov 23 '18 at 14:02













    0














    Case 1:



    If T is not used in Generic, then just use a wildcard.



    class Generic {
    List<?> list;
    void set(List<?> list) {
    this.list = list;
    }
    int size() {
    return list.size(); // doesn't care about T
    }
    }




    Case 2:



    If T is only used as local variables, then declare <T> on the method



    class Generic {
    <T> void swapFirstAndSecond(List<T> list) {
    T first = list.get(0), second = list.get(1);
    list.set(1, first);
    list.set(0, second);
    }
    }




    Case 3:



    If several fields and methods use the same type T, but the exact type of T is not important, then delacre <T> on the class



    class Generic<T> {
    List<T> list;
    void set(List<T> list) {
    this.list = list;
    }
    T getFirst() {
    return list.get(0);
    }
    }




    Case 4:



    If T must be a specific type, like String, then don't declare type parameter <T>



    class Generic {
    List<String> list;
    void set(List<String> list) {
    this.list = list;
    }
    boolean isFirstContainsSecond() {
    String first = list.get(0), second = list.get(1);
    // call String.contains here, so T must be String
    return first.contains(second);
    }
    }





    share|improve this answer




























      0














      Case 1:



      If T is not used in Generic, then just use a wildcard.



      class Generic {
      List<?> list;
      void set(List<?> list) {
      this.list = list;
      }
      int size() {
      return list.size(); // doesn't care about T
      }
      }




      Case 2:



      If T is only used as local variables, then declare <T> on the method



      class Generic {
      <T> void swapFirstAndSecond(List<T> list) {
      T first = list.get(0), second = list.get(1);
      list.set(1, first);
      list.set(0, second);
      }
      }




      Case 3:



      If several fields and methods use the same type T, but the exact type of T is not important, then delacre <T> on the class



      class Generic<T> {
      List<T> list;
      void set(List<T> list) {
      this.list = list;
      }
      T getFirst() {
      return list.get(0);
      }
      }




      Case 4:



      If T must be a specific type, like String, then don't declare type parameter <T>



      class Generic {
      List<String> list;
      void set(List<String> list) {
      this.list = list;
      }
      boolean isFirstContainsSecond() {
      String first = list.get(0), second = list.get(1);
      // call String.contains here, so T must be String
      return first.contains(second);
      }
      }





      share|improve this answer


























        0












        0








        0






        Case 1:



        If T is not used in Generic, then just use a wildcard.



        class Generic {
        List<?> list;
        void set(List<?> list) {
        this.list = list;
        }
        int size() {
        return list.size(); // doesn't care about T
        }
        }




        Case 2:



        If T is only used as local variables, then declare <T> on the method



        class Generic {
        <T> void swapFirstAndSecond(List<T> list) {
        T first = list.get(0), second = list.get(1);
        list.set(1, first);
        list.set(0, second);
        }
        }




        Case 3:



        If several fields and methods use the same type T, but the exact type of T is not important, then delacre <T> on the class



        class Generic<T> {
        List<T> list;
        void set(List<T> list) {
        this.list = list;
        }
        T getFirst() {
        return list.get(0);
        }
        }




        Case 4:



        If T must be a specific type, like String, then don't declare type parameter <T>



        class Generic {
        List<String> list;
        void set(List<String> list) {
        this.list = list;
        }
        boolean isFirstContainsSecond() {
        String first = list.get(0), second = list.get(1);
        // call String.contains here, so T must be String
        return first.contains(second);
        }
        }





        share|improve this answer














        Case 1:



        If T is not used in Generic, then just use a wildcard.



        class Generic {
        List<?> list;
        void set(List<?> list) {
        this.list = list;
        }
        int size() {
        return list.size(); // doesn't care about T
        }
        }




        Case 2:



        If T is only used as local variables, then declare <T> on the method



        class Generic {
        <T> void swapFirstAndSecond(List<T> list) {
        T first = list.get(0), second = list.get(1);
        list.set(1, first);
        list.set(0, second);
        }
        }




        Case 3:



        If several fields and methods use the same type T, but the exact type of T is not important, then delacre <T> on the class



        class Generic<T> {
        List<T> list;
        void set(List<T> list) {
        this.list = list;
        }
        T getFirst() {
        return list.get(0);
        }
        }




        Case 4:



        If T must be a specific type, like String, then don't declare type parameter <T>



        class Generic {
        List<String> list;
        void set(List<String> list) {
        this.list = list;
        }
        boolean isFirstContainsSecond() {
        String first = list.get(0), second = list.get(1);
        // call String.contains here, so T must be String
        return first.contains(second);
        }
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 23 '18 at 15:49

























        answered Nov 23 '18 at 14:35









        yyyy

        635




        635






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53447816%2fjava-generics-casting-generic-object-in-generic-specified-object-doesnt-wor%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)