Java学习笔记(泛型)

知识点总结于毕向东Java基础视频教程25天版本,侵权请联系删除。

泛型

概述

泛型:把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。

泛型的特点:

  • 提高了程序的安全性
  • 将运行期遇到的问题转移到了编译期
  • 省去了类型强转的麻烦
  • 泛型类的出现优化了程序设计

泛型的格式:

  • 通过<>来定义要操作的引用数据类型
import java.util.*;
class Demo2
{
	public static void main(String[] args) 
	{
		TreeSet<String> ts = new TreeSet<String>(new LenComparator());

		ts.add("abcd");
		ts.add("cc");
		ts.add("cba");
		ts.add("aaa");
		ts.add("z");
		ts.add("hahaha");

		Iterator<String> it = ts.iterator();
		while(it.hasNext())
		{
			String s = it.next();
			System.out.println(s);
		}
	}
}

class LenComparator implements Comparator<String> //比较器也需要泛型
{
	public int compare(String o1,String o2)
	{
		int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
		//倒序int num = new Integer(o2.length()).compareTo(new Integer(o1.length()));
		if(num==0)
			return o1.compareTo(o2);
		return num;
	}
}
如果想要容器倒序,只需要将调用比较方法的对象和比较对象互换位置。

泛型类

  • 格式 class 类名称<T>
    T为泛型,它可以是任意的对象或接口,但不能是基本类型
  • 什么时候定义泛型类?
    当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。
    现在定义泛型来完成扩展。

示例:

class Demo
{
	public static void main(String[] args){
		Person<Student> s=new Person<Student>(); //泛型类为
		s.setT(new Student());
		System.out.println(s.getT(new Student()));
	}
}

class Person<T> //T可以是任意对象或接口,它就是代表一个参数
{
	private T t;
	public void setT(T t){
		this.t=t;
	}
	public T getT(T t){
		return t;
	}
}

class Student
{
}

用Object类实现:

class Demo
{
	public static void main(String[] args){
		ObjectDemo o=new ObjectDemo();
		o.setObj(new Student());
		Student s2=(Student)o.getObj();//需要将返回的Obj类型强制转换成对应的类型
	}
}

class ObjectDemo
{
	private Object o;
	public void setObj(Object o)
	{
		this.o=o;
	}
	public Object getObj(){
		return o;
	}
}

class Student
{
}

但我们如果将强制转换改成:

	String s2=(String)o.getObj();

在编译时期不会出错,但是在运行时就会报错。
这是因为编译器在编译时不知道你传进去的是什么类型,且getObj方法返回的是Object类型,所以将Object转换为String类型是可以的。但是在运行时,我们是将Student类型的对象通过setObj方法传递给了o,再通过setObj返回了一个Student类型对象,而此时再将Student类型转换为String类型是不可能通过的。

而使用泛型,就不再需要强制转换,且如果传入类型不对,在编译时期就会报错。

泛型方法

泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。

为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。

class Demo
{
	public static void main(String[] args){
		//泛型类只能使用声明的类型
		Person<String> p=new Person<String>();
		p.print("haha");
		//p.print(123); 

		//泛型方法可以操作不同的类型
		People p2=new People();
		p2.print("haha");
		p2.print(123);
	}
}

class Person<T>
{
	public void print(T t){
		System.out.println(t);
	}
}

class People
{
	public <T> void print(T t){
		System.out.println(t);
	}
}
泛型类上也能定义泛型方法,效果也是一样的。

对于静态方法,它不可以访问类上定义的泛型。
如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

	class Person
	{
		public static <T> void print(T t){...}
	}

泛型接口

将泛型定义在接口上:

interface Inter<T>
{
	void show(T t);
}

//该类不属于泛型类,并将泛型变量T填充为String类型
class InterImplFixed implements Inter<String> 
{
	public void show(String t)
	{
		System.out.println("show :"+t);
	}
}

//用泛型类实现泛型接口
class InterImpl<T> implements Inter<T>
{
	public void show(T t)
	{
		System.out.println("show :"+t);
	}
}

class Demo
{
	public static void main(String[] args) 
	{
		//非泛型类
		InterImplFixed inf=new InterImplFixed();
		inf.show("4");

		//泛型类
		InterImpl<Integer> i = new InterImpl<Integer>();
		i.show(4);
	}
}

