Wildcards and generic interface
1. The lead Wildcard
After added generics in the program, you can avoid ClassCastException
the problem, but will produce a new situation: the unity of the parameters of the problem.
Example: Method Parameter Type parameter does not match the type of the received
public class TestMessage{
public static void main(String[] args) {
Message<Integer> message = new Message<>();
message.setMessage(20);
//fun(message); 与fun()方法中的类型不匹配,报红
}
//此处方法参数的Message泛型类型是String
private static void fun(Message<String> message) {
System.out.println(message.getMessage());
}
}
class Message<T> {
private T message;
public void setMessage(T message){
this.message = message;
}
public T getMessage(){
return this.message;
}
@Override
public String toString() {
return "TestMessage{" +
"message=" + message +
'}';
}
}
Then in order to solve the above problems, can accept all of the generic type do not allow users to freely edit, it is necessary in this case to use a wildcard to process
Example: use wildcards
public class TestMessage{
public static void main(String[] args) {
Message<Integer> message = new Message<>();
message.setMessage(20);
fun(message);
Message<String> message1 = new Message<>();
message1.setMessage("hello");
fun(message1);
}
//其中?可以表示任意类型,但是因为不确定类型,所以无法进行修改
private static void fun(Message<?> message) {
//message.setMessage(100); 无法修改
System.out.println(message.getMessage());
}
}
1.2. Generic upper limit
On the basis of the wildcard, and they had two sons wildcards. Generic Generic upper and lower limits .
- ? Extends categories: generic set an upper limit
, such as: ? Number The the extends : because of the inheritance, so? A subclass, and Number is its limit. It indicates that only can be provided Number or a subclass, for example: Integer, Double- Generic upper limit may be used either on the class, and can be used in the method
Example 1: Method using generic limit
public class TestMessage{
public static void main(String[] args) {
Message<String> message1 = new Message<>();
message1.setMessage("hello");
fun(message1);
}
// 因为String类被final修饰,所以没有子类,此处只能放String
private static void fun(Message<? extends String> message) {
System.out.println(message.getMessage());
}
}
Example 2: Method using generic limit
public class TestMessage{
public static void main(String[] args) {
Message<String> message = new Message<>();
message.setMessage("hello");
fun(message);
Message<StringBuffer> message1 = new Message<>();
message1.setMessage(new StringBuffer().append("hello").append("world"));
fun(message1);
}
private static void fun(Message<? extends CharSequence> message) {
System.out.println(message.getMessage());
}
}
The following are the CharSequence Known Implementing Classes:
Example: use the generic class limit
public class Point6 <T extends CharSequence>{
private T x;
private T y;
public void setX(T x){
this.x = x;
}
public T getX(){
return this.x;
}
public void setY(T y){
this.y = y;
}
public T getY(){
return this.y;
}
@Override
public String toString() {
return "Point6{" +
"x=" + x +
", y=" + y +
'}';
}
public static void main(String[] args) {
Point6<String> p1 = new Point6<>();
p1.setX("hello");
System.out.println(p1);
Point6<StringBuffer> p2 = new Point6<>();
p2.setY(new StringBuffer().append("hello").append(" world"));
System.out.println(p2);
}
}
1.3. Generic limit
- ? Super class: Setting a generic limit
such as:? <? Super Integer>, it represents the Integer, Number, Object
For example: the use of generic limit
public class TestMessage{
public static void main(String[] args) {
Message<String> message = new Message<>();
message.setMessage("hello");
fun(message);
}
private static void fun(Message<? super String> message) {
message.setMessage("world"); //此处可以进行修改!!!
System.out.println(message.getMessage());
}
}
to sum up:
- The upper limit can be used in the statement, it can not be modified;
- The lower limit can only be used in the process parameters can not be used in a generic classes, you can modify the contents
2. Generic Interface
- In addition to defining generic classes, which may be defined in the interface, this situation has become generic interface.
- Generic interface definitions and generic classes are not very different
- Generic interface implementation class:
- You can continue to be generic class interface
- Is not a generic class may specify the particular type of interface
- Define a generic interface:
interface IMessage<T> { //在接口上定义了泛型
public void print(T t);
}
Example: Use generic interface
public interface IMessage<T> {
void print(T t);
public static void main(String[] args) {
IMessage<String> qq = new QQMessage();
qq.print("hello");
MsnMessage<Integer> msn = new MsnMessage<>();
msn.print(100);
}
}
//继承原来的类型
class QQMessage implements IMessage<String>{
@Override
public void print(String t) {
}
}
//指定新的类型
class MsnMessage<T> implements IMessage<T>{
@Override
public void print(T t) {
}
}
Example: Use anonymous inner classes
public interface IMessage<T> {
void print(T t);
public static void main(String[] args) {
new IMessage<String>() {
@Override
public void print(String str) {
System.out.println(str);
}
}.print("hello");
}
}