温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java方法的编写过程中要注意哪些地方

发布时间:2021-11-24 14:59:45 来源:亿速云 阅读:161 作者:iii 栏目:云计算

这篇文章主要介绍“java方法的编写过程中要注意哪些地方”,在日常操作中,相信很多人在java方法的编写过程中要注意哪些地方问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java方法的编写过程中要注意哪些地方”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

不要在构造函数中调用可以被重写的方法

一般来说在构造函数中只能调用static,final或者private的方法。为什么呢?

如果父类在执行构造函数的时候调用了一个可以被重写的方法,那么在该方法中可能会使用到未初始化的数据,从而导致运行时异常或者意外结束。

另外,还可能到方法获取到未初始化完毕的实例,从而导致数据不一致性。

举个例子,我们定义了一个Person的父类:

public class Person {

    public void printValue(){
        System.out.println("this is person!");
    }

    public Person(){
        printValue();
    }
}

然后定义了一个Boy的子类,但是在Boy子类中,重新了父类的printValue方法。

public class Boy extends Person{

    public void printValue(){
        System.out.println("this is Boy!");
    }

    public Boy(){
        super();
    }

    public static void main(String[] args) {
        Person persion= new Person();
        Boy boy= new Boy();
    }
}

输出结果:

this is person!
this is Boy!

可以看到Boy调用了自己重写过的printValue方法。

注意,这里并不是说会产生语法错误,而是这样会导致业务逻辑看起来非常混乱。

怎么解决呢?简单办法就是将Person中的printValue置位final即可。

不要在clone()方法中调用可重写的方法

同样的,我们在定义clone方法的时候也不要调用可重写的方法,否则也会产生意想不到的变化。

还是上面的例子,这次我们添加了clone方法到Person类:

public Object clone() throws CloneNotSupportedException {
        Person person= (Person)super.clone();
        person.printValue();
        return person;
    }

接下来我们添加clone方法到Boy类:

public Object clone() throws CloneNotSupportedException {
        Boy clone = (Boy) super.clone();
        clone.printValue();
        return clone;
    }

因为在clone方法中调用了可重写的方法,从而让系统逻辑变得混乱。不推荐这样使用。

重写equals()方法

考虑一下父类和子类的情况,如果在父类中我们定义了一个equals方法,这个方法是根据父类中的字段来进行比较判断,最终决定两个对象是否相等。

如果子类添加了一些新的字段,如果不重写equals方法,而是使用父类的equals方法,那么就会遗漏子类中新添加的字段,最终导致equals返回意想不到的结果。

所以一般来说,子类需要重写equals方法。

如果重新equals方法,需要满足下面几个特性:

  • reflexive反射性

对于一个Object a来说,a.equals(a)必须成立。

  • symmetric对称性

对于一个Object a和Object b来说,如果a.equals(b)==true,那么b.equals(a)==true一定成立。

  • transitive传递性

对于Object a,b,c来说,如果a.equals(b)==true,b.equals(c)==true,那么a.equals(c)==true一定成立。

  • consistent一致性

对于Object a,b来说,如果a和b没有发生任何变化,那么a.equals(b)的结果也不能变。

  • 对于非空的引用a,a.equals(null) 一定要等于false

具体代码的例子,这里就不写了,大家可以自行练习一下。

hashCode和equals

hashCode是Object中定义的一个native方法:

@HotSpotIntrinsicCandidate
    public native int hashCode();

根据Oracle的建议,如果两个对象的equals方法返回的结果是true,那么这两个对象的hashCode一定要返回同样的int值。

为什么呢?

我们看下下面的一个例子:

public class Girl {

    private final int age;

    public Girl(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (!(o instanceof Girl)) {
            return false;
        }
        Girl cc = (Girl)o;
        return cc.age == age;
    }

    public static void main(String[] args) {

        HashMap<Girl,Integer> hashMap= new HashMap<>();
        hashMap.put(new Girl(20), 20);
        System.out.println(hashMap.get(new Girl(20)));
    }
}

上面的Girl中,我们定义了equals方法,但是并没有重写hashCode,最后返回的结果是null。

因为我们new了两次Girl这个对象,最后导致native方法中两个不同对象的hashCode是不一样的。

我们可以给Girl类中添加一个hashCode方法:

public int hashCode() {
        return age;
    }

这样就可以返回正确的值。

compareTo方法的实现

我们在实现可比较类的时候,通常需要实现Comparable接口。Comparable接口定义了一个compareTo方法,用来进行两个对象的比较。

我们在实现compareTo方法的时候,要注意保证比较的通用规则,也就是说,如果x.compareTo(y) > 0 && y.compareTo(z) > 0 那么表示 x.compareTo(z) > 0.

所以,我们不能使用compareTo来实现特殊的逻辑。

最近看了一个日本的电影,叫做dubo默示录,里面有一集就是石头,剪刀,布来判断输赢。

当然,石头,剪刀,布不满足我们的通用compareTo方法,所以不能将逻辑定义在compareTo方法中。

到此,关于“java方法的编写过程中要注意哪些地方”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI