重载是面向对象语言重要的特性之一,判断重载可以根据参数列表的不同来决定是否两个方法是否存在重载。但返回值却不会成为判断因素之一,这是因为函数调用时并没有特征显示被调函数的返回值信息,也就无法区别被调用的是哪个函数。
泛型擦除是指任何泛型的参数变量在编译时,都会被擦除成Object类,即List<Integer>与List<String>在编译时都被擦除成List<Object>。假如存在两个方法 void function(List<Integer>),void function(List<String>),按照重载定义,这两种方法的参数列表不同,是重载的。但泛型擦除的定义又告诉我们这两种方法是完全一样的,属于重定义。以下面例子为例:
public class Clean {
public void method(ArrayList<String> a) {
System.out.println("call method ArrayList<String>");
}
public void method(ArrayList<Integer> a) {
System.out.println("call method ArrayList<Integer>");
}
public static void main(String[] args) {
}
}
上述代码在编译时会报错,Method method(ArrayList<Integer>) has the same erasure method(ArrayList<E>) as another method in type Clean
这是因为泛型擦除导致方法的特征一样,重定义。然而下面一段代码却可以通过编译,并运行
public class Clean {
public String method(ArrayList<String> a) {
System.out.println("call method ArrayList<String>");
return "";
}
public int method(ArrayList<Integer> a) {
System.out.println("call method ArrayList<Integer>");
return 1;
}
public static void main(String[] args) {
Clean clean = new Clean();
clean.method(new ArrayList<Integer>());
clean.method(new ArrayList<String>());
}
}
运行结果:
call method ArrayList<Integer>
call method ArrayList<String>
上述代码与前一段代码唯一的不同就是两个方法的返回值不同,这种情况与重载的定义冲突,之所以这次能编译和执行成功,是因为两个mehtod()方法加入了不同的返回值后才能共存在一个Class文件之中。Class文件方法表的数据结构时曾经提到过,方法重载要求方法具备不同的特征签名,返回值并不包含在方法的特征签名之中,所以返回值不参与重载选择,但是在Class文件格式之中,只要描述符不是完全一致的两个方法就可以共存。也就是说两个方法如果有相同的名称和特征签名,但返回值不同,那它们也是可以合法地共存于一个Class文件中的。
分享到:
相关推荐
虽然这种机制带来了一些限制,如运行时类型错误、泛型类型参数不能是基本类型、无法创建泛型类型的实例、泛型类型参数不能使用instanceof、无法重载泛型方法等,但我们可以通过一些编程技巧来规避这些问题。理解泛型...
"泛型、泛型擦除、桥接方法" 泛型是一种类型参数化技术,允许开发者在编写代码时指定类型,提高代码的灵活性和可重用性。泛型可以应用于接口、类和方法中,称之为泛型接口、泛型类和泛型方法。 泛型接口是指在接口...
在编译期间,Java会执行一种称为“类型擦除”的过程,将泛型的类型参数替换为它们的边界或Object。这意味着在运行时,泛型并不实际存在,但编译器会通过类型检查确保类型安全。 3. **类型转换与赋值转换**: 在...
- 类型擦除会生成桥接方法来处理泛型方法的重载。这些桥接方法在编译后的字节码中存在,以处理不同类型的参数。 9. **泛型与反射** - 反射在处理泛型时有一定的限制,因为泛型信息在运行时已被擦除。可以通过类型...
- 泛型方法可以与非泛型方法重载,因为泛型方法在编译后会产生多个重载形式,分别对应不同的类型参数。 通过使用泛型,开发者可以编写更加灵活、安全的代码,减少类型转换,并提高代码的可读性和维护性。泛型是...
这种机制确保了泛型与Java的现有类型系统兼容,但同时也意味着无法在运行时进行泛型相关的检查。 总之,Java中的多态性和泛型相结合,极大地提高了代码的复用性和安全性。通过泛型,我们可以创建类型安全的容器和...
类型擦除使得泛型可以与旧的代码无缝兼容,但也是为什么不能实例化泛型类型和创建泛型数组的原因。 11. 泛型的潜在问题和解决方案: 虽然泛型带来了许多便利,但它也引入了复杂性。例如,通配符和类型边界可能会...
这也解释了为什么在Java中不能基于泛型类型进行方法重载,因为经过类型擦除后,不同的泛型类型参数实际上指向了相同的基础类型。 此外,需要注意的是,尽管泛型可以提供类型安全性,但它们并不影响继承关系。例如,...
然而,泛型在引入时也带来了一些问题,其中之一就是不能直接重载泛型方法。本文将深入探讨Java泛型通配符如何解决这一问题。 首先,我们需要理解泛型的基本概念。泛型允许我们在定义集合(如List)时指定元素的类型...
在没有泛型之前,我们可能需要为每种数据类型定义一个重载的方法,而现在,一个泛型方法就能满足所有需求。在方法声明时,类型参数`E`放在尖括号`<>`内,后面跟着返回类型。在方法体内部,`E`可以用来声明参数类型、...
泛型擦除 泛型信息只存在于Java代码编译阶段,在运行时,所有的泛型信息都会被擦除。这是为了与之前的Java版本保持兼容,泛型类型参数在运行时都会被替换为它们的边界(如果没有指定边界,则默认为Object类型)。 ...
- 泛型擦除机制 3. **反射** - Class对象获取方式 - 动态创建对象 - 获取类成员信息 - 方法调用 4. **枚举** - 枚举类型的定义 - 枚举的常用方法 - 枚举的高级应用 5. **注解** - 注解的定义与使用 - ...
泛型擦除原理。 - **集合框架概述**:List、Set、Map三大接口的特点及其实现类对比分析。 #### 3. 多线程技术 - **线程生命周期**:创建、就绪、运行、阻塞和死亡五个阶段的状态转换过程。 - **线程同步机制**:...
- 泛型擦除和类型安全。 5. **多线程** - 线程的创建:实现Runnable接口和继承Thread类。 - 线程状态:新建、运行、阻塞、等待、死亡等。 - 线程同步:synchronized关键字,wait()、notify()、notifyAll()方法...
- 泛型擦除机制。 #### 2. Lambda表达式 - Lambda表达式的语法及应用场合。 - 函数式接口的理解与使用。 #### 3. 注解 - 注解的类型及使用场景。 - 如何自定义注解。 ### Java Web开发 #### 1. Servlet - ...
9. **泛型**:泛型是Java 5引入的新特性,用于提高代码的类型安全性和可读性,理解泛型的基本使用、通配符、泛型方法和泛型擦除。 10. **JVM原理**:理解Java虚拟机的工作原理,包括类加载机制、类的生命周期、JVM...
- 泛型擦除:Java泛型在编译后会擦除,只保留类型信息,运行时无法感知泛型。 - Start和Run区别:start()方法启动线程,run()方法是线程执行的主体。 - JVM内存屏障:用于确保数据的正确可见性,避免指令重排序...
- 泛型不支持操作符重载,所以不能直接在泛型类中定义`+`、`-`、`*`、`/`等运算符。 总结起来,"Generics-four-arithmetic.zip_float_site:www.pudn.com"提供的示例展示了如何利用Java泛型创建一个灵活且类型安全...
- 泛型通配符与类型擦除 - Lambda表达式与函数式接口 - Stream API的使用与并行流 -反射(Reflection)与动态代理 这份《全面解析Java源码》涵盖了Java编程的各个方面,从基本语法到高级特性,是学习和提升Java...
- 理解泛型擦除与反射的关系。 - 掌握注解(Annotation)及其在运行时的元数据获取。 7. **设计模式**: - 熟悉单例、工厂、观察者、装饰者、适配器、代理等常见设计模式。 - 理解模式在实际项目中的应用。 8....