使用泛型类来继承泛型接口的作用就是让用户来定义接口所使用的变量类型,而不是像方法一那样,在类中写死。

泛型的限制

无界通配符

无界通配符:类型通配符一般使用?代替具体的类型实参。当操作类型时不需要使用类型的具体功能时,只使用Object类中的功能,那么可以用 ? 通配符来表未知类型。

  • 类型参数<T>主要用于声明泛型类或泛型方法。 无界通配符<?>主要用于使用泛型类或泛型方法。
public class Test1 {
     public <T> void test1(List<T> list){
        System.out.println("list length: " + list.size());  
        if (!list.isEmpty()) {
            T t = list.get(0); //list中的元素为T类型
            System.out.println("t = " + t);
        }
    }
 
    public void test2(List<?> list){
        System.out.println("list length: " + list.size());
        if (!list.isEmpty()) {
            Object o = list.get(0);//list中的元素为Object
            System.out.println("o = " + o);
        }
    }
}
<?>代表任意java类型,只有在不关心数据的具体类型下才使用通配符表示,但在一些情况下,需要将<?>传入的数据进行强转,但这样不如直接传入。

有界通配符

  • 上界通配符
    ?extends E:可以接收E类型或者E的子类型。代表上限。
  • 下界通配符
    ? super E:可以接收E类型或者E的父类型。代表下限。

示例:
在TreeSet构造方法中,有带比较器参数的构造方法:
在这里插入图片描述

import java.util.*;
class GenericDemo7 
{
	public static void main(String[] args) 
	{
		TreeSet<Student> ts = new TreeSet<Student>(new Comp());
		
		ts.add(new Student("abc03"));
		ts.add(new Student("abc02"));
		ts.add(new Student("abc06"));
		ts.add(new Student("abc01"));
		
		Iterator<Student> it = ts.iterator();

		while(it.hasNext())
		{
			System.out.println(it.next().getName());
		}

		TreeSet<Worker> ts1 = new TreeSet<Worker>(new Comp());

		ts1.add(new Worker("wabc--03"));
		ts1.add(new Worker("wabc--02"));
		ts1.add(new Worker("wabc--06"));
		ts1.add(new Worker("wabc--01"));

		Iterator<Worker> it1 = ts1.iterator();

		while(it1.hasNext())
		{
			System.out.println(it1.next().getName());
		}
	}
}

class Comp implements Comparator<Person>
{
	public int compare(Person p1,Person p2)
	{
		return p2.getName().compareTo(p1.getName());
	}
}

class Person
{
	private String name;
	Person(String name)
	{
		this.name = name;
	}
	public String getName()
	{
		return name;
	}
	public String toString()
	{
		return "person :"+name;
	}
}

class Student extends Person
{
	Student(String name)
	{
		super(name);
	}
}

class Worker extends Person
{
	Worker(String name)
	{
		super(name);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的纺织品企业财务管理系统,源码+数据库+毕业论文+视频演示 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对纺织品企业财务信息管理的提升,也为了对纺织品企业财务信息进行更好的维护,纺织品企业财务管理系统的出现就变得水到渠成不可缺少。通过对纺织品企业财务管理系统的开发,不仅仅可以学以致用,让学到的知识变成成果出现,也强化了知识记忆,扩大了知识储备,是提升自我的一种很好的方法。通过具体的开发,对整个软件开发的过程熟练掌握,不论是前的设计,还是后续的编码测试,都有了很深刻的认知。 纺织品企业财务管理系统通过MySQL数据库与Spring Boot框架进行开发,纺织品企业财务管理系统能够实现对财务人员,员工,收费信息,支出信息,薪资信息,留言信息,报销信息等信息的管理。 通过纺织品企业财务管理系统对相关信息的处理,让信息处理变的更加的系统,更加的规范,这是一个必然的结果。已经处理好的信息,不管是用来查找,还是分析,在效率上都会成倍的提高,让计算机变得更加符合生产需要,变成人们不可缺少的一种信息处理工具,实现了绿色办公,节省社会资源,为环境保护也做了力所能及的贡献。 关键字:纺织品企业财务管理系统,薪资信息,报销信息;SpringBoot
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值