30 个java编程技巧(最佳实践的初学者)

1.return 一个空的集合,而不是 nulljava

若是一个程序返回一个没有任何值的集合,请确保一个空集合返回,而不是空元素。这样你就不用去写一大堆 ”if else” 判断null元素。mysql

30 个java编程技巧(最佳实践的初学者)一

Java 的标准库设计者已经在 Collections 类中放了一个空的 List 常量 EMPTY_LIST,除此以外,还有 EMPTY_MAP, EMPTY_SET,真是贴心。sql

2. 当心使用 String数据库

由于字符串相加或者拼接的方式都会在对象池中查找字符串是否存在,若是不存在则建立,这样在拼接的过程当中会产生大量中间过程的字符串,占用内存资源。StringBuilder效率优于StringBuffer,可是StringBuffer线程安全。编程

30 个java编程技巧(最佳实践的初学者)一
30 个java编程技巧(最佳实践的初学者)一
另外,在实例化一个字符串对象,构造函数应该避免发生直接实例化,例如:
30 个java编程技巧(最佳实践的初学者)一

3. 避免没必要要的对象数组

一个最昂贵的操做(在内存利用率)是java对象的建立。所以,建议只在必要时建立或初始化对象。下面的代码给出了一个例子:安全

30 个java编程技巧(最佳实践的初学者)一
4.Array 和ArrayList 选择

ArrayList和Array是咱们在实际编程中常用的容器,并且由于ArrayList至关于动态化的数组,因此它们之间有太多的类似,以致于咱们在选择哪一种来存储元素的时候,会有小小的迷惑,他们都有注解的优缺点,选择真的取决于你的真实场景。函数

30 个java编程技巧(最佳实践的初学者)一

4.1.Array 有固定大小但 ArrayList 的大小不一样。因为Array 的大小是固定的,在Array 类型变量声明的时候,内存被分配。所以,Array 是很是快的。另外一方面, 使用ArrayList的最大缺点就是当咱们添加新的元素的时候,它是先检查内部数组的容量是否足够,若是不够,它会建立一个容量为原来数组两倍的新数组,���后将全部元素复制到新数组里,接着抛掉旧数组。这点真的很麻烦,由于每次都要这么搞,尤为是元素足够多的时候,这就真的是既影响内存又影响效率的问题,但经过单独测试它们的运行时间,发现其实差很少,最大的影响就是若是是有其余代码也须要使用到内存,那么Array依然不变,可是ArrayList就会变得慢多,相同状况下所花的时间是Array的四倍多(实际状况是远远不止)。性能

4.2.这是添加或删除元素从ArrayList 比Array更容易。测试

4.3.数组能够多维但ArrayList只有一个维度。

4.4.ArrayList由于内部是一个数组,因此它是能够转化为数组的。

4.5 二者的适用场合:

List list = new ArrayList();

虽然咱们想要的确实是ArrayList而不是list,可是咱们知道,父类是能够得到子类的引用而且使用子类的方法,因此这样咱们就能同时使用List和ArrayList的方法而不用惧怕出错了。

首先,一个重要的约束就是,List的声明区域通常是在main方法里(固然静态list也能够,可是咱们通常使用的时候都只是当作存储元素的临时容器),而Array是能够在外部进行声明的,这时它就是全局数组。因此,单看这点,它们的使用已经有区别,若是想要保存一些在整个程序运行期间都会存在并且不变的数据,咱们能够将它们放进一个全局数组里,可是若是咱们单纯只是想要以数组的形式保存数据,方便咱们进行查找,那么,咱们就选择ArrayList。并且还有一个地方是必须知道的,就是若是咱们须要对元素进行频繁的移动或删除,或者是处理的是超大量的数据,那么,使用ArrayList就真的不是一个好的选择,由于它的效率很低,使用数组进行这样的动做就很麻烦,那么,咱们能够考虑选择LinkedList。

30 个java编程技巧(最佳实践的初学者)一

5.用try catch的时候,要加finally吗?

考虑下面的代码片段

30 个java编程���巧(最佳实践的初学者)一
运行结果:

在Finally代码块中

在Finally代码块中

在Finally代码块中

在Finally代码块中

在Try内部代码块,退出不执行Finally代码块

在运行代码前,它看起来像要打印 ”在Finally代码块中“ 5次。可是执行的结果只有4次。第五次打印的结果是 ”在Try内部代码块,退出不执行Finally代码块“。

