泛型.

/**

* 泛型进阶

* 概念:泛型只是编译时的概念,供编译器进行语法检查时用的

* (由于程序员需要一种类型安全的集合,正是这种需求促成了泛型)

* 目的:

* 1.努力将运行时异常转换成编译时错误,减少运行时异常数量(提高了编译器的能力)

* 2.解决模板编程的问题

* 基本的用法:在使用集合时,用<>指定集合中可以放入的类型

* 注意:

* 1.属性中使用集合时不指定泛型,默认为<Object>

* 2.泛型不同的引用与对象之间都是不兼容的

* 3.引用的泛型与对象的泛型必须一致

*/

import java.util.*;

public class TestGenerics1 {

public static void main(String[] args) {

List<String> l=new ArrayList<String>();

l.add("ABC");

l.add("DEF");

String str=l.get(0);//使用泛型后,获得对象时不用进行强制类型转换

/*错误,试图将IntegerDouble类型的对象放入指定存放String类型对象的集合中

l.add(1);

l.add(1.5);

*/

for(String s:l){//for-each循环 (集合/数组中元素类型 变量:集合/数组名)

System.out.println(s);

}

Map<Integer,String> map=new HashMap<Integer,String>();

map.put(1,"Huxz");

map.put(2,"Liucy");

map.put(3,"TangLiang");

//map.put(1.5,"Liucy");

//map.put("Liucy",1.5);

Set<Integer> keys=map.keySet();

for(Integer i:keys){

String value=map.get(i);

System.out.println(i+"---"+value);

}

List<Number> list=new ArrayList<Number>();

list.add(10);

list.add(1.5);

/*

List<Number> list2;

List<Integer> list3=new ArrayList<Integer>();

list2=list3;

*/

}

 

}

 

/**

* 泛型的通配符(用于方法的参数)

* 1.<?> 允许所有泛型的引用调用

* 2.<? extends Number> 只允许泛型为NumberNumber子类的引用调用

* 3.<? super Number> 只允许泛型为NumberNumber父类的引用调用

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

* 注意:

* 1.方法参数中使用集合时不指定泛型,默认为<?>

* 2.方法参数中<? extends Number&Comparable>这种修饰符是不支持的

*/

import java.util.*;

import static java.lang.System.*;

public class TestGenerics2 {

public static void main(String[] args) {

List<String> l1=new ArrayList<String>();

List<Object> l2=new ArrayList<Object>();

List<Number> l3=new ArrayList<Number>();

List<Integer> l4=new ArrayList<Integer>();

List<Double> l5=new ArrayList<Double>();

print(l1);

print(l2);

print(l3);

print(l4);

print(l5);

}

//方法参数中使用集合时不指定泛型,默认为<?>

public static void print(List list){

for(Object o:list){

out.println(o);

}

}

/*<?> 允许所有泛型的引用调用

public static void print(List<?> list){

for(Object o:list){

out.println(o);

}

}

*/

/*<? extends Number> 只允许泛型为 NumberNumber子类的引用调用

public static void print(List<? extends Number> list){

for(Number o:list){

out.println(o);

}

}

*/

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

public static void print(List<? extends Comparable> list){

for(Comparable o:list){

out.println(o);

}

}

*/

/*<? super Number> 只允许泛型为NumberNumber父类的引用调用

public static void print(List<? super Number> list){

for(Object o:list){

out.println(o);

}

}

*/

/*方法参数中<? extends Number&Comparable>这种修饰符是不支持的

public static void print(List<? extends Number & Comparable> list){

for(Object o:list){

out.println(o);

}

}

*/

}

 

/**

* 泛型的通配符(用于泛型方法)

* 定义:修饰符 泛型 返回类型 方法名 参数表 抛出的异常

* 1.<T> 允许所有泛型的引用调用

* 2.<T extends Number> 只允许泛型为NumberNumber子类的引用调用

* 3.<T extends Comparable> 只允许泛型为实现了Comparable接口的实现类的引用调用

* 4.<T extends Number&Comparable>只允许泛型为既是NumberNumber子类 又实现了Comparable接口的实现类的引用调用

* 注意:

* 1.泛型方法中<? super Number>这种修饰符是不支持的

*/

import java.util.*;

