java中泛型之类型通配符(?)

简介:

实体类

package cn.xy.model;

/**
 * 生物类
 * @author xy
 * 
 */
public class Living
{
 private String name;

 public Living(String name)
 {
  super();
  this.name = name;
 }

 public String getName()
 {
  return name;
 }

 public void setName(String name)
 {
  this.name = name;
 }

 @Override
 public String toString()
 {
  return name;
 }
}

 

/**
 * 动物类
 * @author xy
 * 
 */
public class Animal extends Living
{
 public Animal(String name)
 {
  super(name);
 }
}

 

/**
 * 猫类
 * @author xy
 *
 */
public class Cat extends Animal
{
 public Cat(String name)
 {
  super(name);
 }
}


/**
 * 狗类
 * @author xy
 *
 */
public class Dog extends Animal
{
 public Dog(String name)
 {
  super(name);
 }
}

 

测试类1

import java.util.ArrayList;
import java.util.List;
import cn.xy.model.Animal;
import cn.xy.model.Cat;
import cn.xy.model.Dog;
import cn.xy.model.Living;

public class Test
{
 /**
  * 虽Cat和Dog是Animal的子类,但List<Cat>和List<Dog>不是List<Animal>的子类

  * 直接为该方法传入List<Cat>和List<Dog>编译会错误 。
  * 如List<Stirng>不是List<Object>的子类一样。
  */
 public static void GetNames1(List<Animal> animals)
 {
  for (Animal a : animals)
  {
   System.out.println(a.getName());
  }
 }

 /**
  * 该方法使用类型通配符,可以使用任何类型的List来调用它,其类型均为Object
  */
 public static void GetNames2(List<?> animals)
 {
  for (Object obj : animals)
  {
   Animal a = (Animal) obj;
   System.out.println(a.getName());
  }
 }

 /**
  * 该方法设置了类型通配符的上限,即传入的List的类型必须是Animal的子类或者Animal本身
  */
 public static void GetNames3(List<? extends Animal> animals)
 {
  for (Animal a : animals)
  {
   System.out.println(a.getName());
  }
 }

 /**
  * 该方法设置了类型通配符的下限,即传入的List的类型必须是Animal的父类或者Animal本身
  */
 public static void GetNames4(List<? super Animal> animals)
 {
  for (Object a : animals)
  {
   System.out.println(a);
  }
 }

 public static void main(String[] args)
 {
  List<Cat> cats = new ArrayList<Cat>();
  cats.add(new Cat("Tomcat"));
  cats.add(new Cat("Tomcat2"));

  List<Dog> dogs = new ArrayList<Dog>();
  dogs.add(new Dog("Tomdog"));
  dogs.add(new Dog("Tomdog2"));

  List<Living> livings = new ArrayList<Living>();
  livings.add(new Living("living1"));
  livings.add(new Living("living2"));

  // GetNames1(cats);
  // GetNames1(dogs);
  GetNames2(cats);
  GetNames2(dogs);
  GetNames3(cats);
  GetNames3(dogs);
  // GetNames4(cats);
  // GetNames4(dogs);
  GetNames4(livings);

 }
}


测试类2

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

public class Test2
{

 /**
  * 添加的对象必须是和?一样的类型或者是其子类,但并不知道?是什么类型 所以lst.add会产生编译错误,故不能向其中添加对象
  * null值是一个例外,因为null是所有引用类型的实例
  */
 public static void main(String[] args)
 {
  List<?> lst = new ArrayList<String>();
  // lst.add("str");
 }

}

本文转自IT徐胖子的专栏博客51CTO博客,原文链接http://blog.51cto.com/woshixy/1030100如需转载请自行联系原作者


woshixuye111

相关文章
|
5天前
|
存储 Java 开发者
Java 中 Set 类型的使用方法
【10月更文挑战第30天】Java中的`Set`类型提供了丰富的操作方法来处理不重复的元素集合,开发者可以根据具体的需求选择合适的`Set`实现类,并灵活运用各种方法来实现对集合的操作和处理。
|
5天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
13 2
|
15天前
|
Java API
[Java]泛型
本文详细介绍了Java泛型的相关概念和使用方法,包括类型判断、继承泛型类或实现泛型接口、泛型通配符、泛型方法、泛型上下边界、静态方法中使用泛型等内容。作者通过多个示例和测试代码,深入浅出地解释了泛型的原理和应用场景,帮助读者更好地理解和掌握Java泛型的使用技巧。文章还探讨了一些常见的疑惑和误区,如泛型擦除和基本数据类型数组的使用限制。最后,作者强调了泛型在实际开发中的重要性和应用价值。
14 0
[Java]泛型
|
27天前
|
Java 编译器
Java“返回类型为 void 的方法不能返回一个值”解决
在 Java 中,如果一个方法的返回类型被声明为 void,那么该方法不应该包含返回值的语句。如果尝试从这样的方法中返回一个值,编译器将报错。解决办法是移除返回值语句或更改方法的返回类型。
|
29天前
|
设计模式 Java
Java“不能转换的类型”解决
在Java编程中,“不能转换的类型”错误通常出现在尝试将一个对象强制转换为不兼容的类型时。解决此问题的方法包括确保类型间存在继承关系、使用泛型或适当的设计模式来避免不安全的类型转换。
|
24天前
|
存储 安全 Java
🌱Java零基础 - 泛型详解
【10月更文挑战第7天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
10 1
|
26天前
|
Java
Java 中锁的主要类型
【10月更文挑战第10天】
|
1月前
|
Java 语音技术 容器
java数据结构泛型
java数据结构泛型
26 5
|
29天前
|
存储 Java 编译器
Java集合定义其泛型
Java集合定义其泛型
17 1
|
1月前
|
存储 Java 编译器
【用Java学习数据结构系列】初识泛型
【用Java学习数据结构系列】初识泛型
18 2
下一篇
无影云桌面