Normally, when designing a class, you decide the types of all member variables immediately. There are however situations in which you want to decide later. For instance: You want to store a list of stuff, but you don’t want to be pinned down on what that stuff should be.
The only alternative is writing different versions of the same class for each different type of stuff.
Please note that you have already used generic classes:
private ArrayList<String> names;
private ArrayList<Student> students;
ArrayList has been implemented once (DRY) with the ability to decide on what it actually stores later, and when you use it you fill in the type of what is actually going to be stored.
You cannot make mistakes in the use of this list:
students.add(new Chicken("This not allowed"));
IntelliJ itself will not allow you to make this mistake, it will say something like: “Hey! You promised you would store only Students in this list, what’s up with the Chicken?”
At a later time, when you take elements out of this list, you know what type they must be.
Student x = students.get(i); // No problem.
Chicken y = students.get(i); // You've got problems.