【java学习—十一】泛型(1)

文章目录

  • 1. 为什么要有泛型Generic
  • 2. 泛型怎么用
    • 2.1. 泛型类
    • 2.2. 泛型接口
    • 2.3. 泛型方法
  • 3. 泛型通配符
    • 3.1. 通配符
    • 3.2. 有限制的通配符


1. 为什么要有泛型Generic

在这里插入图片描述

    泛型,JDK1.5新加入的,解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化时只要指定好需要的具体的类型即可。
    Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮。

举例:

package day11;

import java.util.ArrayList;
import java.util.List;

public class Test {
	public static void main(String[] args) {
		List list = new ArrayList<>();
		
		//不指定泛型,可以向list集合中添加各种类型元素
		list.add(111);
		list.add("sss");
		list.add(true);
		
		//需求,只能在集合中存字符串
		List<String> l = new ArrayList<String>();
		
		l.add("xx");
//		l.add(111);//指定的String类型,不可以添加String以外的元素类型
		
		
	}

}

    Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦除,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段
    解释:
    视频中老师说:比如上段代码中最后一行的l.add(111)在编译期间就会报错,只有删除这一行,或者将里面的数据改成String类型后,才可以通过编译。

2. 泛型怎么用

2.1. 泛型类

对象实例化时不指定泛型,默认为: Object 。
泛型不同的引用不能相互赋值。

package day11;

import java.util.ArrayList;
import java.util.List;

public class Test {
	public static void main(String[] args) {

		A<String> a1 = new A<String>();//在new A的对象的时候,指定泛型的类型String
		a1.setKey("xxxx");//对象使用setKey(T key)方法,中的key形参就是String
		System.out.println(a1.getKey());//T getKey(),返回值就有new对象确定返回值是String
		
		A<Integer> a2 = new A<Integer>();
		a2.setKey(1);
		Integer i = a2.getKey();
		
		A a3 = new A();//不指定泛型,相当于指定了一个Object类型
		//A<Object> a3 = new A<Object>();//等同于上行代码
		a3.setKey(new Object());
		Object obj = a3.getKey();
		
		//同样的类,但是在new对象时指定不同的数据类型,那么这些对象不能互相赋值
		a1 = a2;//错误,不同的数据类型不能互相赋值
		
		
	}

}

/**
 * 此处的泛型‘T’可以任意的取名,即可换成A,B,C等
 * 一般使用T,译为type
 * @author 14532
 *
 * @param <T>
 */
class A<T>{//< >中的内容可以任何取名,按惯例是T
	private T key;
	public void setKey(T key) {
		this.key = key;
	}
	
	public T getKey() {
		return this.key;
	}
}

2.2. 泛型接口

定义一个泛型接口:

interface Generator<T> {
    T next();
}

①未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
②如果实现接口时,指定接口的泛型的具体数据类型,这个类实现接口所有方法的位置都要替换实际的具体数据类型

举例:

package day11;

public class Test1 {
	public static void main(String[] args) {
		B1<Object> b1 = new B1<Object>();
		B1<String> b11 = new B1<String>();
		
		B2 b2 = new B2();//不用指定泛型,指定泛型反而会报错
	}
}

interface IB<T>{
	T test(T t);
}


/**
 * 未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
 * @author 14532
 *
 * @param <T>
 */
class B1<T> implements IB<T>{//B1<T>:未传入实参,将泛型的声明<T>也一起加到类中
	
	@Override
	public T test(T t) {
		return t;
	}
}


/**
 * 如果实现接口时指定接口的泛型的具体数据类型
 * 这个类实现接口所有方法的位置都要替换实际的具体数据类型
 * @author 14532
 *
 */
class B2 implements IB<String>{
	
	@Override
	public String test(String t) {
		return null;
	}
}

2.3. 泛型方法

    方法,也可以被泛型化,不管此时定义在其中的类是不是泛型化的。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。

泛型方法的格式:

public class DAO {
    public <E> void show(E e){
        System.out.println(e.toString());
    }
    public <T> T show1(T t){
        return t;
    }
}

举例:



class Cc{
	
    /**
     * 无返回值的泛型方法
     * @param <T>
     * @param s
     */
	public <T> void test(T s) {
		T t = s;
	}
	
