How to think when you suddenly understand about generics

Overview

The generics are arguments. I will summarize the thoughts that I thought "Ah, I see" when I wasn't quite sure about Generics.

Referenced site

Thank you for the wisdom of our predecessors. http://d.hatena.ne.jp/Nagise/20101105/1288938415

Java environment

java version 1.8.0_181 Java(TM) SE Runtime Environment (build 1.8.0_181-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

src └example   └java     └generics       ├ Main.java       └ GenericsSample.java

The argument of the value is the method, isn't it?

Parentheses () ← This is

The method is this parenthesis (). This parenthesis () is the same symbol in the place of the method declaration and the place of the method call, but it is used in a different meaning. It's information to show "value used in method".

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        int result = plus(2, 5); //here  "()Declares "The method will be executed with the value of this argument"(Actual argument)
        System.out.println(result);
    }

    public static int plus(int T, int S) { //here "()Declares "I will receive an argument with this argument name"(Formal argument)
        return T + S;
    } // T,Range of S up to here
}

Of course you can do it properly function_2.JPG

Speaking of type arguments, it's generics, isn't it?

Angle brackets <> ← This is

Then, speaking of angle brackets <> ...? Yes, it's Generics. This angle bracket <> is the same symbol in the place of the generics declaration and the place of the generics call (I dare to say this), but it is used in a different meaning. It's information to show "types used in classes and methods".

GenericsSsample.java


package example.java.generics;

public class GenericsSample {
    //here "<>Declares "I will receive the type with this argument name"(Formal argument)
    public <T> void callGenerics(T value){
        System.out.println(value); //What is the value of the argument?
        System.out.println(value.getClass().getName()); //What is the argument type?
    } //Range of T up to here
}

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        GenericsSample genericsSample = new GenericsSample();
        
        //here "<>Declares "I will execute the method with a value of this type"(Actual argument)
        //here  "()Declares "I will execute the method with the value of this argument"(Actual argument)
        //Just specify different kinds of actual arguments with each symbol
        genericsSample.<Integer>callGenerics(1234);
    }
}

It is the value and type set by the argument properly generics_3.JPG generics_8.JPG

When the type value and the type of the value passed as an argument (it's hard to understand, ...) are different

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        GenericsSample genericsSample = new GenericsSample();
        genericsSample.<String>callGenerics(1234);
    }
}

Disturbing air generics_6.JPG

Will fail safely generics_7.JPG

Write in the order of type → value

In Java in the first place

//Order of type variables
String variable;

Since it is written in "type → order" like, it is understandable that the order of the arguments representing the type and the argument also becomes "generics → value".

//Type → Value
//The reason why the generic that represents the type comes before void is that the return type may be the argument specified by the generic.(In this case "T")Because there is(maybe)
public <T> void callGenerics(T value)

//Type → Value
genericsSample.<String>callGenerics(1234);

Generics specified for the class

Like the method, the class just has a declaration (a formal argument) that says "I'll take the type with this argument name".

GenericsSample.java


package example.java.generics;

//here "<>Declares "I will receive the type with this argument name"(Formal argument)
public class GenericsSample<T> {

    //The scope of the argument T of the type specified in the class continues to the method in the class
    public void callGenerics(T value){
        System.out.println(value); //What is the value of the argument?
        System.out.println(value.getClass().getName()); //What is the argument type?
    }
} // <T>Range up to here

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        //here "<>Declares "I will instantiate a class with a value of this type"(Actual argument)
        // new GenericsSample<Integer>Is new GenericsSample<>It is okay to omit to(GenericsSample<Integer>Why is it an Integer? Infers)
        GenericsSample<Integer> genericsSample = new GenericsSample<Integer>();

        //here  "()Declares "The method will be executed with the value of this argument"(Actual argument)
        genericsSample.callGenerics(1234);
    }
}

generics_15.JPG generics_9.JPG

