Java-不可实例化类中缺少静态方法
我有“建筑工人”等级,声纳发出以下警告:Java-不可实例化类中缺少静态方法,java,sonarqube,Java,Sonarqube,我有“建筑工人”等级,声纳发出以下警告: Missing Static Method In Non Instantiatable Class pmd : MissingStaticMethodInNonInstantiatableClass A class that has private constructors and does not have any static methods or fields cannot be used 如何重构该类以满足上述检查? 我挠头是因为我用过那门课
Missing Static Method In Non Instantiatable Class
pmd : MissingStaticMethodInNonInstantiatableClass
A class that has private constructors and does not have any static methods or fields cannot be used
如何重构该类以满足上述检查?
我挠头是因为我用过那门课
样本使用:
ViewBuilder vb = new ViewBuilder.Builder()
.modelPart(CONTENT_PAGE, contentPageDao.get(id))
.modelPart("navigation_sections", navigationSectionDao.list() )
.modelPart("available_tags", tagDao.list() )
.modelPart("available_albums", albumDao.list() )
.section(CONTENT_PAGE)
.page("index")
.element("form")
.action("/admin/content_page/save/" + id + ".html")
.build();
类本身:
import java.util.HashMap;
import java.util.Map;
public final class ViewBuilder {
private static final String ADMIN_LAYOUT = "admin/layout";
private String layout = ADMIN_LAYOUT;
private String section = "";
private static Map<String, Object> viewParts = new HashMap<String, Object>();
/**
* @return the layout
*/ public String getLayout() {
return layout;
}
/**
* @param layout the layout to set
*/ public void setLayout(String layout) {
this.layout = layout;
}
/**
* @return the section
*/ public String getSection() {
return section;
}
/**
* @param section the section to set
*/ public void setSection(String section) {
this.section = section;
}
public static class Builder{
// required params
private String layout;
private String section;
// optional params
private Map<String, Object > viewParts = new HashMap<String, Object >();
public Builder(){
this.layout = ADMIN_LAYOUT;
viewParts.put("layout", ADMIN_LAYOUT);
}
public Builder( String layout ){
if( layout != null ){
this.layout = layout;
viewParts.put("layout", layout );
} else {
this.layout = ADMIN_LAYOUT;
viewParts.put("layout", ADMIN_LAYOUT);
}
}// constructor
public Builder modelPart( String val, Object o ){
this.viewParts.put(val, o );
return this;
}
public Builder action( String val ){
this.viewParts.put("action", val);
return this;
}
public Builder element( String val ){
this.viewParts.put("element", val);
return this;
}
public Builder section( String val ){
this.section = val;
this.viewParts.put("section", val);
return this;
}
public Builder page( String val ){
this.viewParts.put("page", val);
return this;
}
public Builder layout( String val ){
this.layout = val;
return this;
}
public ViewBuilder build( ){
return new ViewBuilder( this );
}
}// Builder
private ViewBuilder(Builder builder){
this.section = builder.section;
this.layout = builder.layout;
viewParts = builder.viewParts;
}
/**
* Get the value of viewParts
*
* @return the value of viewParts
*/
public Map<String, Object> getViewParts() { return viewParts; }
/**
* Set the value of viewParts
*
* @param viewParts new value of viewParts
*/
public void setViewParts(Map<String, Object> viewParts) { this.viewParts = viewParts; }
}
import java.util.HashMap;
导入java.util.Map;
公共最终类ViewBuilder{
私有静态最终字符串ADMIN\u LAYOUT=“ADMIN/LAYOUT”;
私有字符串布局=管理布局;
私有字符串部分=”;
private static Map viewParts=new HashMap();
/**
*@返回布局
*/公共字符串getLayout(){
返回布局;
}
/**
*@param layout要设置的布局
*/公共void setLayout(字符串布局){
this.layout=布局;
}
/**
*@返回该节
*/公共字符串getSection(){
返回段;
}
/**
*@param section要设置的节
*/公共无效设置部分(字符串部分){
this.section=section;
}
公共静态类生成器{
//必需参数
私有字符串布局;
私有字符串部分;
//可选参数
private-Map-viewParts=new-HashMap();
公共建筑商(){
this.layout=管理布局;
viewParts.put(“布局”,管理布局);
}
公共生成器(字符串布局){
if(布局!=null){
this.layout=布局;
viewParts.put(“布局”,布局);
}否则{
this.layout=管理布局;
viewParts.put(“布局”,管理布局);
}
}//建造师
公共生成器modelPart(字符串val,对象o){
this.viewParts.put(val,o);
归还这个;
}
公共生成器操作(字符串val){
this.viewParts.put(“action”,val);
归还这个;
}
公共生成器元素(字符串val){
this.viewParts.put(“元素”,val);
归还这个;
}
公共生成器部分(字符串val){
this.section=val;
this.viewParts.put(“section”,val);
归还这个;
}
公共生成器页面(字符串val){
this.viewParts.put(“page”,val);
归还这个;
}
公共生成器布局(字符串val){
this.layout=val;
归还这个;
}
公共ViewBuilder生成(){
返回新的ViewBuilder(此);
}
}//建筑商
专用视图生成器(生成器){
this.section=builder.section;
this.layout=builder.layout;
viewParts=builder.viewParts;
}
/**
*获取viewParts的值
*
*@返回viewParts的值
*/
公共映射getViewParts(){return viewParts;}
/**
*设置viewParts的值
*
*@param viewParts viewParts的新值
*/
public void setViewParts(映射viewParts){this.viewParts=viewParts;}
}
鉴于您的嵌套构建器类是公共的
和静态的
,我真的看不到嵌套的好处。我建议将其划分为自己的顶级课程。当然,这不是PMD抱怨的原因。您的外部类,ViewBuilder
,没有公共构造函数,也没有静态方法。因为它现在已经存在,所以它在Builder
类周围是一个相当无用的“名称空间包装器”。要么给它添加一个构造函数,要么完全去掉它。鉴于您的嵌套构建器类是public
和static
,我真的认为嵌套它没有什么好处。我建议将其划分为自己的顶级课程。当然,这不是PMD抱怨的原因。您的外部类,ViewBuilder
,没有公共构造函数,也没有静态方法。因为它现在已经存在,所以它在Builder
类周围是一个相当无用的“名称空间包装器”。要么向其添加构造函数,要么完全删除它。需要更新SonarQube PMD规则,以考虑静态嵌套构建器类中的访问器
为此创建了PMD问题,但看起来已被放弃:
我不同意“重构”来消除这种声纳冲突,构建器模式是众所周知的,在创建复杂对象时非常有用。
参见“有效Java”第2章第2项。
需要更新SonarQube PMD规则,以考虑静态嵌套生成器类中的访问器 为此创建了PMD问题,但看起来已被放弃: 我不同意“重构”来消除这种声纳冲突,构建器模式是众所周知的,在创建复杂对象时非常有用。 参见“有效Java”第2章第2项。
满足此检查的另一种方法是使构造函数包私有而不是私有。这样做的另一个好处是,编译器不再需要为内部类ref生成具有包私有访问权限的额外合成构造函数 如果您强烈希望保持构造函数的私有性,以防止同一包中的其他类在不使用
Builder.build()
的情况下创建实例,那么您应该能够通过以下方法抑制Sonar问题:
// private constructor to enforce the use of Builder.build()
@SuppressWarnings("pmd:MissingStaticMethodInNonInstantiatableClass")
满足此检查的另一种方法是使构造函数包私有而不是私有。这样做的另一个好处是,编译器不再需要为内部类ref生成具有包私有访问权限的额外合成构造函数 如果您强烈希望保持构造函数的私有性,以防止同一包中的其他类在不使用
Builder.build()
的情况下创建实例,那么您应该能够通过以下方法抑制Sonar问题:
// private constructor to enforce the use of Builder.build()
@SuppressWarnings("pmd:MissingStaticMethodInNonInstantiatableClass")
+1.“公共的和静态的,我真的看不到嵌套的好处”这正是实现“构建器模式”的方式。如果您认为它“没有什么价值”,我建议您对构建器模式进行一些研究。简而言之,就是能够在保证状态下可靠地创建对象。私有类用于确保外部类构造函数是唯一的调用