1

It was stated in comments that, question was creating confusion. So, i have edited the question, let me know, if it is still creating confusion.

Consider below code:

class Employee{}

class ContractEmployee extends Employee{ }

class PermanentEmployee extends Employee{ } ...

Can any one provide the basic difference between below two cases and when to use which one

Case:1

public <T extends Employee> void empTest(ArrayList<T> list)

public <? extends Employee> void empTest(ArrayList<?> list)

Case:2

public void empTest(ArrayList<? extends Employee> list)

public void empTest(ArrayList<T extends Employee> list)
akki
  • 11
  • 2
  • 1
    Please edit your question, looking at the preview pane to see how it will be rendered. The code in the question is not formatted, and so is basically unreadable. – Andy Turner Sep 30 '18 at 15:39
  • You can't declare a type variable called `?`, so "why can't we write `public extends Employee> void`" because it's invalid syntax. – Andy Turner Sep 30 '18 at 15:49
  • First time i took step into this Stack OverFlow platform, so things are moving here and there. Thanks for suggestion, i even placed an image of my concern. – akki Sep 30 '18 at 16:27
  • Why do you have a picture of the text in the question? If your question is unclear (like it is at least to me), fix it, don't add more things to confuse. – James Z Sep 30 '18 at 19:31

2 Answers2

0

Not full explanation but you will get starting over here. We need to follow PECS pattern in generics. PECS stands for Producer Extends and Consumer Super.

in your line below,
public void empTest(ArrayList list)
You are basically giving list which will act as a producer in further use inside that method. Now as you might know, generic is just compile time illusion and will get erased at runtime, your code in mrthod empTest is expecting the List of particular Employee. for example, if you have Fruit as superclass for Orange and Apple, you should not give list of both Orange and Apple to consumer and restrict it to either Apple or Orange. Does it make sense? I guess yes.

Tukaram Bhosale
  • 348
  • 3
  • 17
0

First of all, your question is quite legitimate, although with your examples, it's hard to explain / understand the differences.

In all the variants, you want to define a method empTest() that accepts an ArrayList of Employees or subclasses of Employee. You do this with

public void empTest(ArrayList<? extends Employee> list) { ... }

So, what are the other syntax variants meant for? Let's use a different example, as your empTest() method doesn't need anything else.

Say, we want to add an employee to a list using something like addEmp(list, emp);. First idea might be:

public void addEmp(ArrayList<Employee> list, Employee emp) { ... }

But that won't do the job, as you won't be able to pass an ArrayList<ContractEmployee> into the method. Next attempt:

public void addEmp(ArrayList<? extends Employee> list, Employee emp) { ... }

Now it accepts the list, but it also allows you to pass an ArrayList<ContractEmployee> in combination with a PermanentEmployee, and adding a PermanentEmployee to an ArrayList<ContractEmployee> isn't allowed. The compiler will flag the line in the method body where you add the employee, as illegal.

So, what we need here, is to check for using the same type of employee in both places, and that's what the named type parameters can be used for.

public <T extends Employee> void addEmp(ArrayList<T> list, T emp) { ... }

This says: it's ok to pass in an ArrayList of any subtype of Employee, and we call that subtype T. Then the emp argument must also come from the same subtype T (or from a sub-subtype because of normal class inheritance).

If being an Employee or not doesn't make a difference to the method, you can even write

public <T> void addEmp(ArrayList<T> list, T emp) { ... }

To summarize it:

  • Use the <... extends SomeClass> constructs if need more variability than the plain <SomeClass> construct.
  • If it's just one place where you need that variability, there's often no need to introduce a name for the subclass, so <? extends SomeClass> in the method's parameter list does the job.
  • If you need the same subclass in multiple places, you need to give it a name, so use something like <T extends SomeClass> in front of the return-type declaration and use T without the angle brackets in the parameters list.

Regarding syntax: - If you need to introduce a name for the type parameter, this is done before the return type. - In the method return type or the method parameter list, you can only use names that already exist, or use unnamed wildcard constructs.

Ralf Kleberhoff
  • 6,990
  • 1
  • 13
  • 7