zoukankan      html  css  js  c++  java
  • Effective Java 41 Use overloading judiciously

    The choice of which overloading to invoke is made at compile time.

       

    // Broken! - What does this program print?

    public class CollectionClassifier {

    public static String classify(Set<?> s) {

    return "Set";

    }

    public static String classify(List<?> lst) {

    return "List";

    }

    public static String classify(Collection<?> c) {

    return "Unknown Collection";

    }

    public static void main(String[] args) {

    Collection<?>[] collections = {

    new HashSet<String>(),

    new ArrayList<BigInteger>(),

    new HashMap<String, String>().values()

    };

    for (Collection<?> c : collections)

    System.out.println(classify(c));

       

    // the result will prints three times "Unknown Collection"

    }

    }

       

    Selection among overloaded methods is static, while selection among overridden methods is dynamic.

       

    The compile-time type of an object has no effect on which method is executed when an overridden method is invoked; the "most specific" overriding method always gets executed.

       

    class Wine {

    String name() { return "wine"; }

    }

    class SparklingWine extends Wine {

    @Override String name() { return "sparkling wine"; }

    }

    class Champagne extends SparklingWine {

    @Override String name() { return "champagne"; }

    }

    public class Overriding {

    public static void main(String[] args) {

    Wine[] wines = {

    new Wine(), new SparklingWine(), new Champagne()

    };

    for (Wine wine : wines)

    System.out.println(wine.name());

    // This will print "wine" "sparking wine" "Champagne"

    }

    }

       

    Principle

    1. A safe, conservative policy is never to export two overloadings with the same number of parameters.

       

    public class SetList {

    public static void main(String[] args) {

    Set<Integer> set = new TreeSet<Integer>();

    List<Integer> list = new ArrayList<Integer>();

    for (int i = -3; i < 3; i++) {

    set.add(i);

    list.add(i);

    }

    for (int i = 0; i < 3; i++) {

    set.remove(i);

    list.remove(i);

    }

    System.out.println(set + " " + list);

    // This will prints [-3, -2, -1] [-2, 0, 2]

    }

    }

    The call to set.remove(i)selects the overloading remove(E), where E is the element type of the set (Integer), and autoboxes I from int to Integer.

       

    The call to list.remove(i), on the other hand, selects the overloading remove(int i), which removes the element at the specified position from a list.

       

    2. The standard way to ensure behavior of the types of the same super class or interface as the parameter of a method is to have the more specific overloading forward to the more general.

       

    public boolean contentEquals(StringBuffer sb) {

    return contentEquals((CharSequence) sb);

    }

       

    Summary

    You should generally refrain from overloading methods with multiple signatures that have the same number of parameters. You can name the method with same prefix rather than overloading the write method. Such as, these variants of ObjectOutputStream have signatures like writeBoolean(boolean), writeInt(int), and writeLong(long).

       

    In some cases, especially where constructors are involved, it may be impossible to follow this advice. In that case, you should at least avoid situations where the same set of parameters can be passed to different overloadings by the addition of casts. In this case you have the option of exporting static factories instead of constructors (Item 1).

       

    If such a situation cannot be avoided, for example, because you are retrofitting an existing class to implement a new interface, you should ensure that all overloadings behave identically when passed the same parameters.

       

       

  • 相关阅读:
    .NET Core下的Socket示例.
    VS没办法调试,直接退出,报错:1. 使用调试生成配置或禁用调试选项“启用‘仅我的代码’”。。。
    2017年2月7日 今年第一天上班了
    .NET Core错误:The specified framework 'Microsoft.NETCore.App', version '1.0.0-rc2-3002702' was not found.
    KB2533623 下载
    Ajax Not Found,asp.net mvc 中
    JavaScript外部函数调用AngularJS的函数、$scope
    029医疗项目-模块三:药品供应商目录模块——供货商药品目录查询功能----------数据模型的分析(建表)
    028医疗项目-模块三:药品供应商目录模块——供货商药品目录查询功能----------需求分析
    50个查询系列-第10个查询:查询没有学全所有课的同学的学号、姓名;
  • 原文地址:https://www.cnblogs.com/haokaibo/p/use-overloading-judiciously.html
Copyright © 2011-2022 走看看