	/**
	 * 有返回值的泛型方法
	 * @param <T>
	 * @param s
	 * @return
	 */
	public <T> T test1(T s) {
		return s;
	}
	
	
	/**
	 * 形参为可变参数的泛型方法
	 * @param <T>
	 * @param strs
	 */
	public <T> void test2(T... strs) {
		for(T s : strs) {
			System.out.println(s);
		}
	}
	
}

举例2:

package day11;

public class Test1 {
	public static void main(String[] args) {

		Cc<Object> c = new Cc<Object>();
		c.test("xxx");
		//泛型方法在调用之前没有固定的数据类型
		//在调用时,传入的参数是什么类型,就会把泛型改成什么类型
		//也就是说,泛型方法会在调用时确定泛型的具体数据类型
		Integer i = c.test1(2);//传递的参数是Integer,泛型就固定成Integer,返回值就是Integer
		Boolean b = c.test1(true);//传递的参数是Boolean,泛型就固定成Boolean,返回值就是Boolean
		
	}
}





class Cc<E>{
	private E e;
	
//	public static void test3() {
//		//在静态方法中不能使用类定义的泛型,如果要使用泛型,只能使用静态方法自己定义的泛型
//		//System.out.println(this.e);
//	}
	/**
	 * 静态方法的泛型方法
	 * @param <T>
	 * @param t
	 */
	public static <T> void test3(T t) {
		//在静态方法中不能使用类定义的泛型,如果要使用泛型,只能使用静态方法自己定义的泛型
		System.out.println(t);
	}
    /**
     * 无返回值的泛型方法
     * @param <T>
     * @param s
     */
	public <T> void test(T s) {
		//在类上定义的泛型,可以在普通的方法中使用
		System.out.println(this.e);
		T t = s;
	}
	
	/**
	 * 有返回值的泛型方法
	 * @param <T>
	 * @param s
	 * @return
	 */
	public <T> T test1(T s) {
		return s;
	}
	
	
	/**
	 * 形参为可变参数的泛型方法
	 * @param <T>
	 * @param strs
	 */
	public <T> void test2(T... strs) {
		for(T s : strs) {
			System.out.println(s);
		}
	}
	
}

3. 泛型通配符

3.1. 通配符

不确定集合中的元素具体的数据类型,使用"?"表示所有类型
如:

	public void test(List<?> list){
		System.out.println(list);
	}

举例:

package day11;

import java.util.ArrayList;
import java.util.List;

public class Test2 {
	public static void main(String[] args) {
		Dd d = new Dd();
		List<String> l1 = new ArrayList<String>();//?:可以代表各种类型,如String、Integer
		d.test(l1);
		
		List<Integer> l2 = new ArrayList<Integer>();
		d.test(l2);
	}

}

class Dd {
	public void test(List<?> list) {//test方法需要一个list集合的参数,不确定list集合中到底是存的数据的类型是什么
		
	}
}

3.2. 有限制的通配符

举例:

<? extends Person> (无穷小, Person)
只允许泛型为Person及Person父类的引用调用

<? super Person> [Person, 无穷大]
只允许泛型为Person及Person父类的引用调用

<? extends Comparable>
只允许泛型为实现Comparable接口的实现类的引用调用

举例:

package day11;

import java.util.ArrayList;
import java.util.List;

public class Test2 {
	public static void main(String[] args) {
		Dd d = new Dd();
		
		//list参数的元素数据类型是CC1及其子类
		List<CC1> lc = new ArrayList<CC1>();
		d.test1(lc);
		
		List<DD1> ld = new ArrayList<DD1>();
		d.test1(ld);
		
//		List<BB1> lb = new ArrayList<BB1>(); //BB1不是CC1的子类
//		d.test1(lb);
		
		
		//list参数的元素数据类型是CC1及其父类 
		d.test2(lc);
		
		List<BB1> lb = new ArrayList<BB1>();
		d.test2(lb);
		
		List<AA1> la = new ArrayList<AA1>();
		d.test2(la);
		
//		d.test2(ld);//DD1不是CC1的父类
		
		//list参数的元素数据类型是IA的实现类
		List<IAImpl> lia = new ArrayList<IAImpl>();
		d.test3(lia);
		
//		d.test3(la);//AA1不是IA的实现类

	}
}

