zoukankan      html  css  js  c++  java
  • 编写高质量代码:改善Java的151个建议五(类、对象、方法)31-51

    该书籍PDF下载地址:http://download.csdn.net/download/muyeju/10001473

    31.接口中不要存在实现代码

      接口中不能存在实现代码(虽然可以实现,但是如果把实现代码写在接口中,那么接口就绑定了可能变化的因素,这就导致实现不在文档和可靠,是随时可能被抛弃,被修改,被重构的)

    package jsontest;
    
    
    public class Salary {
        public static void main(String[] args) {
            B.a.doSomething();
        }
    }
    
    interface A{
        public void doSomething() ;
    }
    
    interface B{
        public static final A a = new A() {
            public void doSomething() {
                System.out.println("---------接口中的实现方法");
            }
        };
    }

    32.静态变量一定要先声明后赋值

      静态变量的加载过程:静态变量是类初始化时首先被加载的,JVM会去查找类中的所有静态声明,然后分配空间,这时候只是完成了地址的分配,还没有赋值,JVM会根据类中的静态赋值(静态类赋值和静态块赋值)的先后顺序来执行。静态变量在内存中只有一个拷贝,其后的所以赋值操作都是改变其值,地址不会改变。

    33.不要覆写静态方法(可以隐藏)

      一个实例对象有2个类型,表面类型和实际类型,表面类型是声明时的类型,实际类型是对象产生时的类型。对于非静态方法,它是根据对象的实际类型来执行的。而对于静态方法,一方面静态方法不依赖实例对象,它是通过类名访问的;其次可以通过对象访问静态方法,如果是通过对象调用静态方法,JVM会通过对象的表面类型查找静态方法的入口。

      隐藏:在子类中构建与父类相同的方法名、输入参数、输出参数、访问权限、并且父类和子类都是静态方法,此种行为叫隐藏

      隐藏和覆写的区别:

        1.隐藏用于静态方法,覆写用于非静态方法,隐藏没有@Override

        2.隐藏的目地是抛弃父类方法,重现子类方法。而覆写则是增加或虚弱父类的行为,延续父类的职责

      注:通过实例方法访问静态方法静态属性不是好习惯,给代码带来了坏问道,建议戒之

    34.构造函数尽量简单

      子类实例化的过程:首先初始化父类的变量,然后调用父类的构造方法,再初始化子类的变量,然后调用子类的构造方法,最后生成实例对象

    35.不要在构造函数中初始化其它类

    36.使用构造代码块精炼程序

      构造代码块:在类中没有任何前缀和后缀,并使用{}括起来的代码片段

      构造代码块会在每个构造函数内首先执行(需要注意的是:构造代码块不是在构造函数之前运行的,它依托于构造函数的执行)

      使用场景:

        初始化实例变量:如果每个构造函数都要初始化变量,可以通过构造代码块实现

        初始化实例环境

    37.构造代码块会想你所想

      java编译器会把构造代码块插入到每一个构造函数中,但是如果遇到this关键字,则不插入构造代码块

    38.使用静态内部类提高封装性

      静态内部类:在类中的静态类就是静态内部类。

      内部类:在类中的类

      区别:

        静态内部类只能访问外部类的静态方法和静态属性,而内部类有外部类的引用,可以自由访问

        静态内部类独立于外部类存在,而内部类不能脱离外部类存在

        普通内部类中,不能声明static的属性和方法,而静态内部类没有任何限制

    39.使用匿名类的构造函数

      匿名类的构造函数用构造函数块来代替

      例:Apple a = new Apple{{}}

    40.匿名类的构造函数很特殊

    41.让多重继承成为现实

      通过内部类实现(内部类去继承需要的类)

    42.让工具类不可实例化

      保证工具类只能通过类名访问,不能通过实例对象访问。(工具类里面的属性和方法都设为静态的)

      要保证不能被实例化,就要将该类的构造方法设为私有,同时在抛异常。

      例:

    public class DatesUtil {
        
        private DatesUtil(){
            throw new Error("不要实例化我,请通过类名调用") ;
        }
    }

    43.避免对象的浅拷贝

      类实现了Cloneable接口就具备了拷贝的能力,然后覆写clone方法就完全具备拷贝的能力

      Object提供了一个对象的默认拷贝方法,即super.clone(),该方法有缺陷,是一种浅拷贝方式,它是有选择性的拷贝,规则如下:

      1.基本类型只拷贝值

      2.对象拷贝地址引用

      3.String对象拷贝的是地址引用,但是修改值时它会从字符串池中重新生成新的字符串,原来的字符串保持不变,在此我们可以认为它是一个基本类型

    44.推荐使用序列化实现对象的拷贝

      类要实现序列化接口,然后调用序列化工具,SerializableUtils.deepCopy方法就可以实现拷贝了

      

     45-49:实体类中建议重写toString()、equals()、hashcode()方法

        alt+shift+S

        

        equals判断的时候要考虑null的情况
        equals中使用getClass()进行类判断
        重写toString()是直接打印对象时能看到相关信息,例People [age=20, name=李四, sex=0],不重写的话就是类似这种jsontest.People@18f0fc6
        重写equals()和hashcode()是判断是否相等时用到
        HashMap的底层机制:是以数组的方式保存Map条目的,其中的关键是数组下标的处理机制:依据传入元素的hashcode的返回值来决定数组的下标,如果数组的位置上已 经有 了Map条目,且与传入的键值相等,则不处理,如果不相等就覆盖,如果传入的位置上没有条目就插入,然后放到Map条目的链表中。同理,检查键是否存在,也是根据哈西码确定位置,然后遍历查找位置。

    50.使用package-info类为包服务(没细看)  

    51.不要主动进行垃圾回收

  • 相关阅读:
    P1363-幻象迷宫
    P1582-倒水
    P2123-皇后游戏
    P1233-木棍加工
    P1052-过河
    P1541-乌龟棋
    P1736-创意吃鱼法
    P1417-烹调方案
    LeetCode--043--字符串相乘(java)
    LeetCode--041--缺失的第一个整数(java)
  • 原文地址:https://www.cnblogs.com/-scl/p/7643905.html
Copyright © 2011-2022 走看看