java 代码编写细节-提升性能

1. 合理使用final

将Java局部变量定义为final有多重好处,包括提高代码可读性、防止变量被意外修改、优化性能、避免多线程安全问题和满足语法规范。

  1. 提高代码可读性‌:使用final修饰局部变量可以明确表达变量的含义和作用,使得代码更加易读易懂,从而提高代码的可读性。
  2. 防止变量被意外修改‌:final修饰的局部变量在程序的其他地方不会被无意中修改,这有助于防止在程序执行过程中对变量的值进行不期望的更改,从而提高了代码的可维护性。
  3. 优化性能‌:使用final修饰局部变量可以帮助编译器进行优化,从而提高程序的执行效率。这是因为编译器可以针对final变量进行一些特定的优化,因为知道这些变量的值在使用过程中不会被修改。
  4. 避免多线程安全问题‌:在多线程环境下,final修饰的局部变量是线程安全的,因为它们的值一旦被赋值就不会改变。这避免了在多线程环境中可能出现的并发问题。
  5. 满足语法规范‌:在某些情况下,如lambda表达式中,Java编译器要求局部变量必须使用final修饰符。因此,将局部变量定义为final也是满足语法规范的一种方式。

 

2. 避免过度封装

java 代码编写过度封装的危害

在Java中,过度的封装可能会导致一些潜在的问题,如增加了系统的复杂性、可能降低了系统的性能、可能降低了代码的可读性和可维护性。

以下是一些过度封装可能导致的问题的例子:

  1. 增加了系统的复杂性:每次访问对象的属性时,都需要通过getter和setter方法,这可能会使代码变得冗长复杂。

  2. 可能降低了系统的性能:在Java中,访问对象的私有属性需要通过getter和setter方法,这可能会导致一定的性能损失。

  3. 可能降低了代码的可读性和可维护性:过度的封装可能会使代码难以理解,特别是对于那些不熟悉封装细节的开发者。

解决方案:

  1. 适度封装:在保证代码可读性和可维护性的前提下,适当的封装是必要的。

  2. 使用public final字段:对于不应该被外部修改的字段,可以使用public final修饰,这样外部只能读取,不能修改。

  3. 使用Lombok库:Lombok是一个Java库,它可以自动生成getter、setter等方法,减少了代码的冗余。

综上所述,不要刻意要求代码的封装,一般一个业务一个方法,尽量不要超过200行就可以了,对于写业务逻辑的程序员来说,没有必要刻意封装。 

3.避免在循环中创建大量对象

在Java中,在循环中创建大量对象可能导致内存溢出问题,因为这会占用大量的堆内存。如果对象创建过于频繁,可能会导致垃圾回收器(GC)频繁运行,这将影响应用程序的性能并降低整体吞吐量。

解决方案通常包括:

  1. 优化代码以减少对象创建的次数。

  2. 使用对象池或其他缓存机制来复用对象。

  3. 如果必须在循环中创建大量临时对象,请确保及时地让对象变成垃圾以便被GC回收。

// 优化实践:创建对象之前先初始化
MyObject obj = null;
for (int i = 0; i < 10000; i++) {
    if (obj == null) {
        obj = new MyObject();
    }
}

// 最后如果obj还在使用范围内,确保释放对象以避免内存泄漏
 obj = null;
 
// 更优化的实践:使用对象池
ObjectPool<MyObject> pool = new ObjectPool<>(MyObject::new);
for (int i = 0; i < 10000; i++) {
    MyObject obj = pool.borrowObject();
    // 使用obj...
    pool.returnObject(obj); // 对象使用完毕后归还到池中
}

 

4.尽量避免重复调用值固定的方法(方法的调用是有额为的性能损耗的)

        如下:

for(int i = 0; i < list.size() ; i ++)

//在每次遍历时都要调用list.size() 应改为
for(int i = 0, len = list.size() ; i < len  ; i ++)

 

5.直接访问成员变量和访问get/set方法到底哪个更好

直接访问对象的成员通常比通过方法调用对象的成员更快。

在Java中,访问对象的成员变量或调用对象的方法有几种不同的方式,每种方式都有其特定的性能特点。根据提供的数据,我们可以得出以下结论:

  1. 直接访问对象的成员变量(属性访问)‌通常比通过getter/setter方法访问要快。这是因为直接访问避免了方法调用的开销。根据提供的数据,getter/setter的性能已经接近直接属性访问,大约慢50%,这意味着在大多数情况下,没有必要担心getter/setter的性能而采用直接属性访问‌。

  2. 使用Map来存储和访问对象属性‌比使用getter/setter方法要慢得多,大约慢三倍。这表明,在考虑性能时,直接访问对象的成员变量或使用getter/setter方法通常是更优的选择‌。

  3. 反射访问‌,无论是通过Field还是通过Method访问,都比直接访问或使用getter/setter方法慢得多,甚至可以达到150倍的差异。反射访问的代价不仅在于性能上,还在于它增加了代码的复杂性,因此应谨慎使用‌。

  4. JIT(Just-In-Time编译器)的作用‌:在重复次数增加的情况下,方法访问和属性访问的差距缩小。有趣的是,反射的Method访问比Field访问快四倍。这主要是JIT的作用,它能够优化重复执行的代码,提高其执行效率‌。

综上所述,直接访问对象的成员变量通常比通过方法调用对象的成员更快。在选择访问方式时,应考虑到性能、代码的可读性和维护性等因素。在大多数情况下,使用getter/setter方法已经足够满足性能需求,并且提供了更好的封装性。而在需要动态性和灵活性时,可以考虑使用反射,但需要权衡其带来的性能开销‌

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值