class Dd {
	public void test(List<?> list) {//test方法需要一个list集合的参数,不确定list集合中到底是存的数据的类型是什么
		
	}
	
	public void test1(List<? extends CC1> list) {//list参数的元素数据类型是CC1及其子类
		
	}
	
	public void test2(List<? super CC1> lsit) {//参数的元素数据类型是CC1及其父类 
		
	}
	
	public void test3(List<? extends IA> lsit) {//list参数的元素数据类型是IA的实现类
		
	}
}


class AA1{}

class BB1 extends AA1{}

class CC1 extends BB1{}

class DD1 extends CC1{}

interface IA{}

class IAImpl implements IA{}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/112139.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android原生项目集成uniMPSDK(Uniapp)遇到的报错总结

uni小程s序SDK 集成到Android原生项目:老项目中用到的库较多&#xff0c;会出现几种冲突问题&#xff0c;总结如下&#xff1a; 报错1&#xff1a; Execution failed for task :app:processDebugManifest. > Manifest merger failed with multiple errors, see logs Andro…

【文献分享】基于线特征的激光雷达和相机外参自动标定

论文题目&#xff1a;Line-based Automatic Extrinsic Calibration of LiDAR and Camera 中文题目&#xff1a;基于线特征的激光雷达和相机外参自动标定 作者&#xff1a;Xinyu Zhang, Shifan Zhu, Shichun Guo, Jun Li, and Huaping Liu 作者机构&#xff1a;清华大学汽车安…

论文翻译-ImageNet Classification with Deep Convolutional Neural Networks

[toc] 前言 AlexNet是是引领深度学习浪潮的开山之作&#xff0c;即使是我们现在进入了ChatGPT时代&#xff0c;这篇论文依然具有一定的借鉴意义。AlexNet的作者是多伦多大学的Alex Krizhevsky等人。Alex Krizhevsky是Hinton的学生。网上流行说 Hinton、LeCun和Bengio是神经网…

go-gin-vue3-elementPlus带参手动上传文件

文章目录 一. 总体代码流程1.1 全局Axios部分样例1.2 上传业务 二. 后端部分三. 测试样例 go的mvc层使用gin框架. 总的来说gin的formFile封装的不如springboot的好.获取值有很多的坑. 当然使用axios的formData也有不少坑.现给出较好的解决办法 以下部分仅贴出关键代码 一. 总…

ORANGE室内高尔夫—韩国室内模拟高尔夫原装进口真实体验身临其境

ORANGE室内高尔夫—韩国室内模拟高尔夫 真实体验 身临其境 室内高尔夫的产品优势&#xff1a; 1. 实际高尔夫球场的限制&#xff1a;室内高尔夫可以弥补室外高尔夫球场数量有限的问题&#xff0c;使得更多人能够享受高尔夫运动。 2. 天气和季节的限制&#xff1a;室内高尔夫可…

苹果AirTag平替产品选择,国内外支持苹果Find My芯片功耗全面对比

2021年4月20,苹果在春季产品发布会上推出了全新的产品类型- AirTag,将哆啦A梦的追踪徽章带到了现实。这个小产品当年并没有像其它苹果新品那样一朝爆红。随着年轮缓缓而坚定地前行, AirTag也缓缓而坚定地前行,并被越来越多的人接受和喜欢。 深入思考AirTag背后的产品逻辑和实现…

前端基础之JavaScript

目录 一、JavaScript概述 二、JavaScript引入方式 三、JavaScript语言规范 四、JavaScript语言基础 五、JavaScript数据类型 数值(Number) 字符串(String) 布尔值(Boolean) null和undefined 对象(Object) forEach() map() 六、运算符 七、流程控制 八、函数 函…

10.31日模拟赛总结

文章目录 考试时间及策略考试结果考试反思题解A.进步科学B.吉吉没急C.老杰克哒D.季积晓淆 考试时间及策略 没啥好说的&#xff0c;因为好像都不会。所以全场感觉都在罚坐&#xff0c;很痛苦。 考试结果 30 0 50 5 85 考试反思 T1&#xff1a;T1是个神奇状压&#xff0…

vsCode安装CodeRunner插件输出中文乱码问题

