`

泛型定义

 
阅读更多

方法的参数及返回值一般是具体的某个类或某个接口。 (接口的好处是多态)。

 

当方法的参数或返回值是允许是多种不同的类型时,只能使用Object对象。

如:实例化某一个类:

 

public Object createJavaBean(Class classz) throws Exception{
		return classz.newInstance();
	}
//调用时需使用 Person person =(Person)createJavaBean(Person.class);
//              Dog dog= (Dog)createJavaBean(Dog.class);
//              Cat cat = (Cat)creatJavaBean(Cat.clas);
// createJavaBean 可以生成不同类型的实例,在调用时才能根据参数确定其正确的返回值类型。
 返回值为Object ,需要将类型强制转换为实际的类型。

 

如果这是一个常被调用的方法,其他人调用时,需要查看方法代码才能明白返回的Object是什么。

因此最好使用泛型:IDE能够提示传入或返回正确的类型,而不用强制类型转换。

 

泛型类:一个类可以操作多个不同类型对象时(每个类实例对应的类型固定),类定义时不能明确的方法的参与返回值类型,则可以将不确定的类型定义为类型参数(代替了Object),定义了类型参数的类为泛型类。

 

 泛型类说明它操作或方法返回的类型不确定,直到实例化时(传入实际的类型参数值)才确定,该实例的所有方法都能明确其返回值或参数值的类型(写代码时IDE直接提示该类型是什么了),而不是Object。

 

泛型方法:方法的参数或返回值的类型不确定,可以定义为类型参数(而不是Object),直到方法调用时,传入实际的参数类型,从而推导出实际的返回值类型,或推导出其它的参数的类型(写代码时IDE直接提示该类型是什么了),而不是Object。

 

 

泛型方法:

方法的返回值前定义泛型说明: < 类型参数A[A extends  类或另一类型参数][,类型参数B[B extends 类或另一类型参数]....]>,方法参数类型或返回值类型 定义好的类型参数A或B了。

 

public <T> T createJavaBean(Class<T> classz) throws Exception{
		return classz.newInstance();
}
//定义了T类型,说明参数是某一类的Class对象,返回值类型则为该类型的实例。
//那么传入的参数类型一确定,那么它的返回值类型也就确定了。所以返回值不是Object,而是实际的类型。

//调用时:Person person = createPerson(Person.class);而不需要类型转换
 如果createJavaBean 只能够创建Person 及其子类型 ,其它的类型不能创建 。那么就应该定义T类型的范围 : T extends Person,说明T只能是Person 或其子类型。
public <T extends Person> T createPerson(Class<T> classz) throws Exception{
		return classz.newInstance();
}
调用:BlackPerson blacPerson = createPerson(BlackPerson.class);
				//BlackPerson是Person 的子类。
				createPerson(String.class);//这行编译报错
	
 

 泛型类:

   在类名后面加上泛型说明: < 类型参数A[A extends  类或另一类型参数][,类型参数B[B extends 类或另一类型参数]....]>,类中的任意方法的参数或返回值就可以使用类型参数A或B了。

 

类型参数值在泛型类实例化时确定: new 泛型类<实际类型参数A,实际类型参数B....>(构建器参数)。

实例化之后,方法的参数与返回值是类型参数的,都已明确它的类型=实际传入的类型

   



 在实例化泛型类时,也可以不传入实际的类型参数,那么类中定义的类型参数就自动为Object.



 泛型类的子类:

第一种方式,扩展父类,给出实际的参数类型:



 第二种方式:继续使用参数类型



 

类型通配符:?

代表任意类型。 

 一般用于泛形类实例变量。

 List<?> list ;//不明确类型的List,

list = new ArrayList<String>();//正确

list = new ArrayList<Integer>();//正确

list = new ArrayList<Object>();//正确

可以用于方法参数中,实现对某一个类的不同泛型类实例的通用操作,但只能调用泛型实例的非泛型参数的方法,因为泛型参数是?,无法确定其类型,参数传递不进去。

 

 void test(List<?> list){
		Object obj = list.get(0);//调用非泛型方法,返回值类型为?,未明确的类型,上溯到所有类型的父类Object
		list.add(new String(""));//调用泛型方法,参数类型是?,未明确的类型,可能是String、Integer等等,这行代码中给?赋值为String,编译不过去
	}

  

void test(List<? extends Person> list){
		Person person = list.get(0);//调用非泛型方法,返回值类型为?,未明确的类型,上溯到类型上限 Person 
		//list.add(new Person());//调用泛型方法,编译不过去
	}

 

 

 

 

AbstractCollection 源码:

 

 

public abstract class AbstractCollection<E> implements Collection<E> {
    public boolean containsAll(Collection<?> c) {
	Iterator<?> e = c.iterator();
	while (e.hasNext())
	    if (!contains(e.next()))
		return false;
	return true;
    }
       public boolean contains(Object o) {
	Iterator<E> e = iterator();
	if (o==null) {
	    while (e.hasNext())
		if (e.next()==null)
		    return true;
	} else {
	    while (e.hasNext())
		if (o.equals(e.next()))
		    return true;
	}
	return false;
    }	
   public boolean addAll(Collection<? extends E> c) {
	boolean modified = false;
	Iterator<? extends E> e = c.iterator();
	while (e.hasNext()) {
	    if (add(e.next()))
		modified = true;
	}
	return modified;
    }
}
   源码中:

 

      1.方法 containsAll(Collection<?> c) ,参数可以是任意类型的 Collection。

      2.方法addAll(Collection<? extends E> c),可以接受E类型或E子类型的Collection.

   

   

获取泛型实例的实际类型:

方式一:

父类 TypeReference ,来源于 MyBatis3.2.3

 

public abstract class TypeReference<T> {
		 
		  private final Type rawType;//T的实际类型
		 
		  protected TypeReference() {
		    rawType = getSuperclassTypeParameter(getClass());
		  }
		 
		  Type getSuperclassTypeParameter(Class<?> clazz) {
		    Type genericSuperclass = clazz.getGenericSuperclass();
		    if (genericSuperclass instanceof Class) {
		      // try to climb up the hierarchy until meet something useful
		      if (TypeReference.class != genericSuperclass) {
		        return getSuperclassTypeParameter(clazz.getSuperclass());
		      }
		 
		      throw new RuntimeException("'" + getClass() + "' extends TypeReference but misses the type parameter. "
		        + "Remove the extension or add a type parameter to it.");
		    }
		 
		    Type rawType = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0];
		    // TODO remove this when Reflector is fixed to return Types
		    if (rawType instanceof ParameterizedType) {
		      rawType = ((ParameterizedType) rawType).getRawType();
		    }
		 
		    return rawType;
		  }
		 
		  public final Type getRawType() {
		    return rawType;
		  }
		 
		  @Override
		  public String toString() {
		    return rawType.toString();
		  }
		 
		
}
 DAO 类扩展 TypeReference:

 

 

 

public class Dao<T,PK> extends TypeReference<T>{
	
	public T queryOne() throws Exception{
		T t = ((Class<T>)this.getRawType()).newInstance();
		Map dataMap = new HashMap();//数据查询结果
		dataMap.put("name", "ll");//模拟数据
		BeanUtils.populate(t, dataMap);
		return t;
	}

}

 PersonDao 扩展了 Dao:

public class PersonDao extends Dao<Person, String> {//这里指明T的类型,要不然获取不到
	public static void main(String args []){
		try{
			PersonDao personDao = new PersonDao();
			Person person = personDao.queryOne();
			System.out.println(person);//输出:Person [name=ll]
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

 

  • 大小: 8.5 KB
  • 大小: 8.3 KB
  • 大小: 4.9 KB
  • 大小: 7 KB
分享到:
评论

相关推荐

    1.java泛型定义.zip

    1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1....

    基于JAVA泛型定义推导的理念, 完全基于接口源码来分析生成接口文档生成的工具

    smart-doc是一款同时支持JAVA REST API和Apache Dubbo RPC接口文档生成的工具,smart-doc在业内率先提出基于JAVA泛型定义推导的理念, 完全基于接口源码来分析生成接口文档,不采用任何注解侵入到业务代码中。...

    Java泛型定义与用法实例详解

    Java泛型定义与用法实例详解 Java泛型是Java语言中的一种重要机制,用于在编译期检查类型安全,避免在运行期引发ClassCastException。泛型的引入使得Java语言更加灵活和强大,本文将详细介绍Java泛型的定义、原理、...

    泛型java的泛型知识,非常有用

    - 定义泛型类时,类型参数写在尖括号内,如 `class TestGen, V&gt;`。 - 实例化泛型对象时,需要指定类型参数的具体类型,如 `TestGen, String&gt; t = new TestGen, String&gt;()`。 - `extends` 关键字在泛型中的作用是...

    230204-025shopDemo(CURD操作的泛型定义实现之IRepository)

    /// &lt;param name="getAllAsync"&gt;1个具有返回值的泛型异步委托方法实例,该泛型异步委托方法实例用于获取1个指定实体的所有实例。 /// &lt;param name="getCacheKey"&gt;1个具有返回值的委托方法实例,委托方法实例用于...

    Java泛型定义与用法入门示例

    Java泛型定义与用法入门示例 Java泛型定义与用法是Java编程语言中非常重要的概念,它可以帮助开发者编写更加安全、灵活和可重用的代码。在本文中,我们将详细介绍Java泛型定义与用法,并通过实例形式分析了Java泛型...

    Java 泛型最全指南(定义和使用+继承泛型类/实现泛型接口+泛型的边界+通配符+类型擦除)

    泛型定义是在类、接口或方法中声明类型参数,使用尖括号 `和 `&gt;`括起来。例如,`public class Holder&lt;T&gt; { ... }` 声明了一个名为 `Holder` 的泛型类,类型参数为 `T`。在使用时,可以指定具体的类型,例如 `Holder...

    java泛型学习ppt

    通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。 泛型的好处包括: * 类型安全:泛型可以提高 Java 程序的类型安全,消除代码中的强制类型转换,减少出错机会。 * 消除强制...

    SSH泛型代码实例

    - **数据访问**:在Spring Data JPA或MyBatis等持久层框架中,使用泛型定义Repository接口,可以实现对特定类型的实体进行操作,例如`List&lt;User&gt; findByUsername(String username)`。 2. **Struts框架中的泛型** ...

    数据结构-加入泛型的线性表、栈、队列

    泛型是现代编程语言中的一个特性,允许开发者在编写代码时定义可参数化的类型。这意味着数据结构或方法可以接受任何类型的对象,只要它们遵循特定的约束。例如,在Java中,我们可以声明一个泛型列表`List&lt;T&gt;`,其中`...

    Java中的泛型

    #### 泛型定义 泛型是一种抽象概念,它允许你在定义类、接口或方法时使用类型参数。这些类型参数在编译时会被具体的实际类型替换。如果你定义了一个类`MyClass&lt;T&gt;`,这里的`T`就是一个类型参数。当你创建`MyClass`...

    21-05-16_Nop4.4(006_使用EFCore5中间件来定义数据库下文和泛型来定义实体及其属性映射规则类的基类和接口,默认被正常启动).rar

    本篇将详述如何使用EFCore 5来定义数据库上下文,以及如何通过泛型定义实体及其属性映射规则的基类和接口,以便在默认情况下实现系统启动。 首先,数据库上下文(DbContext)是EFCore的核心组成部分,它代表了应用...

    Java泛型类与泛型方法的定义详解

    使用泛型方法时,至少返回值或参数有一个是泛型定义的,而且应该保持一致,否则可能会受到各种限制。 Java泛型类和泛型方法是Java编程语言中的一种重要概念,它们提高了代码的灵活性和可读性,使得开发者可以编写...

    java中的泛型样例

    方法的泛型定义在方法名之前,例如`public &lt;T&gt; void printList(List&lt;T&gt; list)`。 7. **协变与逆变**:在Java中,泛型是协变的,意味着`List&lt;Number&gt;`是`List&lt;Object&gt;`的子类型,这允许将Number列表赋值给Object列表...

    泛型、TreeMap.rar

    方法的泛型定义方式与类相似,但类型参数位于返回类型之前,如`public &lt;T&gt; void printList(List&lt;T&gt; list) {...}`。 3. 上界通配符:有时我们不关心具体的类型,只关心它是否继承自某个父类或实现了某个接口。这时...

    2.java定义泛型类.zip

    2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip...

    C#泛型类、泛型方法、泛型接口、泛型委托的实例

    泛型接口则定义了可以被任何类型实现的一组操作,这些类型可能是泛型类或其他类型。例如,我们可以定义一个泛型接口`IGenericCollection&lt;T&gt;`,要求实现它的类必须提供添加、删除和获取元素的方法: ```csharp ...

    java泛型详解

    通过了解泛型定义的变量的类型限制,编译器可以在更高层次上验证类型假设。这样做的好处是类型错误可以在编译时就被发现,而不是等到运行时才出现异常。 2. **消除强制类型转换**:泛型的另一个显著优势是减少了源...

    泛型实例详解

    上述代码展示了如何使用泛型定义一个栈类。通过实例化`Stack&lt;T&gt;`,我们可以轻松创建不同类型的栈,如`Stack&lt;int&gt; intStack = new Stack(10);`,并且能够在编译时确保类型的安全性。 #### 泛型的实例化机制 C#泛型...

Global site tag (gtag.js) - Google Analytics