首页 > 编程语言 >【Java基础知识3】泛型

【Java基础知识3】泛型

时间:2024-08-05 15:26:11浏览次数:16  
标签:Java array1 System 基础知识 类型 add 泛型 out

一、泛型的意义

泛型的本质是将类型参数化,从而达到代码复用。

即:在不创建新的类型下,通过泛型指定不同类型来控制形参具体类型,简单来讲就是,当我们不知道用什么数据类型接收数据的情况下,可以使用泛型来接收。

代码示例:

未使用泛型情况下:

private static int add(int a, int b) {
    System.out.println(a + "+" + b + "=" + (a + b));
    return a + b;
}

private static float add(float a, float b) {
    System.out.println(a + "+" + b + "=" + (a + b));
    return a + b;
}

private static double add(double a, double b) {
    System.out.println(a + "+" + b + "=" + (a + b));
    return a + b;
}

使用泛型情况下:

private static <T extends Number> double add(T a, T b) {
    System.out.println(a + "+" + b + "=" + (a.doubleValue() + b.doubleValue()));
    return a.doubleValue() + b.doubleValue();
}

二、泛型的使用

注:E e:Element元素,T t:Type类型

1.泛型类

格式:

修饰符 class 类名<泛型类型> { . . . } 

代码示例:

class GenericClass<E> {
	private E name;
	public void setName(E name) {
		this.name=name;
	}
	public E getName() {
		return this.name;
	}
}
public class GenericDemo {
	public static void main(String[] args) {
		//使用泛型,限定该类的数据类型为String类
		GenericClass<String> name1=new GenericClass<String>();
		name1.setName("使用泛型");
		String str1=name1.getName();
		System.out.println(str1);
		//不使用泛型,该类的数据类型默认为Object类
		GenericClass name2=new GenericClass();
		name2.setName("不使用泛型");
		Object obj1=name2.getName();
		System.out.println(obj1);
	}
}

2.泛型方法

格式:

修饰符 <泛型> 返回值类型 方法名(参数列表(泛型)){ 方法体 };

3.泛型接口

格式:


interface GenericInterface<I> {
	public void method(I i);
}
class Genericing implements GenericInterface<String> {
	public void method(String s) {
		System.out.println("泛型接口传参为:"+s);
	}
}
public class GenericDemo {
	public static void main(String[] args) {
		Genericing generic=new Genericing();
		generic.method("Test");
	}
}

4.泛型通配符

<?> 无限制通配符
<? extends E> extends 关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类
<? super E> super 关键字声明了类型的下界,表示参数化的类型可能是指定的类型,或者是此类型的父类

// 为了获得最大限度的灵活性,要在表示 生产者或者消费者 的输入参数上使用通配符,使用的规则就是:生产者有上限、消费者有下限
1. 如果参数化类型表示一个 T 的生产者,使用 < ? extends T>;
2. 如果它表示一个 T 的消费者,就使用 < ? super T>;
3. 如果既是生产又是消费,那使用通配符就没什么意义了,因为你需要的是精确的参数类型。

代码示例:

class IteratorArrayList {
	//由于不确定接收的ArrayList集合中的元素是什么类型,所以使用泛型通配符 ?
	//array1的元素为Integer类型,array2的元素为String类型
	public static void printing(ArrayList<?> array1) {
		Iterator<?> iterator=array1.iterator();
		while(iterator.hasNext()) {
			Object obj=iterator.next();//next()方法取出的元素类型是Object,可以接收任意的数据类型
			System.out.print(obj + " ");
		}
	}
}
public class GenericDemo {
	public static void main(String[] args) {
		//array1集合限定数据类型为Integer
		ArrayList<Integer> array1=new ArrayList<Integer>();
		array1.add(111);
		array1.add(222);
		array1.add(333);
		array1.add(444);
		array1.add(555);
		System.out.print("遍历Integer数据类型的array1集合:");
		IteratorArrayList.printing(array1);
		System.out.println();
		System.out.println("====================================");
		//array2集合限定数据类型为String
		ArrayList<String> array2=new ArrayList<String>();
		array2.add("一号");
		array2.add("二号");
		array2.add("三号");
		array2.add("四号");
		array2.add("五号");
		System.out.print("遍历String数据类型的array2集合:");
		IteratorArrayList.printing(array2);
	}
}

三、泛型的擦除

1.泛型擦除原则

  • 消除类型参数声明,即删除<>及其包围的部分;
  • 根据类型参数的上下界推断并替换所有的类型参数为原生态类型:如果类型参数是无限制通配符或没有上下界限定则替换为Object,如果存在上下界限定则根据子类替换原则取类型参数的最左边限定类型(即父类);
  • 为了保证类型安全,必要时插入强制类型转换代码;
  • 自动产生“桥接方法”以保证擦除类型后的代码仍然具有泛型的“多态性”。