1 vsCode下载 vcCode官网地址&#xff1a;https://code.visualstudio.com/ 2 安装CodeRunner 通过Ctrl Shift P 找到 settings找到code-runner.executorMap&#xff0c;在 settings.json 中加入 "code-runner.executorMap": {....."python": "s…

上班族如何做日程自律清单实现逆袭呢?电脑日程管理软件助力高效办公

越来越多的上班族都表示自己每天的工作任务非常多&#xff0c;经常从早忙到晚也无法按时完成工作&#xff0c;导致工作的拖延完成&#xff0c;这应该怎么办呢&#xff1f;其实对于职场人士来说&#xff0c;想要在工作中提升效率&#xff0c;就需要提前做好每天的工作日程安排&a…

如何在Android设备上检查应用程序使用情况,包括使用时间

你可能不知道自己花了多少时间在手机上。很可能你一天中有一半的时间都在盯着手机屏幕。如果你怀疑这一事实,你会很快核实的。在这篇文章中,我们将向你介绍如何在Android设备上检查应用程序的使用情况。 如何在Android上检查应用程序电池使用情况 你使用时间最长的应用程序…

腾讯云轻量级服务器哪个镜像比较好?

腾讯云轻量应用服务器镜像是什么&#xff1f;镜像就是操作系统&#xff0c;轻量服务器镜像系统怎么选择&#xff1f;如果是用来搭建网站腾讯云百科txybk.com建议选择选择宝塔Linux面板腾讯云专享版&#xff0c;镜像系统根据实际使用来选择&#xff0c;腾讯云百科来详细说下腾讯…

2023年四川省网络与信息安全技能大赛 决赛个人赛Writeup

文章目录 Web前端验证PHP_Try MiscHelloWorld密码在这easy_log Cryptobaser 线下“断网”CTF个人赛&#xff0c;题都很简单(新手级难度)&#xff0c;总共10道题目&#xff0c;解了6题。 赛题附件请自取&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1lgNEBO7a1L4KLE2t…

Academic Inquiry|如何阅读英文文献

相关素材&#xff1a; 知云文献阅读器、谷粉学术 相关可借鉴文章&#xff1a; [1]Academic Inquiry|国外文献查找-CSDN博客 [2]Academic accumulation|英文文献速读-CSDN博客 [3]Academic Inquiry|edge、chrome浏览器插件配置及相关问题解答-CSDN博客 一、相关素材准备 &#…

最新Ai智能创作系统源码V3.0,AI绘画系统/支持GPT联网提问/支持Prompt应用+搭建部署教程

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

kubernetes-service微服务

目录 一、service微服务 二、Ipvs模式 三、ClusterIP 1.ClusterIP 2.headless 四、NodePort 1.NodePort 2.默认端口 五、LoadBalancer 1.LoadBalancer 2.metallb 六、ExternalName 一、service微服务 Kubernetes Service微服务是一种基于Kubernetes的微服务架构&…

智慧矿山:AI算法在带式运输机中的异物识别应用

随着现代农业和工业的发展&#xff0c;带式运输机在各种生产作业中发挥着越来越重要的作用。然而&#xff0c;在带式运输机运行过程中&#xff0c;可能会混入各种异物&#xff0c;这些异物的存在可能会对运输过程和设备本身造成损害。为了解决这一问题&#xff0c;本文将介绍一…

一个极好用的浏览器标签页插件

这是我登录后&#xff0c;并且上传了个人壁纸的页面 Br标签页 一 . 我们来看看界面和功能1.注册登录2.首页及右键功能3.添加小组件和app网址4.切换壁纸5. 计划页面 二 . Edge浏览器安装和chrome&#xff08;谷歌&#xff09;浏览器安装1. Edge浏览器安装2. chrome&#xff08;谷…

【java】命令行,包

文件夹情况&#xff1a; HelloWorld.java package com.demo; public class HelloWorld{public static void print(){System.out.println("HelloWorld!");}public static void main(String[] args){print();} } import.java import com.demo.HelloWorld; public cla…

K8S的pod创建过程

创建流程图 用户发起请求创建deployment&#xff1b;apiserver收到创建资源的请求&#xff0c;apiserver对客户端操作进行身份认证&#xff0c;认证完成后接受该请求&#xff0c;并把相关的信息保存到etcd中&#xff0c;然后返回确认信息给客户端&#xff1b;apiserver向etcd…