What is more correct than Java Generic Interface and Generic Methods in this case?


This issue arose because of the PDF... discussions with a colleague about what is preferable. There is a code that can be written in two ways:

1 Method:

public interface MyInterface<T> {
    T function(T prm);
}

And

Method 2:

public interface MyInterface {
    <T> T function(T prm);
}

The implementation of the interface is a single MyInterfaceImpl class (also with Generic for a class or method), the class is created using Spring DI in the class constructors, that is:

1 Method:

public class OtherClass {
  private final MyInterface<String> str;

  @Inject
  public OtherClass(MyInterface<String> str) {
     this.str = str;
  }

2 Way:

public class OtherClass {
  private final MyInterface str;

  @Inject
  public OtherClass(MyInterface str) {
     this.str = str;
  }

In principle, the implementation itself in both ways is not a problem. The question is the correctness, pros and cons of each approach. If you can, please quote Oracle documentation or well-known authors on this subject (I haven't found any good ones yet).

Update: Once again about the conditions: 1. interfaces and classes have only one method, 2. in each class where it is used, the interface / method works with only one type, 3. use both options in principle may.

Author: Slava Vedenin, 2017-11-22

2 answers

And so, and so correctly, you should look at what is the meaning of of your class. That is, you should program your classes so that their design corresponds to the subject area.

For example, if you have a universal factory for the production of weapons, then you have one, and the types of weapons can produce many:

public class WeaponFactory {
    public <T extends Weapon> T produce() { ... }
}

And if you have a machine that produces one type of weapon, then this type is a "parameter" of the machine itself, and its variety is produced weapons pre-allocated:

public class WeaponMachine<T extends Weapon> {
    public T make() { ... }
}

Look at the semantics of your classes.


I have no supporting sources, but I think this is one of the central, usually unspoken principles of OOP.

We have many options to split the responsibility between different methods and groups of methods. Some of them lead to problems. (For example, the responsibility for some actions may not be assigned to any of the objects by mistake.)

So here's the idea it consists in the following: if you write objects and assign permissions so that it corresponds to the skills and actions of objects in real life (that is, in the subject area), then there is less chance for problems. Because after all, in real life, such a scheme works? So it should work in the program as well. And if something doesn't work out, we can compare our code with a "working model" from reality, and see what part of the information we are missing.

 12
Author: VladD, 2017-12-01 13:14:57

If you want the class that will inherit your interface to work with only one type, then MyInterface<T> is more suitable, since it will be extremely inconvenient to use generic methods if the class will work with only one type, you will need to explicitly specify the type each time using <T>

But if you want the class that will inherit your interface to work with different types, then it is better to use generic methods.

A good example would be java.util.List. In him there are methods that use the generic type(boolean add(E e);, E set(int index, E element);), and generic methods (<T> T[] toArray(T[] a);) and others.

 9
Author: Esidrys Metall, 2018-05-28 14:40:18