先看两段小程序:
第一段定义了一个类BaseClass, 具有包级访问权限
package aboutClass;
class BaseClass {
private String name = "";
BaseClass(String name){
this.name = name;
}
String getName(){
return name;
}
}
第二段在同一个包内定义了另一个类,其中包含了一个List<BaseClass>
package aboutClass;
import java.util.ArrayList;
import java.util.List;
class TestBaseClass {
private List<BaseClass> items = new ArrayList<BaseClass>();
void addItem(BaseClass b){
items.add(b);
}
List<BaseClass> getItems(){
return items;
}
String getFirstName(){
List<? extends BaseClass> list = getItems();
if(list.size() >= 1)
return list.get(0).getName();
else return "";
}
}
你可能会认为这个程序不会有任何问题,虽然在getFirstName()方法中的写法有点奇怪。但是第二段根本就无法通过编译,原因是list中的元素无法得到getName()方法的访问权限。但是我们的两段程序都是在同一个包里的呀,而且第一段程序也有着包级访问权限,那问题出在哪里呢?
很明显,List<? extends BaseClass> list = getItems();这句奇怪的语句导致了问题。通配符似乎扩大了访问范围。现在我们来假设一下如果该句是合法的会出现什么情况?那将意味着我们可以在包外访问一个包级的方法!虽然BaseClass是包级的,但是我们仍然可以通过继承在包外得到它的一个子类实例!因此,在这里java禁止我们调用包级的方法是出于安全的考虑,也是完全合情合理的。我们想要访问到这个方法,必须得经过显式转换。但最好的方法是,不要尝试去写这种奇怪的代码。
分享到:
相关推荐
- Struts2的拦截器支持使用通配符来指定Action的执行顺序或拦截条件,例如在`struts.xml`中配置拦截器时可以使用通配符来指定某些特定的Action被拦截。 - **国际化处理**: - Struts2内置了国际化支持机制,允许...
Java 11版中,类的构造器、访问修饰符、抽象方法以及接口的使用都有明确的规定。此外,还涉及到了内部类、匿名类和枚举等高级特性。 三、异常处理 Java的异常处理机制通过try-catch-finally语句实现,规范中详细...
泛型是Java 5引入的一个重要特性,它允许在类、接口和方法中使用类型参数,从而增强了代码的类型安全性。通过使用泛型,我们可以在编译时就检测到可能的类型错误,而不是在运行时发现。例如,`List<String>` 就是一...
8. **反射**:Java反射机制允许程序在运行时动态地获取类的信息并调用其方法,试题可能测试考生对Class类、Method类、Constructor类的理解和使用。 9. **注解(Annotation)**:注解是Java提供的一种元数据,用于向...
书中详细介绍了ArrayList、LinkedList、HashSet、HashMap等容器的使用,以及Iterator、ListIterator的迭代方式。 4. 多线程:Java提供了强大的多线程支持,书中详细阐述了线程的创建、同步、死锁等问题,以及如何...
Java中的命名空间和访问权限是面向对象编程的重要概念,它们帮助我们组织代码并控制不同类之间的相互访问。本文将详细阐述这两个主题。 首先,我们来看类的命名空间。在Java中,命名空间主要通过包(package)来...
9. **泛型**:Java泛型提供了类型安全的容器,谜题可能探讨其边界、类型擦除和通配符的使用。 10. **并发工具类**:如CountDownLatch、CyclicBarrier、Semaphore等,谜题可能要求使用这些工具实现特定的并发控制...
在Java编程世界中,"包"(Package)是组织类和接口的一种机制,它使得代码管理更加有序,避免了命名冲突的问题。`com.bruceeckel.*` 提到的这个包名,可能来源于Bruce Eckel的著作《Thinking in Java》。这本书是...
学生提问:当我们使用编译C程序时,不仅需要指定存放目标文件的位置,也需要指定目标文件的文件名,这里使用javac编译Java程序时怎么不需要指定目标文件的文件名呢? 13 1.5.3 运行Java程序 14 1.5.4 根据...
泛型是Java 5引入的一项特性,它允许在类、接口和方法中使用类型参数。这意味着可以在编译时检查类型安全,避免了强制类型转换的需要,并减少了运行时错误。泛型通过在定义容器类(如List、Set和Map)时指定元素类型...
书中会介绍泛型的声明、通配符、类型擦除等概念。 12. **Java API**:Java标准库提供了大量的预定义类和接口,如Math类、String类、Date类等。书中会介绍一些常用的API及其用法。 通过深入学习《Java编程思想...
Java的泛型提供了一种方式来指定容器对象的类型,从而在编译时增加类型安全性和减少运行时错误。学习如何使用泛型类和方法,以及通配符的用法,能够提高代码的可读性和复用性。 最后,随着Java版本的更新,诸如...
- 泛型通配符:了解上界通配符、下界通配符的使用场景。 3. 集合框架 - List、Set和Queue的区别:理解各自的特点,以及在不同场景下的选用。 - HashMap与TreeMap:性能比较,以及如何根据需求选择合适的实现。 ...
Java编程语言是全球范围内广泛应用的开发语言,尤其在企业级应用和互联网开发中占据着重要地位。本资源“Java完全自学宝典”旨在为初学者提供一个全面的学习路径,通过源代码实例帮助理解并掌握Java的核心概念和技术...
1. **Java语言基础**:这部分测试对Java语法、数据类型、控制结构(如if语句和循环)、方法、数组以及类和对象的理解。考生需要熟悉面向对象编程的基本概念,包括封装、继承和多态。 2. **类和对象**:深入理解类的...
7. **多线程**:Java内置了对多线程的支持,源码中会有Thread和Runnable接口的使用,以及同步机制如synchronized关键字和java.util.concurrent包的高级工具。 8. **输入/输出(I/O)系统**:Java I/O库提供了处理...
8. **反射机制**:Java的反射机制允许在运行时动态获取类的信息并操作类的对象,包括创建对象、调用方法、访问字段等。这对于实现元编程、插件化等高级功能很有用。 9. **泛型**:Java泛型提供了一种在编译时检查...
- 泛型通配符:包括extends和super关键字的使用,以便在处理不同类型的泛型容器时提供更大的灵活性。 5. **多线程** - Thread类和Runnable接口:代码展示了如何创建和启动线程,以及如何实现线程间的协作和同步。...
Java 泛型是一种强大的工具,它允许在编程时指定容器(如列表、集合等)所存储的数据类型。这种特性在2004年随着Java 5的发布引入,极大地提升了代码的安全性和可读性。泛型的主要好处在于类型检查和类型安全。在不...
- **泛型**:理解泛型的约束、通配符,以及如何在代码中使用泛型。 5. **并发处理** - **线程**:创建线程的方式(Thread类和Runnable接口),线程的状态,以及线程同步机制(synchronized关键字、wait/notify)...