3

Saw a couple of similar questions today- got me thinking:

What are the rules for when to use generics?

  • When a collection is involved?
  • When there are getter methods which return collection elements?
  • Whether the object changes type during its lifetime?
  • Whether the relationship is composition/aggregation to the class?

There doesn't seem to be a consensus on the questions you should ask yourself in order to determine whether you should use generics. Is it purely an opinionated decision?

Is it easier to ask when you shouldn't use generics??

user997112
  • 29,025
  • 43
  • 182
  • 361

4 Answers4

4

Let me start with some general points about generics and type information before I get back to the first point on your bullet list.


Generics prevent unnecessary type casts.

Do you remember Java before generics were introduced? Type casts were used everywhere.

This is what type casts essentially are: You are telling the compiler about an object's type, because the compiler doesn't know or cannot infer it.

The problem with type casts is that you sometimes make mistakes. You can suggest to the compiler that an instance of class Fiddle is a Frobble ((Frobble)fiddle), and the compiler will happily believe you and compile your source code. But if it turns out that you were wrong, you'll much later get a nice run-time error.

Generics are a different, and usually safer way of letting the compiler retain type information. Basically, the compiler is less likely to make typing mistakes than a human programmer... the less type casts required, the fewer potential error sources! Once you've established that a list can only contain Fiddle objects (List<Fiddle>), the compiler will keep this information and prevent you from having to type-cast each item in that list to some type. (You still could cast a list item to Frobble, but why should you, now that the compiler let's you know that the item is a Fiddle!?)

I have found that generics greatly reduce the need for type casting, so the presence of lots of type casts — especially when you always cast to the same type — might be an indicator that generics should be used instead.

Letting the compiler keep as much type information as possible is a good thing because typing errors can be discovered earlier (at compile-time instead of at run-time).

Generics as a replacement for the "generic" java.lang.Object type:

Before generics, if you wanted to write a method that worked on any type, you employed the java.lang.Object supertype, because every class derives from it.

Generics allow you to also write methods that work for any type, but without forcing you or the compiler to throw away known type information — that's exactly what happens when you cast an object to the Object type. So, frequent use of the Object type might be another indicator that generics might be appropriate.


When a collection is involved?

Why do generics seem an especially good fit for collections? Because, according to the above reasoning, collections are rarely allowed to contain just any kind of object. If that were so, then the Object type would be appropriate because it doesn't put any restrictions whatsoever on the collection. Usually however, you expect all items in a collection to be (at least) a Frobble (or some other type), and it helps if you let the compiler know. Generics are the way how to do just that.


Whether the relationship is composition/aggregation to the class?

You've linked to another question that asks about a class Person having a car property should be made generic as class Person<T extends ICar>.

In that case, it depends whether your program needs to distinguish between Honda people and Opel people. By making such a Person class generic, you essentially introduce the possibility of different kinds of people. If this actually solves a problem in your code, then go for it. If, however, it only introduces hurdles and difficulties, then resist the urge and stay with your non-generic Person class.

Side node: Keep in mind that you don't have to make a whole class generic; you can make only a few specific methods generic. At least in the .NET ecosystem, it is recommended to keep generics as "local" as possible, i.e. don't turn a class into a generic one when it's sufficient to make only a method generic.

Community
  • 1
  • 1
stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
2

I find myself using generics when the following three criteria are met:

  1. I note that I am repeating code, and start thinking of how to refactor it into a new method/class.
  2. The class/method I am rewriting doesn't really care about what the concrete type of one of the arguments is, only that it follows a certain contract (eg <T extends Bar>).
  3. The return type of the method/one of the methods is related to said parameter or
    two or more parameters are related and need to have the same type, although I don't really care what that type is.

Usually when these criteria are met, there is a Collection of some kind involved, but not necessarily.

Keppil
  • 45,603
  • 8
  • 97
  • 119
  • 1
    I would ammend #2 to say that the class/method doesn't care what the "convrete" type of the arguments are, only that they follow a certain contract. For instance: public class Foo. You only care that whatever is substituted for T can be treated as a Bar instance. – Matt Jul 11 '12 at 21:25
0

In my opinion the second statement (when not to use them) is correct.

When not to use generics: when the strong typing is too restrictive (typically generics in generics). In some cases you want to ensure loose coupling among your components and the point is "send me what you want, the API will somehow handle it", than you will employ some kind of visitor, rather than specifying complete concrete API using some generic type.

When you should: if you had not, you would have to cast the variable to some type (you even you might have to guess or use instanceof)...


Just one sidenote: every structured type is some kind of collection...

malejpavouk
  • 4,297
  • 6
  • 41
  • 67
0

Is it easier to ask when you shouldn't use generics??

To answer this question, one of the major problems with Generics is its treatment for Checked Exceptions. Here is a write-up from Geotz about this.

Reason why you should consider generics, again there is a cache of information shared.

sathish_at_madison
  • 823
  • 11
  • 34