程序员的语法糖?java泛型浅析

泛型

指的是在类定义的时候并不会设置类中的属性或方法中的具体类型,而是在类使用时再进行定义。

泛型是JAVA中的语法糖。(语法糖:方便开发者开发,在运行阶段无用)

泛型的作用:

1.类型不一致会在编译期报错,确保在创建对象,存放对象或调用方法时使用的是正确的类型。

2.杜绝了向下转型带来的安全隐患,避免在运行时出现ClassCastException

 

泛型类:

示例:

public class Myclass <T> {

    T value1;

    T value2;

    public Myclass(T value1,T value2){

        this.value1=value1;

        this.value2=value2;

    }

    public void Print() {

        System.out.println("value1:"+value1);

        System.out.println("value2:"+value2);

    }

 

创建对象:     

Myclass<String> m1=new Myclass<String>("Hello","bit");

m1.Print();//调用方法

当然泛型也可以指定为任何引用类型,甚至是自己定义的类型:

public class Myclass <T> {
	T value1;
	T value2;
	public Myclass(T value1,T value2){
		this.value1=value1;
		this.value2=value2;
	}
	public void Print() {
		System.out.println("value1:"+value1);
		System.out.println("value2:"+value2);
	}
	public static void main(String[] args) {
		Myclass<String> m1=new Myclass<String>("Hello","bit");
		m1.Print();
		Myclass<Integer> m2=new Myclass<Integer>(10,12);
		m2.Print();
		Myclass<Double> m3=new Myclass<Double>(20.2,13.0);
		m3.Print();
		Myclass<Class1> m4=new Myclass<Class1>(new Class1("bit"),new Class1("bit"));//自己定义的类型
		m4.Print();
	}
}
class Class1 {
	String value;
	public Class1(String Name) {
		this.value=Name;
	}
	@Override
	public String toString() {
		return this.value;
	}
}

在JDK1.7之后:创建对象是后面的一个泛型参数可以不写,即:
 

Myclass<String> m1=new Myclass<>("Hello","bit");

泛型接口:

扫描二维码关注公众号,回复: 2989560 查看本文章

使用方法与泛型接口基本相同,但是在在子类实现接口的时候有两种方法

1.子类实现仍然使用泛型。

interface IF<T>{
	void Print();
}
public class Myclass <T> implements IF<T> { //Myclass仍然使用泛型,子类的使用与泛型类使用一致
	T value1;
	T value2;
	public Myclass(T value1,T value2){
		this.value1=value1;
		this.value2=value2;
	}
	public void Print() {
		System.out.println("value1:"+value1);
		System.out.println("value2:"+value2);
	}

2.子类指定具体类型,则后面子类只能使用指定的类型

interface IF<T>{
	void Print();
}
public class Myclass implements IF<String> {
	String value1;
	String value2;
	public Myclass(String value1,String value2){
		this.value1=value1;
		this.value2=value2;
	}
	public void Print() {
		System.out.println("value1:"+value1);
		System.out.println("value2:"+value2);
	}
	public static void main(String[] args) {
		Myclass m1=new Myclass("Hello","bit");
		m1.Print();

 

泛型方法:

示例:

	public <T> T Method(T t) {
		return t;
	}

使用时直接调用即可,如:
        new Mylass().Method("bit");

 

在一个类中可以同时使用了泛型类和泛型方法:
 

public class Myclass<V>{
	V value1;
	V value2;
	public Myclass(V value1,V value2){
		this.value1=value1;
		this.value2=value2;
	}
	public <T> T Method(T t) {
		return t;
	}
	public void Print() {
		System.out.println("value1:"+value1);
		System.out.println("value2:"+value2);
	}
	public static void main(String[] args) {
		Myclass<String> m1=new Myclass<String>("Hello","bit");
		m1.Print();
		m1.Method(20);
    }
}

 

在上一个例子中,V和K表示的不是同一种类型,所以V在创建对象时被指定为了String类型,但是Method方法同样可以使用其他类型。同时不建议泛型类和泛型方法的泛型使用同一个字母。

在通配符:

可以接受所有的泛型参数但是不能让用户随意修改。

public class Myclass<V>{
	V value1;
	public Myclass(V value1){
		this.value1=value1;
	}
	
	public V getValue1() {
		return value1;
	}

	public void setValue1(V value1) {
		this.value1 = value1;
	}

	public static void Print(Myclass<?> m) {
		System.out.println("value1:"+m.value1);
//		m.setValue1(15);   通配符取得的值不可以修改,只可以访问
	}
	public static void main(String[] args) {
		Myclass<String> m1=new Myclass<String>("Hello");
		Print(m1);
		Print(new Myclass<Integer>(10));
	}
}

< ?  extends T >

设置类型上限,可以用于类或方法,所指定的类型只能是T及T的子类。在方法中还是不可以修改其值。

public class Myclass<V extends Number>{
	V value1;
	public Myclass(V value1){
		this.value1=value1;
	}
	
	public V getValue1() {
		return value1;
	}

	public void setValue1(V value1) {
		this.value1 = value1;
	}

	public static void main(String[] args) {
		Myclass<Integer> m1=new Myclass<>(11);
		Myclass<Double> m3=new Myclass<Double>(20.2);
    }
}

 

	public <T extends Number> void Print(T A) {
		System.out.println("value1:"+A);
	}

 

< ? super T >

设置类型下限,只可用于方法,可以修改其值。

	public static void Print(Myclass <? super Integer> m ) {
		System.out.println("value1:"+m.value1);
	}

//调用:
        Myclass<Integer> m1=new Myclass<>(11);
		Print(m1);

类型擦除:

泛型是通过类型擦除来实现的,编译器在编译时(进入JVM之前)擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息这样做的目的,是确保能和Java 5之前的版本开发二进制类库进行兼容。你无法在运行时访问到类型参数,因为编译器已经把泛型类型转换成了原始类型。

public class Myclass<V>{
	V value1;
	public Myclass(V value1){
		this.value1=value1;
	}
	
	public V getValue1() {
		return value1;
	}

	public void setValue1(V value1) {
		this.value1 = value1;
	}

	public void Print() {
		System.out.println("value1:"+value1);
	}
	public static void main(String[] args) {
		Myclass<Integer> m1=new Myclass<>(11);
		Myclass<Double> m2=new Myclass<Double>(20.2);
		System.out.println(m1.getClass()==m2.getClass()); //打印结果为true

	}
}

猜你喜欢

转载自blog.csdn.net/weixin_41891854/article/details/81264941