关于 Java 虚拟机是如何编译 finally 语句块的问题,有兴趣的读者能够参考《 The JavaTM Virtual Machine Specification, Second Edition 》中 7.13 节 Compiling finally。那里详细介绍了 Java 虚拟机是如何编译 finally 语句块。实际上,Java 虚拟机会把 finally 语句块做为 subroutine(对于这个 subroutine 不知该如何翻译为好,干脆就不翻译了,省得产生歧义和误解。)直接插入到 try 语句块或者 catch 语句块的控制转移语句以前。可是,还有另一个不可忽视的因素,那就是在执行 subroutine(也就是 finally 语句块)以前,try 或者 catch 语句块会保留其返回值到本地变量表(Local Variable Table)中。待 subroutine 执行完毕以后,再恢复保留的返回值到操做数栈中,而后经过 return 或者 throw 语句将其返回给该方法的调用者(invoker)。

将上面代码修改以下:

30 个java编程技巧(最佳实践的初学者)一
运行结果:

在Try内部代码块,退出不执行Finally代码块

在Try内部代码块,退出不执行Finally代码块

在Try内部代码块,退出不执行Finally代码块

在Try内部代码块,退出不执行Finally代码块

在Try内部代码块,退出不执行Finally代码块

总结:

这里就不过多的去具体分析整个过程有兴趣的朋友可找资料了解整个过程,一个小小的、看似简单的 finally 语句块背后竟然隐藏了这么多玄机。看来,咱们平时仍是应该认真的阅读 Java 相关的基础文档,好比:Java 语言规范、Java 虚拟机规范等,不少棘手的问题均可以从中获得答案。只有真正的吃透了基础知识,才能达到运用自如的境界!

1> try、catch、finally语句中,在若是try语句有return语句,则返回的以后当前try中变量此时对应的值,此后对变量作任何的修改,都不影响try中return的返回值

2> 若是finally块中有return 语句,则返回try或catch中的返回语句忽略。

3 >若是finally块中抛出异常,则整个try、catch、finally块中抛出异常

因此使用try、catch、finally语句块中须要注意的是

1> 尽可能在try或者catch中使用return语句。经过finally块中达到对try或者catch返回值修改是不可行的。

2 >finally块中避免使用return语句,由于finally块中若是使用return语句,会显示的消化掉try、catch块中的异常信息,屏蔽了错误的发生

3 >finally块中避免再次抛出异常,不然整个包含try语句块的方法回抛出异常,而且会消化掉try、catch块中的异常

6.奇数判断

看看下面的代码行,并肯定若是他们能够用来精确地识别一个给定的数字是不是奇数?

30 个java编程技巧(最佳实践的初学者)一

奇数能够被定义为被2整除余数为1的整数。表达式 num% 2 计算的是 num整除 2 时所产生的余数,所以看起来这个程序应该可以正确运转。遗憾的是,它不能;它在四分之一的时间里返回的都是错误的答案。

为何是四分之一?由于在全部的 int 数值中,有一半都是负数,而 isOdd 方法对于对全部负奇数的判断都会失败。在任何负整数上调用该方法都回返回 false ,无论该整数是偶数仍是奇数。

这是 Java 对取余操做符(%)的定义所产生的后果。该操做符被定义为对于全部的 int 数值 a 和全部的非零 int 数值b,都知足下面的恒等式:

(a / b) * b + (a % b) == a

如今进行修改以下:

30 个java编程技巧(最佳实践的初学者)一

使用此代码,不只是解决了奇数的负的问题,并且这个代码也高度优化。由于,算术和逻辑运算的速度更快,比除法和乘法,结果取得了更快。

7. 单引号和双引号之间的区别

30 个java编程技巧(最佳实践的初学者)一

尝试运行上面的程序。这个程序演示了一个死锁。这种死锁的产生是由于两个线程都在等待其余线程所抓取的资源。他们都不在任何一个版本。从代码,彷佛还“HaHa”是回来了,但它实际上返回ha169。缘由是,若是使用双引号,字符串对待,但在单引号的状况下,字符自动转换为int型,进行计算。

8. 经过简单的技巧避免内存泄漏

内存泄漏常常会致使软件的性能退化。由于,java自动管理内存,开发商没有太多的控制。但仍有一些标准的作法,能够用来防止内存泄漏。

当查询完成时,老是释放数据库链接。

尽可能使用 Finally 块。

释放存储在静态表中的实例。

9. 避免死锁

死锁出现的缘由有不少。避免死锁不是一句话就能解决的。一般来讲,当某个同步对象在等待另外一个同步对象所拥有的资源上的锁时,便会产生死锁。

