在编程中,我们常常需要引用多个相同的对象,但在解决特定问题时往往不知道需要生成多少个对象?它们需要存储多久?该如何存储这些对象?
在大多数数语言中都可以通过数组类型来实现这一需求,这类数组通常被称作为容器(也被成为集合)。容器自身会进行扩充,编程者不必在意会有多少个对象需要存储,只需要创建容器对象,然后让其帮你处理所有细节。
JAVA中常见的容器分为三类:
1.List
List用于存储序列,常见的导出类为ArrayList和LinkedList,它们都实现了List的接口。在ArrayList中,随机访问元素花费的时间是固定的,但往中间插入元素,开销会比LinkedList大;LinkedList随机访问元素的代价高昂,但随机插入元素的性能优异。
2.Map
Map被称为关联数组,用过存储键值对的形式,来建立对象之间的关联。
3.Set
存储的对象不会重复,常用于去重的场景。
除此之外还有队列、树、堆栈等构件,适用于不同的存储场景。
JAVA容器中存储的对象默认为Object类型,因其为单根继承结构,故所有对象都可以向上转型为Object对象,可以存储Object的容器便可以存储任意对象。
但对象向上转型,会使它丢失身份,当我们从容器中取回对象时,就获取了一个对Object类型的引用,这时就需要一个接口在获取对象时能够转为具体引用对象,这里需要用到向下转型,将需要获取的对象指定为泛型,用一对尖括号表示。
List shapeList &#61; new ArrayList<>();
向下转型通常是不安全的&#xff08;如&#xff1a;正方形可以向上转型为几何形&#xff0c;但几何形向下转型不一定为正方形&#xff0c;它还有可能是圆形&#xff09;&#xff0c;故向下转型时需要程序员付出更多心血去思考&#xff0c;避免程序出错。
这里顺带一提JAVA的异常处理机制&#xff0c;异常处理依赖于程序员的警惕性&#xff0c;异常是一种对象&#xff0c;它从出错地点被“抛出”&#xff0c;并被相应的异常处理器“捕获”。异常处理就像是程序在正常路径发生错误时&#xff0c;执行另一条路径&#xff0c;从而不影响后续程序的正常运行。
在对象的使用中&#xff0c;我们还有一个不可忽视的问题&#xff1a;对象的生成与销毁。
每个对象为了生存都需要占用内存资源&#xff0c;当我们不再需要一个对象时&#xff0c;它必须被清理掉&#xff0c;使其被占用的资源被释放&#xff0c;否则易发生内存泄露。
在C&#43;&#43;中&#xff0c;对象的生命周期是由程序员直接控制&#xff0c;这种方式将存储空间的分配和释放置于优先考虑的位置&#xff0c;必须在编写程序时知道对象的确切数量、生命周期和类型&#xff0c;这会使得问题变得复杂&#xff0c;牺牲了灵活性&#xff0c;但这也是为了追求最大的执行速度做出的牺牲。
JAVA采用动态内存分配方式&#xff0c;每当创建新对象时&#xff0c;就使用new关键字来进行构建&#xff0c;这种方式直到运行时才知道需要多少对象&#xff0c;对象在堆中创建&#xff0c;存储空间在运行时被动态管理&#xff0c;程序员不必关心对象会在何时会被释放&#xff0c;JAVA中的“垃圾回收器”可以自动发现不在使用的对象&#xff0c;并将其销毁&#xff0c;减少了编程时需要考虑的问题&#xff0c;可以避免暗藏的内存泄露&#xff0c;这也得益于JAVA对象都是源于Object的单根继承结构&#xff0c;简化了“垃圾回收器”的实现。
本次分享至此结束&#xff0c;希望本文对你有所帮助&#xff0c;若能点亮下方的点赞按钮&#xff0c;在下感激不尽&#xff0c;谢谢您的【精神支持】。
若有任何疑问&#xff0c;也欢迎与我交流&#xff0c;若存在不足之处&#xff0c;也欢迎各位指正&#xff01;