Java learning summary: 21

Generic

Generic derivation

Example: Demonstration of downward transformation

package Project.Study.Genericity;

class Point{					//定义坐标类
    private Object x;			//可以保存任意数据
    private Object y;			//可以保存任意数据

    public Object getX() {
        return x;
    }

    public Object getY() {
        return y;
    }

    public void setX(Object x) {
        this.x = x;
    }

    public void setY(Object y) {
        this.y = y;
    }
}
public class Test {
    public static void main(String args[]){
        Point p=new Point();				//实例化Point类数据
        p.setX("东经100度");				//设置坐标数据
        p.setY(10);							//设置坐标数据
        System.out.println("x坐标:"+p.getX()+"y坐标"+p.getY());
        //根据设置好的坐标取出数据进行操作
        String x=(String)p.getX();			//取出坐标数据
        String y=(String)p.getY();			//取出坐标数据
        System.out.println("x坐标:"+x+"y坐标"+y);
    }
}
//结果
//Exception in thread "main" java.lang.ClassCastException: class //java.lang.Integer cannot be cast to class java.lang.String //(java.lang.Integer and java.lang.String are in module java.base of //loader 'bootstrap')
//	at Project.Study.Genericity.Test.main(Test.java:30)
//x坐标:东经100度y坐标10

Example: Use generics to reduce transformation operations

package Project.Study.Genericity;
//此时的T在Point类定义上只表示一个标记,在使用时需要为其设置具体的类型
class Point<T>{		
    private T x;		//此属性的类型不知道,由Point类使用时的动态决定
    private T y;		//此属性的类型不知道,由Point类使用时的动态决定

    public T getX() {
        return x;
    }

    public T getY() {
        return y;
    }

    public void setX(T x) {
        this.x = x;
    }

    public void setY(T y) {
        this.y = y;
    }
}
public class Test {
    public static void main(String args[]){
        Point<String> p=new Point<String>();		//实例化Point类数据,设置泛型为String
        p.setX("东经100度");
        p.setY("北纬20度");
        System.out.println("x坐标:"+p.getX()+"y坐标"+p.getY());
        String x=p.getX();							//取出坐标数据,不再需要强制类型转换
        String y=p.getY();							////取出坐标数据,不再需要强制类型转换
        System.out.println("x坐标:"+x+"y坐标"+y);
    }
}
//结果
//x坐标:东经100度y坐标10
//x坐标:东经100度y坐标10

Tip: You can define multiple generic tags in a class.

class Point<P,R>{
	public R fun(P p){
		return null;
	}
}

It should be noted that if you want to use generics, the types that it can adopt can only be classes, that is, they cannot be basic types, only reference types.

Wildcard

Example: Use of wildcard "?"

package Project.Study.Genericity;

class Message<T>{
    private T msg;
    public void setMsg(T msg){
        this.msg=msg;
    }

    public T getMsg() {
        return msg;
    }
}
public class Test1 {
    public static void main(String args[]){
        Message<Integer>message1=new Message<>();
        Message<String>message2=new Message<>();
        message1.setMsg(30);
        message2.setMsg("Hello World");
        fun1(message1);							//引用传递
        fun2(message2);
    }
    public static void fun1(Message<?> temp){	//不能设置,但是可以取出
        System.out.println(temp.getMsg());
    }
    public static void fun2(Message temp){		//默认使用Object作为泛型类型,可以在方法中随意修改对象内容(即使类型不符合),这种做法是不严谨的
    	temp.setMsg(100);
        System.out.println(temp.getMsg());
    }
}
//结果
//30
//100

By the above fun2 (), the wildcard "?" Must be used to restrict this operation of arbitrarily modifying data. Therefore, the generic type set by "?" Only means that it can be taken out, but it cannot be set . Once the content is set, an error message will appear when the program is compiled.

"? Extends class": Set the upper limit of the generic, which can be used in the declaration and method parameters;

? extends Number: means you can set Number or a subclass of Number (Integer, Double, ...)

Example: Set an upper limit for generics

package Project.Study.Genericity;

class Message<T extends Number>{	//设置泛型上限,只能是Number或Number子类
    private T msg;
    public void setMsg(T msg){
        this.msg=msg;
    }

    public T getMsg() {
        return msg;
    }
}
public class Test1 {
    public static void main(String args[]){
        Message<Integer>message1=new Message<>();				//Integer是Number子类
        message1.setMsg(30);
        fun1(message1);											//引用传递
    }
    public static void fun1(Message<? extends Number> temp){	//定义泛型上限
        System.out.println(temp.getMsg());
    }
}
//结果
//30

"? Super class": set the lower limit of generics, used on method parameters;

? super String: means that only String or its parent Object can be set.

Example: Set the lower limit of generics

package Project.Study.Genericity;

class Message<T>{				//定义泛型
    private T msg;
    public void setMsg(T msg){
        this.msg=msg;
    }

    public T getMsg() {
        return msg;
    }
}
public class Test1 {
    public static void main(String args[]){
        Message<String>message1=new Message<>();
        message1.setMsg("Hello World");						//设置属性内容
        fun1(message1);										//引用传递
    }
    public static void fun1(Message<? super String> temp){	//定义泛型下限
        System.out.println(temp.getMsg());
    }
}
//结果
//Hello World

Generic interface

In any case, if you want to use an interface, you must define the corresponding subclass, and for a generic interface subclass, there are the following two implementations.

Implementation one: continue to set generic tags in subclasses

Example:

package Project.Study.Genericity;

interface IMessage<T>{      //定义泛型接口
    public void print(T t);
}
class MessageImpl<S>implements IMessage<S>{ //在子类继续设置泛型,此泛型也作为接口中的泛型类型
    public void print(S t){
        System.out.println(t);
    }
}
public class Test2 {
    public static void main(String[] args){
        IMessage<String>msg=new MessageImpl<String>();
        msg.print("HelloWorld");
    }
}
//结果
//HelloWorld

Implementation method 2: No generic type is set in the subclass, but a generic type is explicitly defined for the parent class interface.

package Project.Study.Genericity;

interface IMessage1<T>{
    public void print(T t);
}
class MessageImpl1 implements IMessage1<String>{
    public void print(String t){
        System.out.println(t);
    }
}
public class Test3 {
    public static void main(String [] args){
        IMessage1<String>msg=new MessageImpl1();
        msg.print("HelloWorld");
    }
}
//结果
//HelloWorld

Generic method

package Project.Study.Genericity;

public class Test4 {
    public static void main(String [] args){
        String str=fun("HelloWorld");
        System.out.println(str.length());
    }

    /**
     * 此方法为泛型方法,T的类型由传入的参数类型决定
     * 必须在方法返回值前明确定义泛型标记
     * @param t 参数类型,同时也决定了返回值类型
     * @param <T>
     * @return  直接返回设置进来的内容
     */
    public static <T>T fun(T t){
        return t;
    }
}
//结果
//10
49 original articles published · 25 praised · 1526 visits

Guess you like

Origin blog.csdn.net/weixin_45784666/article/details/104544839