Java-特性-可变参数、泛型

一、可变参数

可变参数本质就是动态创建的数组

修饰符 返回值类型 方法名(数据类型 … 变量名){ // 可变参数,可接受0个值,可n个值
    方法体
}

注意:

  1. 可变参数本质就是一个数组,arr就是一个数组的引用地址(反编译工具查看源代码);
  2. 一个方法可以有可变参数和普通参数,但是可变参数必须放到参数列表末尾;
  3. 一个方法有且只能有一个可变参数;

增强for循环:对数组或者集合的输出,使用 for(数据类型 变量 : 数组|集合){…}

package com.joeaaa.demo10;

public class VarArgs {
    public static void main(String[] args) throws Exception {
        System.out.println(add(1,2,3)); // 6
    }
    public static int add(int ... data){
        int sum = 0;
        for (int datum : data) {
            sum += datum;
        }
        return sum;
    }
}

二、泛型

在定义的时候不声明类中操作的属性或方法的参数类型,而是在使用时动态配置。

package com.joeaaa.demo10;
/*
* 泛型
*/
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;
    }
}
/*
* 使用范型
*/
public class GenericClassTest1
{
    public static void main(String[] args) {
        // 设置
        Point<String> point = new Point<String>();
        point.setX("东经100度");
        point.setY("北纬20度");
        // 取出
        String x = point.getX(); // 无需向下转型
        String y = point.getY();
        System.out.println("X坐标为:"+ x + ",Y坐标为:"+y);
        // X坐标为:东经100度,Y坐标为:北纬20度
    }
}

使用通配符?表示任意范型。此方法可以接收,任意泛型,但不能进行赋值修改。

public static void print(Message<?> temp){
    System.out.println(temp.getInfo()); // 只能输出
}

泛型的上限与下限

上限:在类定义时使用。? extends Number,表示只能是Number或者是Number的子类Integer等;

package com.joeaaa.demo10;
/*
* 泛型,设置上限
*/
class Messages<T extends Number>{
    private T info;
    public void setInfo(T info){
        this.info = info;
    }
    public T getInfo(){
        return info;
    }
}

public class GenericClassUpper {
    public static void main(String[] args) {
        Messages<Integer> msg = new Messages<Integer>(); // Integer是Number的子类
        msg.setInfo(100);
        print(msg); // 引用传递
    }
    public static void print(Messages<?> temp){
        System.out.println(temp.getInfo()); // 只是输出,100
    }
}

下限:在方法的参数上使用。? super String,表示只能时String或者是String的父类(Object)

package com.joeaaa.demo10;
/*
* 设置泛型下限
*/

class Message<T>{
    private T info;
    public void setInfo(T info){
        this.info = info;
    }
    public T getInfo(){
        return info;
    }
}

public class GenericClassLower {
    public static void main(String[] args) {
        Message<String> msg = new Message<String >(); // Integer是Number的子类
        msg.setInfo("Hello,world!");
        print(msg); // 引用传递
    }
    // 只能是String的泛型或者是Object的泛型使用
    public static void print(Message<? super String> temp){
        System.out.println(temp.getInfo()); // 只是输出,Hello,world!
    }
}

泛型接口

interface Message<T>{
    public String echo(T msg);
}

泛型接口的实现

  1. 在子类上继续定义泛型,同时此泛型在接口上继续使用;
  2. 在子类上设置具体类型;
package com.joeaaa.demo10;
/*
* 泛型接口
*/
interface Message1<T>{
    String echo(T msg);
}
class Message1Impl<T> implements Message1<T>{
    public String echo(T msg){
        return "ECHO: "+ msg;
    }
}

public class GenericClassInterface1 {
    public static void main(String[] args) {
        Message1<String> msg = new Message1Impl<>();
        System.out.println(msg.echo("Alex"));
    }
}
package com.joeaaa.demo10;

/*
 * 泛型接口,在子类上设置具体类型
 */
interface Message2<T>{
    String echo(T msg);
}
class Message2Impl implements Message2<String>{
    public String echo(String msg){
        return "ECHO: "+ msg;
    }
}

public class GenericClassInterface2 {
    public static void main(String[] args) {
        Message1<String> msg = new Message1Impl();
        System.out.println(msg.echo("Alex"));
    }
}