2.无限制类型擦除

当类定义中的类型参数没有任何限制时,在类型擦除中直接被替换为Object,即形如<T><?>的类型参数都被替换为Object。

3.有限制类型擦除

当类定义中的类型参数存在限制(上下界)时,在类型擦除中替换为类型参数的上界或者下界,比如形如<T extends Number><? extends Number>的类型参数被替换为Number<? super Number>被替换为Object。

4.擦除方法定义中的类型参数

标签:Java,array1,System,基础知识,类型,add,泛型,out
From: https://blog.csdn.net/HollyShit_/article/details/140822490

相关文章

  • 【Java基础知识5】异常
    一、什么是异常?正常程序所不能处理或没有处理的不正常行为称为异常。Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。二、异常的层次结构三、异常的分类1.Throwable异常体系的顶层类,其派生出两个重要的子类, Error 和......
  • java面对对象基础
    1.对象的内存布局类实例化为对象:类实例化为对象的语句一定要加括号,否则编译不通过//类名生成对象名=new类名()//类名生成对象名=new类名()ToolMytool=newTool();classTool{ publicbooleanoddOreven(intnum){ if(num%2!=0){ returntrue; }else{ retur......
  • Java基础语法
    关键字和保留字在Java编程语言中,关键字和保留字是语言的基本组成部分。它们有特定的含义并在Java程序中扮演着重要的角色。理解这些关键字和保留字对于编写有效的Java代码至关重要。1.关键字(Keywords)关键字是Java语言中具有特殊含义的词,它们在编译器中被预定义并用于执行特定......
  • 我可以将 Python 与 javascript 结合起来用于网站或应用程序吗
    我不知道如果j添加Python和javascript可以吗我尝试过。但决定在继续之前询问一下是否可以继续但是如果我只使用javascript还是只使用python会更好吗?我只需要建议或答案将Python与Javascript结合用于网站或应用程序不仅完全可行,而且也是一种非常常见的做法!二者......
  • Python 网络抓取与请求和美丽的汤被需要 javascript 阻止
    我正在尝试从网站上抓取文本。我使用简单的代码:requests.get(url_here)。我的代码直到最近才有效。现在,当我使用请求时,我收到一条消息,而不是获取网站的文本:“该网站需要启用JavaScript!您使用的浏览器不支持JavaScript,或者已关闭JavaScript。“我已验证我的浏览器确实......
  • Java基于XXLJOB的定时任务实现阶梯式通知方式
    数据库表设计CREATETABLE`tx_order_push_info`(`order_no`varchar(64)DEFAULTNULLCOMMENT'交易单号',`order_id`decimal(11,0)DEFAULTNULLCOMMENT'交易单Id',`push_status`decimal(2,0)DEFAULTNULLCOMMENT'推送状态',`push_count......
  • Java RMI技术详解与案例分析
    JavaRMI(RemoteMethodInvocation)是一种允许Java虚拟机之间进行通信和交互的技术。它使得远程Java对象能够像本地对象一样被访问和操作,从而简化了分布式应用程序的开发。一些应用依然会使用RMI来实现通信和交互,今天的内容我们来聊聊RMI的那些事儿。一、先来了解一下概念RMI......
  • java笔记4
    7.封装封装是面向对象编程的四大基本特性之一,它将对象的数据(属性)和行为(方法)组合在一起,并隐藏内部的实现细节。何为封装封装是创建对象的过程,确保对象的内部状态只能通过对象提供的方法来访问和修改。访问修饰符private关键字private修饰的成员只能在类的内部访问,不能被......
  • QT-开发基础知识-全-
    QT开发基础知识(全)原文:FoundationsofQtDevelopment协议:CCBY-NC-SA4.0一、C++的Qt方式Qt是一个跨平台、图形化的应用开发工具包,使您能够在Windows、MacOSX、Linux和不同品牌的Unix上编译和运行您的应用。Qt的很大一部分致力于为一切事物提供平台中立的接口,从......
  • 2024最全 Java 面试八股文(程序员必备)
     一、Java基础篇1.接口和抽象类的区别相似点:(1)接口和抽象类都不能被实例化(2)实现接口或继承抽象类的普通子类都必须实现这些抽象方法不同点:(1)抽象类可以包含普通方法和代码块,接口里只能包含抽象方法,静态方法和默认方法,(2)抽象类可以有构造方法,而接口没有(3)抽象类中的成员变......