试着运行下下面的程序。它会告诉你什么是死锁。这个死锁是因为两个线程都在等待对方所拥有的资源,所以会产生死锁。它们会一直等待,没有谁会先放手。

30 个java编程技巧(最佳实践的初学者)一
30 个java编程技巧(最佳实践的初学者)一
30 个java编程技巧(最佳实践的初学者)一

运行结果:

Addition Thread: 13

Subtraction Thread: 7

Holding First Lock…

Holding Second Lock…

Addition Thread: Waiting for AddLock…

Subtraction Thread: Waiting for SubLock…

但若是调用的顺序变一下的话,死锁的问题就解决了。

将 MySubtractionThread中的线程加锁顺序调换再看看

30 个java编程技巧(最佳实践的初学者)一

运行结果:

Addition Thread: 13

Holding First Lock…

Addition Thread: Waiting for AddLock…

Threads: Holding Add and Sub Locks…

Subtraction Thread: 7

Holding Second Lock…

Subtraction Thread: Waiting for SubLock…

Threads: Holding Add and Sub Locks…

三种用于避免死锁的技术:

1>加锁顺序

2>加锁时限

3>死锁检测

一个更好的方案是给这些线程设置优先级,让一个(或几个)线程回退,剩下的线程就像没发生死锁同样继续保持着它们须要的锁。若是赋予这些线程的优先级是固定不变的,同一批线程老是会拥有更高的优先级。为避免这个问题,能够在死锁发生的时候设置随机的优先级。

10.JAVA运行内存的设置

一些java应用程序能够被高度的CPU密集型以及他们须要不少内存。这样的应用程序一般运行速度慢,由于内存高的要求。因此,咱们能够在相关的配置文件中进行修改调整内存大小。

Xms = 设置内存初始化的大小

Xmx = 设置最大可以使用内存的大小

XX:PermSize =初始大小,将分配给JVM的启动过程

XX:MaxPermSize = 最大尺寸能够分配JVM的启动过程

11. 如何在java时间操做

有java时间两种标准方法:

System.currentTimeMillis()、System.nanoTime()

平时产生随机数时咱们常常拿时间作种子,好比用System.currentTimeMillis的结果,可是在执行一些循环中使用了System.currentTimeMillis,那么每次的结果将会差异很小,甚至同样,由于现代的计算机运行速度很快。后来看到java中产生随机数函数以及线程池中的一些函数使用的都是System.nanoTime。

>System.currentTimeMillis返回的是从1970.1.1 UTC 零点开始到如今的时间,精确到毫秒,平时咱们能够根据System.currentTimeMillis来计算当前日期,星期几等,能够方便的与Date进行转换,

> System.nanoTime提供相对精确的计时,可是不能用他来计算当前日期,

因此在使用中,咱们能够根据咱们具体的目的去正确的选择他们。

12. Float 和Double的选择

Data type Bytes used Significant figures (decimal)
Float 4 7
Double 8 15

double应该比float更好用,缘由:

大多数处理器须要几乎相同数量的处理时间来执行浮点和双运算的操做。在相同数量的计算时间双提供了更高的精度。

13. Java的乘方运算

java提供了两个方法:

Multiplication:乘法

30 个java编程技巧(最佳实践的初学者)一

pow(double base, double exponent):(base的exponent次方)

30 个java编程技巧(最佳实践的初学者)一
math.pow只应在必要时使用,像指数是一个分数。Math.pow()方法一般慢300-600倍的速度比乘法。

14. 如何处理空指针异常

空指针异常在java中是很常见的。当咱们尝试调用一个空对象引用的方法时,这个异常会发生。例如:

30 个java编程技巧(最佳实践的初学者)一
若是在上面的例子中,若是获得一个NullPointerException异常,而后学校 是null 或liststudents()null。有个好注意你能够提前将异常抛出,经过提前抛出异常(又���"迅速失败"),异常得以清晰又准确堆栈信息当即反映出什么出了错(提供了非法参数值),为何出错(文件名不能为空值),以及哪里出的错,菜鸟和高手均可能犯的一个错是,在程序有能力处理异常以前就捕获它。Java编译器经过要求检查出的异常必须被捕获或抛出而间接滋长了这种行为。天然而然的作法就是当即将代码用try块包装起来,并使用catch捕获异常,以避免编译器报错。
30 个java编程技巧(最佳实践的初学者)一
 
0
相关文章
相关标签/搜索