catalogue
1. Generic problem elicitation
The generic type is jdk1 5 and then added to the java language. The main purpose is to solve the ClassCastException problem. There may be security risks during object downward transformation.
give an example
public class Point { private Object x; private Object y; public Object getX() { return x; } public void setX(Object x) { this.x = x; } public Object getY() { return y; } public void setY(Object y) { this.y = y; } }
public class JavaDemo { public static void main(String[] args) { Point point = new Point(); point.setX(10); point.setY("dsfdf"); int x = (Integer) point.getY(); int y = (Integer) point.getX(); System.out.println(x + "====" + y); } }
In this case, there seems to be no problem, but there are security risks. Due to the use of Object, the string type cannot be forcibly converted to Integer, and there will be no error during compilation, so there are security risks. In order to avoid this hidden danger, we introduce the concept of generics. Using generics can directly expose this hidden danger in the compilation process.
2. Definition of generics
The essence of generics is that the types of parameters and return values of properties or methods in a class can be dynamically determined when the object is instantiated.
Usage: a placeholder (generic tag) that is clearly defined when defining a class, for example:
public class Point<T> { private T x; private T y; public T getX() { return x; } public void setX(T x) { this.x = x; } public T getY() { return y; } public void setY(T y) { this.y = y; } }
As shown above, after using generic tags, the data types of the x and y attributes in the Point class are not clear, and they are determined externally.
public class JavaDemo { public static void main(String[] args) { Point<Integer> point = new Point(); point.setX(10); point.setY("dsdf");//Direct error reporting during compilation int x = point.getY(); int y = point.getX(); System.out.println(x + "====" + y); } }
As mentioned above, when instantiating the Point class, the data types of x and y are specified as Integer (hint: if not specified here, Point still uses Object, which is the default result). If incorrect type conversion is used, an error will be reported directly during the compilation process, avoiding the potential safety hazard at runtime.
3. Generic wildcard
The introduction of generic wildcards is mainly to prevent arbitrary tampering with the data types of method parameters. The following cases are shown:
public class Message<T> { private T content; public T getContent() { return content; } public void setContent(T content) { this.content = content; } }
public class JavaDemo { public static void main(String[] args) { Message<String> msg1 = new Message<>(); msg1.setContent("www.loong.cn"); fun(msg1); Message<Integer> msg2 = new Message<>(); msg2.setContent(234); fun(msg2); } public static void fun(Message temp){ System.out.println(temp.getContent()); } }
There seems to be no problem with the above use, but there are hidden dangers. As for the problem of tampering with parameters mentioned above, we can redefine the data type of Message in the method. As follows: the output results are completely different. Both instantiated objects print "haha"
public class JavaDemo { public static void main(String[] args) { Message<String> msg1 = new Message<>(); msg1.setContent("www.loong.cn"); fun(msg1); Message<Integer> msg2 = new Message<>(); msg2.setContent(234); fun(msg2); } public static void fun(Message temp){ temp.setContent("hahaha"); System.out.println(temp.getContent()); } }
So we have a new concept, generic wildcard, which can be used as follows
Used? Later, although the method can accept all types of parameters, the parameters can no longer be modified and can only be obtained.
public class JavaDemo { public static void main(String[] args) { Message<String> msg1 = new Message<>(); msg1.setContent("www.loong.cn"); fun(msg1); Message<Integer> msg2 = new Message<>(); msg2.setContent(234); fun(msg2); } public static void fun(Message<?> temp){ temp.setContent("hahaha");//This line of compilation directly reports an error System.out.println(temp.getContent()); } }
Two other generic wildcards:
3.1 ? Extensions class: sets the upper limit of generics
For example:? Extensions Number: indicates that only Number or subclass of Number can be set for this generic type.
give an example:
public class JavaDemo { public static void main(String[] args) { Message<String> msg1 = new Message<>(); msg1.setContent("www.loong.cn"); fun(msg1);//This line reports an error during compilation Message<Integer> msg2 = new Message<>(); msg2.setContent(234); fun(msg2); } public static void fun(Message<? extends Number> temp){ System.out.println(temp.getContent()); } }
3.2 ? super class: sets the lower bound of generics
For example:? super String: indicates that the generic type can only set String or the parent class of String
give an example:
public class JavaDemo { public static void main(String[] args) { Message<String> msg1 = new Message<>(); msg1.setContent("www.loong.cn"); fun(msg1); Message<Integer> msg2 = new Message<>(); msg2.setContent(234); fun(msg2);//report errors } public static void fun(Message<? super String> temp){ System.out.println(temp.getContent()); } }
4. Generic interface
In addition to being defined on classes, generics can also be used on interfaces
public interface Imessage<T> { public String echo(T t); }
For subclasses of generic interfaces, there are two implementations:
4.1 continue to set generics in subclasses:
public class MessageImpl<S> implements Imessage<S> { @Override public String echo(S s) { return "Hello: " + s; } }
public class JavaDemo { public static void main(String[] args) { Imessage<String> imessage1 = new MessageImpl<>(); System.out.println(imessage1.echo("Brother long")); } }
4.2 subclasses are directly defined when implementing the parent class interface
public class MessageImpl implements Imessage<String> { @Override public String echo(String s) { return "Hello: " + s; } }
public class JavaDemo { public static void main(String[] args) { Imessage<String> imessage1 = new MessageImpl(); System.out.println(imessage1.echo("Brother long")); } }
5. Generic method
If you write a generic tag on a method, such a method is called a generic method
public class JavaDemo { public static void main(String[] args) { Integer[] num = fun(1, 2, 3); for (int temp : num) { System.out.println(temp + "! "); } String[] strings = fun("a", "b", "c"); for (String temp : strings) { System.out.println(temp + "! "); } } public static <T> T[] fun(T... args) { return args; } }