java 核心技术之基础篇
Posted 小伪桑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 核心技术之基础篇相关的知识,希望对你有一定的参考价值。
首先,谈谈我对java平台的理解,java本身是一种面向对象的语言,显著的特征有两个方面,一是所谓的“一次书写,到处运行”,能够非常容易的获得跨平台的能力,另外就是垃圾回收(GC),java 通过垃圾收集器回收分配内存,大部分情况下,程序员不需要自己操心内存的分配与回收。
对于“java 是解释执行”这句话,是不太准确的。我们开发的源代码,首先通过javac编译成字节码,然后运行时,通过java虚拟机内嵌的解释器将字节码转换成最终的机器码。长见的JVM,比如大多数情况下使用的Oracle JDK提供的jvm ,提供了JIT(Just -In-Time)编译器,所谓的动态编译器,JIT能够在运行时将热点代码编译成机器码,这时部分热点代码就属于编译执行,而不是解释执行了。所以说java是解析运行的这一说法是不准确的。
对于java的特性还有:(1)基本语言特性 ,面向对象(封装,继承,多态)、反射、泛型...(2)java类库:核心类库,如IO/NIO、网络、utils...;安全类库、jdk、management以及海量的第三方类库(3)java虚拟机:垃圾收集器、运行时、动态编译、辅助功能,如jfr(4)工具:辅助工具,如jar、jdeps ,编译器,javac 、sjavac。
以上是对java语言以及平台的理解,下面一一攻克几个java的基础的认识,由点及面,渐渐深入了解java的一些语言特性:
----------------------------------------------------------------------------------------------------------------------------------------------
一、世界上不会有永远不出错的程序,异常情况如影随形的缠绕着我们这些程序员,只有更好的认识异常,处理异常,我们的程序才有可靠性;java语言设计了完善的异常处理机制,降低可编写和维护的门槛,下面的问题,请对比 Exception 和 Error,另外区别 运行时异常与一般异常的区别?
回答如此:Exception 和 Error 都继承Throwable 类,在java 中只有Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。Exception是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。
Error 是指在正常情况下,不大可能出现的情况,绝大部分的Error会导致程序的非正常、不可恢复状态,既然是非正常那就不需要捕获,常见的有OutOfMemoryError类
Exception 又分为可检查异常和不检查异常,可检查异常在源代码里必须要显示进行捕获处理,这是在编译器检查的一部分,不检查异常就是所谓的运行时异常,类NUllPointerException、ArrayIndexOutOfBoundsException 类,根据需要判断捕获。
图示总结:
二、以题切入java语言的要素,一个经典的java 基础题,谈谈final 、finally、 finalize有啥不同?典型回答是,final可以用来修饰类、方法、变量;final修饰的class代表不可继承扩展,final的变量不可修改,final的方法不可重写;finally 则是java保证重点代码一定要被执行的一种机制。可以使用 try-catch-finally 或 try-finally 来进行类似关闭JDBC连接、保证Unlock 锁等动作。finalize 则是基础类 java.long.Object 的一个方法,他设计的目的是保证对象在被垃圾回收收集前完成特定资源的回收。finalize已经不推荐使用。
推荐使用final 关键字来明确表示我们代码的语义以及逻辑意图,这已经证明在很多场景下是很好的实践,比如:
可以将方法或类声明为final,以明确告知别人,这些行为是不允许修改的。查看java的核心类库也可看到有相当一部分的声明标记为final,保证了平台的安全性。
使用final 修饰的参数和变量,可以清楚的避免意外的赋值导致的错误。
final变量产生某种程度的不可变的效果,可以用于保护只读数据,尤其是并发编程中,可减少额外的同步开销。
对于finally 明确知道怎么用就行了,java平台已经逐步使用java.lang.ref.Cleaner 来替换finalize实现。
三、下面聊聊日常使用的字符串,字符串几乎是所有编程语言中一个特殊的存在,因为不管数量还是体积,字符串都是大多数应用的重要组成。下面的问题:理解java 语言中的字符串,String StringBuffer、StringBuilder 有什么不同?
典型回答:String 是一个非常基础的类,提供了构造和管理字符串的各种基本逻辑。它是典型的Immutable类,被声明为 final class,由于他的不可变性,类似拼接、裁剪字符串都会产生新的String 对象。由于字符串的操 作的普遍性,所以相关操作对于应用的性能也有所影响。
StringBuffer 是为了解决上面拼接产生太多中间对象的问题提供的一个类,可以使用append、add方法,把字符串添加到已有序列的末尾或指定位置。StringBuffer 是一个线程安全的类,所以随之带来了额外的性能上的开销,除非有线程安全的需要,不然推荐他的后继者 StringBuilder,
StringBuilder 本质上和 StringBuffer 没有区别,但是他去掉了线程安全的部分,有效的减少了线程开销,是绝大部分情况下进行字符串拼接的首选。
扩展部分:1、在JDK 8中,字符串拼接造作会被javaC 转换成 StringBuilder 操作。
2、字符串缓存 jDK 6 采用的是 intern ()方法,对缓存中类似的文本字符串进行缓存以备重复使用,但是不推荐大量使用,因为有“永久代”问题,使用不当,OOM就会光顾;再后续版本中采用的是intern ,intern是一种显式的排重机制,在jdK1.8中推出了一个新特性,也就是 G1 GC下的字符串排重。他是通过将相同的数据的字符串指向同一份数据来做到的,是JVM底层的改变,不需要java类库做改变。开启参数 -xx: +UseStringDedupLication
3、另外,也可从java自身的演化方面进行观察,在历史版本中他是使用 char数组来存数据的,非常的直接,这里就不在进行扩展了。
四、 java虽然号称面向对象的语言,但是原始数据类型仍然是重要的组成元素,所以经常会被考察原始数据类型和包装类的java语言特性,问题如是:int 和Integer 有什么区别?谈谈Integer值的缓存范围。
典型回答:int是整形数字,是java 8个原始类型之一(Type 、boolean 、byte、short、char、int 、float、double、long );Integer 是int对应的包装类,他有一个int 类型的字段存储数据,并且提供了基本操作,比如数学运算、int 和字符串之间的转换等,在java5 中引入了自动装箱和自动拆箱功能,自动进行转换,极大的简化了相关的编程。具体详情可考察https://blog.csdn.net/sun_wangdong/article/details/43281105,
关于Integer 的值缓存,涉及到java5 的另一改进,构建Integer 对象的传统方式是调用构造器,直接new 一个对象。我们发现大部分的操作是集中在较小的数值范围内,java5 中新添加了静态工厂方法 valueOf,在调用是利用缓存机制,带来明显的性能改进,按照javdoc,这个值默认缓存是 -128至127 之间。
知识扩展:1、理解自动装箱、拆箱,自动拆装箱算是一种语法糖,语法糖可以简单理解为java平台为我们自动进行的一些转换,保证不同的写法在运行时等价,他们发生在编译阶段,生成字节码的是一致的。 javac 自动为我们把装箱转换为 Integer.valueOf(),把拆箱转换为 Integer.intValue();调用 Integer.ValueOf();自然可以得到缓存上的好处。
注意事项:1、基本类型均具有取值范围,有可能出现数组越界的问题;2、数据类型转换1234567890L 不会超过范围、处理货币存储时使用BigDecimal工具类,使用 double会出行差距。
3、优先使用基本类型。建议避免无意的拆装箱,4、考虑线程安全的话,我们后续会总结。
以上是关于java 核心技术之基础篇的主要内容,如果未能解决你的问题,请参考以下文章