Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重构:消除构造函数中的重复_Java_Refactoring - Fatal编程技术网

Java 重构:消除构造函数中的重复

Java 重构:消除构造函数中的重复,java,refactoring,Java,Refactoring,我似乎缺少足够的咖啡来让我清楚地看到下面的问题 假设我有一个包含两个构造函数和几个字段的类。一个构造函数是无参数构造函数,一个字段依赖于另一个字段。另一个构造函数为它的一个字段接受一个注入值。例如: public class Practice { private final int n; private final char c; private final Map<String, String> m; private final Set<Str

我似乎缺少足够的咖啡来让我清楚地看到下面的问题

假设我有一个包含两个构造函数和几个字段的类。一个构造函数是无参数构造函数,一个字段依赖于另一个字段。另一个构造函数为它的一个字段接受一个注入值。例如:

public class Practice {
    private final int n;
    private final char c;
    private final Map<String, String> m;
    private final Set<String> s;

    public Practice() {
        this.n = 0;
        this.c = 'a';
        this.m = new HashMap<>();
        this.s = m.keySet();
    }
    
    public Practice(Set<String> s) {
        this.n = 0;
        this.c = 'a';
        this.m = new HashMap<>();
        this.s = s;
    }
}
公共课堂实践{
私人终审法院;
私人最终字符c;
私人最终地图m;
私人终场;
公共实践(){
这个。n=0;
this.c='a';
this.m=新的HashMap();
this.s=m.keySet();
}
公众执业(组别s){
这个。n=0;
this.c='a';
this.m=新的HashMap();
这个.s=s;
}
}
我的问题:如何消除两个构造函数之间的代码重复?

第一次失败的尝试:

public Practice() {
    this(new HashMap<>(), new HashMap<>().keySet());
}

public Practice(Set<String> s) {
    this(new HashMap<>(), s);
}

private Practice(int n, char c, Map<String, String> m, Set<String> s) {
    this.n = 0;
    this.c = 'a';
    this.m = m;
    this.s = s;
}
公共实践(){
这(new HashMap(),new HashMap().keySet());
}
公众执业(组别s){
这(新的HashMap(),s);
}
私人执业(int n,char c,Map m,Set s){
这个。n=0;
this.c='a';
这个,m=m;
这个.s=s;
}

当然,这会失败,因为无参数构造函数会创建两个独立的映射,而不是一个。对于初始版本,您可以从默认构造函数传递一个
null
,然后在设置
s
时检查
null

公共课堂实践{
私人终审法院;
私人最终字符c;
私人最终地图m;
私人终场;
公共实践(){
这个(空);
}
公众执业(组别s){
这个。n=0;
this.c='a';
this.m=新的HashMap();
this.s=null==s?m.keySet():s;
}
}
同样,可以更新包含3个构造函数的版本:

公共实践(){
这个(空);
}
公众执业(组别s){
这(0,'a',new HashMap(),s);//因为所有args构造函数都是私有的
}
私人执业(int n,char c,Map m,Set s){
这个,n=n;
这个.c=c;
这个,m=m;
this.s=null==s?m.keySet():s;
}

如果一个参数依赖于另一个参数,您可以通过添加额外的构造函数来解决问题。在这种情况下,
私人执业(地图)

公共实践(){
这个(新的HashMap());
}
公众执业(组别s){
这(新的HashMap(),s);
}
私人执业(地图){
这个(map,map.keySet());
}
私人执业(地图、地图、集合s){
这个。n=0;
this.c='a';
这个.m=映射;
这个.s=s;
}

您可以在将变量定义为成员时初始化变量。在构造函数中,您可以严格地初始化那些在初始化后可以保存不同值的变量

另请注意:由于
n
c
是原语,因此它们适合作为
静态的
,因为它们也被标记为
最终的
。这对
m
不适用

public class Practice {
    private static final int n = 0;
    private static final char c = 'a';
    private final Map<String, String> m = new HashMap<>();
    private final Set<String> s;

    public Practice() {
        this.s = m.keySet();
    }
    
    public Practice(Set<String> s) {
        this.s = s;
    }
}
公共课堂实践{
私有静态最终整数n=0;
私有静态最终字符c='a';
私有最终映射m=新HashMap();
私人终场;
公共实践(){
this.s=m.keySet();
}
公众执业(组别s){
这个.s=s;
}
}

最后,没有必要消除每一个和任何重复的代码。这方面的规则各不相同,尽管我通常遵循三个规则,或者当重复的块很大时。

只需一句话:
null==s
通常是一种C/C++风格,以防止意外分配条件,如
s=null。在java中,语言设计无法实现这一点。@JoopEggen,如果
s
属于
Boolean
类型,那么即使是语言设计也无法对抗NPE
Boolean ok=true;System.out.println((ok=null)?“ok”:“Bad”):我在90-s的中间发现了这个习惯,它就像一个安全措施,使用左边的文字和右边的“代码> ==< /代码>比较”,因为文字不能被分配。是的,对我来说,这是一种来自于允许的C/C++函数的习惯。这是一个不自然的公式(“x等于3”与“3等于x”),所以在使用java时,我通常不使用它。我想知道java代码样式检查器是否适合您的样式。@k314159。在尤达以上的情况下,似乎一点也不有害
public class Practice {
    private static final int n = 0;
    private static final char c = 'a';
    private final Map<String, String> m = new HashMap<>();
    private final Set<String> s;

    public Practice() {
        this.s = m.keySet();
    }
    
    public Practice(Set<String> s) {
        this.s = s;
    }
}