public class TestGenerics3 {

public static void main(String[] args) {

List<String> l1=new ArrayList<String>();

List<Object> l2=new ArrayList<Object>();

List<Number> l3=new ArrayList<Number>();

List<Integer> l4=new ArrayList<Integer>();

List<Double> l5=new ArrayList<Double>();

String[] a1=new String[10];

Object[] a2=new Object[10];

Number[] a3=new Number[10];

Integer[] a4=new Integer[10];

Double[] a5=new Double[10];

copyFromArray(l1,a1);

copyFromArray(l2,a2);

copyFromArray(l3,a3);

copyFromArray(l4,a4);

copyFromArray(l5,a5);

}

public static <T > void copyFromArray(List<T> l,T[] a){

for(T o:a){

l.add(o);

}

}

/*<T extends Number> 只允许泛型为NumberNumber子类的引用调用

public static <T extends Number > void copyFromArray(List<T> l,T[] a){

for(T o:a){

l.add(o);

}

}

*/

/* 此处不许用super

public static <T super Number> void copyFromArray(List<T> l,T[] a){

for(T o:a){

l.add(o);

}

}

*/

//public static <T,V> void m(List<T> l1,List<V> l2){}

//<T extends Number&Comparable>只允许泛型为既是NumberNumber子类又

// 实现了Comparable<sp>

<think>嗯,用户想了解在类上定义的使用方法,特别是语法部分。他们提到对不太理解,需要多些例子和解释。首先,我得确认用户的基础,可能他们已经有Java或其他语言的经验,但概念比较模糊。 首先,我应该从基本概念入手,解释的作用,比如类安全,避免强制类转换,提高代码复用。然后,具体到在类上定义的语法:class 类名<1,2...>{},这部分需要详细展开,说明参数的位置和使用方法。 接下来,需要举几个例子,由浅入深。第一个例子可能是一个简单的容器类,比如Box<T>,展示如何用存储不同类的数据。这样用户能直观看到同一个类如何适应不同数据类。 然后,可能需要展示多个参数的例子,比如Pair<K,V>,说明如何处理多个类。这里可以结合不同数据类的组合,比如String和Integer,或者Integer和Double,让例子更生动。 还要注意边界情况,比如如果用户没有指定,会发生什么,这时候应该提到默认是Object,但可能引发类安全问题,强调使用的好处。 另外,用户可能需要了解在方法中的使用,但问题集中在类上,所以应该专注于类的例子,不过可以稍微提一下方法中的作为扩展。 可能用户在实际使用中会遇到如何限制的问题,比如使用extends关键字,但根据用户的问题描述,可能暂时不需要深入,但可以简单提及,作为进一步学习的点。 需要检查例子是否足够清晰,避免太过复杂的场景,确保每个步骤都有解释,比如类定义时的位置,实例化时如何指定具体类,以及如何在这些类中使用作为字段、方法参数或返回类。 还要注意术语的一致性,比如“类参数”和“参数”是否使用正确,避免混淆。同时,确保代码示例正确,没有语法错误,比如正确使用尖括号,避免中文符号。 最后,总结的优点,帮助用户巩固理解,并鼓励他们尝试自己编写代码,加深印象。可能还需要提醒常见的错误,比如忘记指定导致的类转换异常,或者误用原始类的情况。</think>在类上的使用是Java中非常重要的类安全机制,下面我用通俗易懂的方式配合多个示例为你讲解: --- ### 一、类基本概念 **作用**:让类可以处理多种数据类,同时保持类安全(避免强制类转换) **语法**: ```java class 类名<T1, T2...> { // T1, T2是类参数(标识符) // 类成员可以使用这些类 } ``` --- ### 二、基础示例 #### 示例1:最简单的类 ```java // 定义类 class Box<T> { private T content; public void set(T content) { this.content = content; } public T get() { return content; } } // 使用示例 Box<String> stringBox = new Box<>(); stringBox.set("Hello"); String str = stringBox.get(); // 直接获取String类,无需强制转换 Box<Integer> intBox = new Box<>(); intBox.set(100); int num = intBox.get(); // 直接获取Integer自动拆箱为int ``` **关键点**: - `T` 是类占位符 - 创建实例时指定具体类 - 编译器会进行类检查 --- #### 示例2:多个类参数的类 ```java class Pair<K, V> { private K key; private V value; public Pair(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } } // 使用示例 Pair<String, Integer> student = new Pair<>("Alice", 95); Pair<Integer, Double> coordinate = new Pair<>(10, 20.5); ``` --- ### 三、进阶使用示例 #### 示例3:类与集合结合 ```java class DataProcessor<T> { private List<T> dataList = new ArrayList<>(); public void addData(T data) { dataList.add(data); } public void processAll() { for(T item : dataList) { System.out.println("Processing: " + item); } } } // 使用示例 DataProcessor<LocalDate> dateProcessor = new DataProcessor<>(); dateProcessor.addData(LocalDate.now()); dateProcessor.addData(LocalDate.of(2023, 12, 25)); ``` --- #### 示例4:带有限制的(边界限定) ```java class NumberBox<T extends Number> { // 限定T必须是Number的子类 private T number; public double getSquare() { return number.doubleValue() * number.doubleValue(); } } // 正确使用 NumberBox<Integer> intBox = new NumberBox<>(); NumberBox<Double> doubleBox = new NumberBox<>(); // 错误使用(编译时报错) // NumberBox<String> stringBox = new NumberBox<>(); ``` --- ### 四、类的重要特性 1. **类安全**:编译时检查类错误 2. **消除强制转换**:获取数据时自动处理类 3. **代码复用**:同一套逻辑处理不同数据类 4. **类擦除**:运行时信息会被擦除(重要底层特性) --- ### 五、使用场景建议 1. 容器类(如自定义集合) 2. 数据包装类(如结果包装器) 3. 工具类(处理不同类数据的工具) 4. 需要类安全的回调机制 试着写一个简单的类,比如`Storage<T>`类,包含存储和获取数据的方法,这会帮助你更好地理解这个概念。如果遇到具体问题,可以随时问我!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值