java中的通配符

通配符的表示方法有<? extends T>,<? super T>,<?>.

<? extends T>表示可以引用T及T的子类

<? super T>表示可以引用T及T的父类

<?>表示无限定引用。

<? extends T>看起来与声明泛型类或函数里的类型限定<T extends A>类似,但两者有很大区别

先直观的看一下“T”,一个在extends前边,一个在extends后边。

类型限定是在声明类或函数时如:

public <T extends A>T func(T){};

通配符是在作为变量引用时使用如:

<? extends T> aObj = new Obj();

下面结合代码说明:

import java.lang.reflect.*;
class TestClass1<T>{
TestClass1(T t){
this.aT=t;
}
public T DispAndRet(){
Class<?> aDemo=null;
aDemo=aT.getClass();
Method aMethod=null;
try
{
aMethod=aDemo.getMethod("DispAndRet");
}
catch(Exception e)
{
System.out.println(aT.getClass()+": "+aT.toString());
return aT;
}
try
{
aMethod.invoke(aT);
}
catch (Exception e)
{
System.out.println("invoke error");
}
return aT;
}
private T aT;
}

class TestClass2<T> extends TestClass1<T>{
TestClass2(T t){
super(t);
}
}

class TestClass3<T> extends TestClass1<T>{
TestClass3(T t){
super(t);
}
}

public class Test2{
public static void main(String[] args){
TestClass1<String> aTest=new TestClass1<String>("this is test");
aTest.DispAndRet();

TestClass1<TestClass2> bTest=new TestClass1<TestClass2>(new TestClass2<String>("bTest ref TestClass2"));
bTest.DispAndRet();

//bTest=new TestClass1<TestClass3>(new TestClass3<String>("bTest ref TestClass3"));
//bTest.DispAndRet();

TestClass1<? extends TestClass1> cTest=new TestClass1<TestClass3>(new TestClass3<String>("cTest ref TestClass2"));
cTest.DispAndRet();

cTest=new TestClass1<TestClass2>(new TestClass2<String>("cTest ref TestClass3"));
cTest.DispAndRet();

cTest=new TestClass1<TestClass1>(new TestClass1<String>("cTest ref TestClass1"));
cTest.DispAndRet();
}
}

//////////////////

输出

class java.lang.String: this is test
class java.lang.String: bTest ref TestClass2
class java.lang.String: cTest ref TestClass2
class java.lang.String: cTest ref TestClass3
class java.lang.String: cTest ref TestClass1

///////////////////////////////////////////////

首先声明了了一个泛型类TestClass1,然后继承了两个子类TestClass2,TestClass3

main函数里先用TestClass1<String> aTest定义了一个变量引用String 类型。

用TestClass1<TestClass2> bTest引用了一个TestClass2类型,红色代码部分代码想把bTest引用TestClass3,结果编译出错

提示如下:

”required: TestClass1<TestClass2>

found: TestClass1<TestClass3>

这是因为bTest是用TestClass1<TestClass2>定义的,只能引用TestClass2。引用TestClass3会编译出错。

接下来TestClass1<? extends TestClass1> cTest 采用通配符定义了cTest,表示 cTest可以引用TestClass1及其子类。

TestClass2和TestClass3都是其子类,下一句cTest=new TestClass1<TestClass2>(new TestClass2<String>("cTest ref TestClass3"));

把cTest引用TestClass3时就不会编译出错了。

 

时间: 2024-11-04 16:39:58

java中的通配符的相关文章

Java中泛型通配符的一点概念

以List<T>为例,通常如果我们想在List中存储某种类型的数据,我们会用下面的语法进行声明和使用: 1 List<String> allMsg = new ArrayList<String>(); 2 allMsg.add("hello"); 3 allMsg.add("world"); 4 5 for(String msg : allMsg) 6 { 7 System.out.println("[类型:"

java泛型中的通配符

概述 在学习java中泛型这块内容的时候,刚开始非常容易理解,但是,到通配符的时候,我就晕了,因为学习java这块内容的指导思想,是比对着.net来的,可是java中的通配符,.net中没有这样的概念,于是花时间学习了一下,下面通过例子向大家讲解通配符 实例代码 package com.tgb.mydemo; import java.util.ArrayList; import java.util.List; public class Test { public static void main

【Java】java 中的泛型通配符——从“偷偷地”地改变集合元素说起

一直没注意这方面的内容,想来这也算是基础了,就写了这个笔记. 首先java的通配符共有三种----先别紧张,现在只是粗略的过一下,看不看其实无所谓 类型 介绍 <?> 无限定通配符,等价于 <? extends Object> <? extends Number> 上限通配符,表示参数类型只能是 Number 或是 Number 的子类. <? super Number> 下限通配符,表示参数类型只能是 Number 或是 Number 的父类. 然后再让我

在Java中使用xpath对xml解析

xpath是一门在xml文档中查找信息的语言.xpath用于在XML文档中通过元素和属性进行导航.它的返回值可能是节点,节点集合,文本,以及节点和文本的混合等.在学习本文档之前应该对XML的节点,元素,属性,文本,处理指令,注释,根节点,命名空间以及节点关系有一定的了解以及对xpath也有了解.XML学习地址:http://www.runoob.com/xml/xml-tutorial.htmlxpath基本语法学习地址:http://www.runoob.com/xpath/xpath-tut

Java 中的泛型详解-Java编程思想

Java中的泛型参考了C++的模板,Java的界限是Java泛型的局限. 2.简单泛型 促成泛型出现最引人注目的一个原因就是为了创造容器类. 首先看一个只能持有单个对象的类,这个类可以明确指定其持有的对象的类型 class Holder1 { private Circle a; public Holder1(Circle a) { this.a = a; } Circle get() { return a; } } 上面的类的可重用性不怎么样,无法持有其他类型的任何对象,下面通过持有Object

java中的泛型(转)

什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样. 可以在集合框架(Collection framework)中看到泛型的动机.例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String)的对象. 因为 Map.get(

Java中的泛型 (上) - 基本概念和原理

本节我们主要来介绍泛型的基本概念和原理 后续章节我们会介绍各种容器类,容器类可以说是日常程序开发中天天用到的,没有容器类,难以想象能开发什么真正有用的程序.而容器类是基于泛型的,不理解泛型,我们就难以深刻理解容器类.那,泛型到底是什么呢? 什么是泛型? 一个简单泛型类 我们通过一个简单的例子来说明泛型类的基本概念.实现原理和好处. 基本概念 我们直接来看代码: public class Pair<T> { T first; T second; public Pair(T first, T se

Java 中泛型的全面解析

Java泛型(generics) 是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter).声明的类型参数在使用时用具体的类型来替换.泛型最主要的应用是在JDK 5中的新集合类框架中.对于泛型概念的引入,开发社区的观点是褒贬不一.从好的方面来说,泛型的引入可以解决之前的集合类框架在使用过程中通常会出现的运行时刻类型错误,因为编译器可以在编译时刻就发现很多明显的错误.而从不好的地方来说,为了保证与旧有版本的兼容性,Java泛型的实现上存在着一些不够优雅的

Java 中 泛型的限定

泛型 一般 出现在集合中,迭代器中 也会出现! 泛型 是为了 提高代码的 安全性. 泛型 确保数据类型的唯一性. 在我们常用的容器中,  越是 单一 约好处理啊! 泛型的限定: ? 是通配符 指代 任意类型 泛型的限定上限: <? extends E> 接受 E 或者 E 的子类型. 泛型的限定下限: <?  super   E>  接收  E 或者 E 的父类. 泛型的限定上限 (定义父类 填装子类 类型!) 代码: package stu.love.v; import java