Of course, if you specify a different type for the method. .. ..

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        //here "<>Declares "I will instantiate a class with a value of this type"(Actual argument)
        // new GenericsSample<Integer>Is new GenericsSample<>It is okay to omit to(GenericsSample<Integer>Why is it an Integer? Infers)
        GenericsSample<Integer> genericsSample = new GenericsSample<Integer>();

        //here  "()Declares "The method will be executed with the value of this argument"(Actual argument)
        genericsSample.callGenerics("test");
    }
}

Disturbing air generics_10.JPG

Will fail safely generics_11.JPG

If <> is attached to both the class and the method with the same argument name. ..

GenericsSample.java


package example.java.generics;

//here "<>Declares "I will receive the type with this argument name"(Formal argument)
public class GenericsSample<T> {

    //here "<>Declares "I will receive the type with this argument name"(Formal argument)
    //The scope of the argument T of the type specified in the class continues to the method in the class... ??
    public <T> void callGenerics(T value){
        System.out.println(value); //What is the value of the argument?
        System.out.println(value.getClass().getName()); //What is the argument type?
    }
} // <T>Range up to here... ??

Main.java


package example.java.generics;

public class Main {
    public static void main(String[] args) {
        //here "<>Declares "I will instantiate a class with a value of this type"(Actual argument)
        // new GenericsSample<Integer>Is new GenericsSample<>It is okay to omit to(GenericsSample<Integer>Why is it an Integer? Infers)
        GenericsSample<Integer> genericsSample = new GenericsSample<Integer>();

        //here  "()Declares "The method will be executed with the value of this argument"(Actual argument)
        genericsSample.callGenerics("test");
    }
}

Not disturbing at all generics_12.JPG generics_13.JPG

I won't fail ... generics_14.JPG

The cause of this is ** where "<>" declares "I will receive the type with this argument name" (formal argument) **

Because I specified it with the same argument name. I overwrote it with a new local type variable in the method. It feels like ↓.

GenericsSample.java


package example.java.generics;

//here "<>Declares "I will receive the type with this argument name"(Formal argument)
public class GenericsSample<T> {

    //Within the class, the actual arguments of the generics specified when the class was instantiated.(new GenericsSample<Integer>Integer)Is valid

    //The scope of the argument T of the type specified in the class is the actual argument of the generics specified at the time of the method.(This time String)Has been overwritten with
    // genericsSample.callGenerics("test");of"test"From ""test"Because is a String<T>ofTはStringだ!」と推論された)
    public <T> void callGenerics(T value){
        System.out.println(value); //What is the value of the argument?
        System.out.println(value.getClass().getName()); //What is the argument type?
    }
}

Can't it be specified when declaring a static class?

**can not. ** ** For non-static classes

//here "<>Declares "I will instantiate a class with a value of this type"(Actual argument)
// new GenericsSample<Integer>Is new GenericsSample<>It is okay to omit to(GenericsSample<Integer>Why is it an Integer? Infers)

But when it's a static class, you can't instantiate the class, right? It is impossible because there is no timing to specify the actual argument and create it. .. (But if it is a static method unit, you can specify the actual argument at the time of calling, so you can specify the type argument of the generics!)

Conclusion

Don't panic because it's just an argument.

Recommended Posts

How to think when you suddenly understand about generics
How to replace characters that you do not understand [Principle]
Think about how to divide MVC into M and V
Things to think about when deciding on a new system architecture
How to think about class design (division) in a business system (1)
Understand in 5 minutes !! How to use Docker
About "Dependency Injection" and "Inheritance" that are easy to understand when remembered together
[Rails] How to write when making a subquery
Understand how to share Spring DB connection (DB transaction)
When you want to bind InputStream in JDBI3
When you want to use the method outside
How to delete the database when recreating the application
What do you use when converting to String?
How to log in automatically when Ubuntu restarts
[Ruby] When you want to replace multiple characters
How to delete the tweet associated with the user when you delete it at the same time
How to make a Vagrant Plugin that you learned when you forked and published vagrant-mutagen
Do you really understand? How to check the library and license used by the app
Perspectives to worry about when doing code reviews of web applications (Rails)
Summary of points I was worried about when migrating from java to kotlin
Points to review when Rubocop is slow to run
About exception handling
About exception handling
About Ruby variables
How to think when you suddenly understand about generics