方法的参数及返回值一般是具体的某个类或某个接口。 (接口的好处是多态)。
当方法的参数或返回值是允许是多种不同的类型时,只能使用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泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1....
smart-doc是一款同时支持JAVA REST API和Apache Dubbo RPC接口文档生成的工具,smart-doc在业内率先提出基于JAVA泛型定义推导的理念, 完全基于接口源码来分析生成接口文档,不采用任何注解侵入到业务代码中。...
Java泛型定义与用法实例详解 Java泛型是Java语言中的一种重要机制,用于在编译期检查类型安全,避免在运行期引发ClassCastException。泛型的引入使得Java语言更加灵活和强大,本文将详细介绍Java泛型的定义、原理、...
- 定义泛型类时,类型参数写在尖括号内,如 `class TestGen, V>`。 - 实例化泛型对象时,需要指定类型参数的具体类型,如 `TestGen, String> t = new TestGen, String>()`。 - `extends` 关键字在泛型中的作用是...
/// <param name="getAllAsync">1个具有返回值的泛型异步委托方法实例,该泛型异步委托方法实例用于获取1个指定实体的所有实例。 /// <param name="getCacheKey">1个具有返回值的委托方法实例,委托方法实例用于...
Java泛型定义与用法入门示例 Java泛型定义与用法是Java编程语言中非常重要的概念,它可以帮助开发者编写更加安全、灵活和可重用的代码。在本文中,我们将详细介绍Java泛型定义与用法,并通过实例形式分析了Java泛型...
泛型定义是在类、接口或方法中声明类型参数,使用尖括号 `和 `>`括起来。例如,`public class Holder<T> { ... }` 声明了一个名为 `Holder` 的泛型类,类型参数为 `T`。在使用时,可以指定具体的类型,例如 `Holder...
通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。 泛型的好处包括: * 类型安全:泛型可以提高 Java 程序的类型安全,消除代码中的强制类型转换,减少出错机会。 * 消除强制...
- **数据访问**:在Spring Data JPA或MyBatis等持久层框架中,使用泛型定义Repository接口,可以实现对特定类型的实体进行操作,例如`List<User> findByUsername(String username)`。 2. **Struts框架中的泛型** ...
泛型是现代编程语言中的一个特性,允许开发者在编写代码时定义可参数化的类型。这意味着数据结构或方法可以接受任何类型的对象,只要它们遵循特定的约束。例如,在Java中,我们可以声明一个泛型列表`List<T>`,其中`...
#### 泛型定义 泛型是一种抽象概念,它允许你在定义类、接口或方法时使用类型参数。这些类型参数在编译时会被具体的实际类型替换。如果你定义了一个类`MyClass<T>`,这里的`T`就是一个类型参数。当你创建`MyClass`...
本篇将详述如何使用EFCore 5来定义数据库上下文,以及如何通过泛型定义实体及其属性映射规则的基类和接口,以便在默认情况下实现系统启动。 首先,数据库上下文(DbContext)是EFCore的核心组成部分,它代表了应用...
使用泛型方法时,至少返回值或参数有一个是泛型定义的,而且应该保持一致,否则可能会受到各种限制。 Java泛型类和泛型方法是Java编程语言中的一种重要概念,它们提高了代码的灵活性和可读性,使得开发者可以编写...
方法的泛型定义在方法名之前,例如`public <T> void printList(List<T> list)`。 7. **协变与逆变**:在Java中,泛型是协变的,意味着`List<Number>`是`List<Object>`的子类型,这允许将Number列表赋值给Object列表...
方法的泛型定义方式与类相似,但类型参数位于返回类型之前,如`public <T> void printList(List<T> list) {...}`。 3. 上界通配符:有时我们不关心具体的类型,只关心它是否继承自某个父类或实现了某个接口。这时...
2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip...
泛型接口则定义了可以被任何类型实现的一组操作,这些类型可能是泛型类或其他类型。例如,我们可以定义一个泛型接口`IGenericCollection<T>`,要求实现它的类必须提供添加、删除和获取元素的方法: ```csharp ...
通过了解泛型定义的变量的类型限制,编译器可以在更高层次上验证类型假设。这样做的好处是类型错误可以在编译时就被发现,而不是等到运行时才出现异常。 2. **消除强制类型转换**:泛型的另一个显著优势是减少了源...
上述代码展示了如何使用泛型定义一个栈类。通过实例化`Stack<T>`,我们可以轻松创建不同类型的栈,如`Stack<int> intStack = new Stack(10);`,并且能够在编译时确保类型的安全性。 #### 泛型的实例化机制 C#泛型...