Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8278323

Incompatible types are passed with List.of to generics methods

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      OS: Mac OS Cataline 10.15.7
      Java Version: openjdk 17 2021-09-14

      A DESCRIPTION OF THE PROBLEM :
      An incompatible type can be passed with List.of() to a method that is restricted by lower bounded wildcards.

      Employee extends Person and Unemployed extends the Employee class.

      private static void printList(final List<? super Employee> list){
              /** **/
      }

      var unEmployedList = List.of(new Unemployed("Huseyin"));
      printList(unEmployedList);

      Compiler does not compile this code, exception message: java: incompatible types: java.util.List<org.jugistanbul.Unemployed> cannot be converted to java.util.List<? super org.jugistanbul.Employee>

      But the compiler compiles this code:
      printList(List.of(new Unemployed("Huseyin")));


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create Person Class:

      class Person
      {
          private String name;

          public Person() {
          }

          public Person(String name) {
              this.name = name;
          }

          public String getName() {
              return name;
          }

          public void setName(String name) {
              this.name = name;
          }
      }

      And create Employee class which extends Person class

      class Employee extends Person
      {
         private BigDecimal salary;

         public Employee(){}
          public Employee(String name) {
              super(name);
          }

          public BigDecimal getSalary() {
              return salary;
          }

          public void setSalary(BigDecimal salary) {
              this.salary = salary;
          }
      }

      And create Unemployed class which extends Employee class

      class Unemployed extends Employee {

          public Unemployed(String name) {
              super(name);
          }
      }

      Then create printList method with lower bounded wildcard restrict

      private static void printList(final List<? super Employee> list){
              /** **/
       }

      And finally, call the method whit the argument Unemployed list that is built with List.of

      printList(List.of(new Unemployed("Huseyin")));

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The expected behavior is that the code does not compile and gives an incompatible types exception message like this: java.util.List<org.jugistanbul.Unemployed> cannot be converted to java.util.List<? super org.jugistanbul.Employee>

      ACTUAL -
      The compiler compiles this code and gives no exception message

      ---------- BEGIN SOURCE ----------
      package org.jugistanbul;

      import java.math.BigDecimal;
      import java.util.List;

      /**
       * @author hakdogan (huseyin.akdogan@patikaglobal.com)
       * Created on 02.12.2021
       ***/
      public class Generics
      {

          private static void printList(final List<? super Employee> list){
              System.out.println(list.get(0).getClass().getName());
          }

          public static void main(String[] args) {
              
              var personList = List.of(new Person("Battal Gazi"));
              var employeeList = List.of(new Employee("Koroglu"));
              var unEmployedList = List.of(new Unemployed("Bolu Beyi"));

              printList(personList);
              printList(employeeList);
              printList(unEmployedList);
          }
      }

      class Person
      {
          private String name;

          public Person() {
          }

          public Person(String name) {
              this.name = name;
          }

          public String getName() {
              return name;
          }

          public void setName(String name) {
              this.name = name;
          }
      }

      class Employee extends Person
      {
         private BigDecimal salary;

         public Employee(){}
          public Employee(String name) {
              super(name);
          }

          public BigDecimal getSalary() {
              return salary;
          }

          public void setSalary(BigDecimal salary) {
              this.salary = salary;
          }
      }

      class Unemployed extends Employee {

          public Unemployed(String name) {
              super(name);
          }
      }
      ---------- END SOURCE ----------

      FREQUENCY : always


            adev Anupam Dev
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: