我试着理解为什么在谈论构造函数时类成员的可访问性之间存在差异.
请考虑以下示例:
class A {
static class B {
private B(String s) {}
private void foo() {}
}
static class C extends B {
public C(String s) {
super(s); // call B(String), which is private, and obviously accessible
}
void bar() {
foo(); // compilation error (symbol unknown), as B.foo() is private
}
}
}
Run Code Online (Sandbox Code Playgroud)
私人的私人成员A不应该是私人的B.对于字段和方法,情况确实如此,但似乎构造函数不遵循相同的规则.
从JLS-8(6.6.1.确定可访问性),我们可以阅读:
[...]
只有在类型可访问且声明成员或构造函数允许访问时,才能访问引用类型的成员(类,接口,字段或方法)或类类型的构造函数:
[...]
否则,声明成员或构造函数
private,当且仅当它发生在包含成员或构造函数声明的顶级类(第7.6节)的主体内时才允许访问.
任何人都可以解释为什么构造函数可以访问C,即使在声明时private?
sonarqube 错误地报告以下(简化)来源PreparedStatement has no parameters.(鱿鱼:S2695):
public static final String UPDATE_QUERY = "UPDATE TABLE SET COL1=? WHERE PK=?";
private PreparedStatement preparedStatement = null;
public void updateMethod(Date date, Long pk )
{
if(preparedStatement == null)
{
//ConnectionService is not a Connection!
preparedStatement = ConnectionService.prepareStatement(UPDATE_QUERY);
}
//sonarqube reports on the following two lines: 'This "PreparedStatement" has no parameters.'
preparedStatement.setDate(1, date);
preparedStatement.setLong(2, pk);
ResultSet rs = preparedStatement .executeQuery();
//further code left out
}
Run Code Online (Sandbox Code Playgroud)
问题:
这是分析仪的错误还是限制?
有什么我可以做的来隐藏这些"误报"吗?
声纳规则squid:S2384引发了这个代码的问题:
public Date getCreatedOn() {
return createdOn;
}
Run Code Online (Sandbox Code Playgroud)
我明白我们不应该返回原文,而是应该返回该对象的副本.
另一方面,Sonar没有就此代码提出问题:
public Date getCreatedOn() {
return this.createdOn;
}
Run Code Online (Sandbox Code Playgroud)
是什么让这个代码不同?
我们是不是在第二种情况下退回原件?
这似乎是"有条件执行的块应该可以到达"规则的误报的新例子(鱿鱼:S2583).有谁知道为什么SonarQube声称if(this.x == 0)总是false在以下Java类中进行求值?
public class MyClass {
private long x;
void setX(long x) {
this.x = x;
}
public void decrementX() {
if(this.x > 0) {
this.x--;
if(this.x == 0) { // <-- Always false?!
// apparently dead code
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
显然,变量x可以设置为1,然后decrementX()将进入这个确切的条件:
@Test
public void testDecrement() {
MyClass c = new MyClass();
c.setX(1);
c.decrementX();
}
Run Code Online (Sandbox Code Playgroud)
(使用SonarJava插件4.13.0.11627在SonarQube服务器5.6.6上执行)
更新:如Absurd-Mind所述,SonarQube在this.x缩短时很高兴x.在我看来,这是假阳性.
我的项目的分析与SonarQube失败5.6,更新后的Java插件的版本3.14来4.0.
在我的SonarQube实例中,除了其他插件之外,我目前还有需要Java插件的Findbugs插件(版本3.3)和Cobertura插件(1.6.3).
查看日志,我收到以下消息:
[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.1-build231:sonar (default-cli)
on project MyProject: Execution default-cli of goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.1-build231:sonar failed:
An API incompatibility was encountered while executing org.sonarsource.scanner.maven:sonar-maven-plugin:3.1-build231:sonar:
java.lang.NoSuchMethodError:
org.sonar.plugins.java.api.JavaResourceLocator.findResourceByClassName(Ljava/lang/String;)Lorg/sonar/api/resources/Resource;
...
Caused by: java.lang.NoSuchMethodError: org.sonar.plugins.java.api.JavaResourceLocator.findResourceByClassName(Ljava/lang/String;)Lorg/sonar/api/resources/Resource;
at org.sonar.plugins.findbugs.FindbugsSensor.analyse(FindbugsSensor.java:108)
at org.sonar.batch.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:58)
at org.sonar.batch.phases.SensorsExecutor.execute(SensorsExecutor.java:50)
at org.sonar.batch.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:83)
at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:192)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:241)
at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:236)
at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:226)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
at org.sonar.batch.task.ScanTask.execute(ScanTask.java:47)
at org.sonar.batch.task.TaskContainer.doAfterStart(TaskContainer.java:86)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
at org.sonar.batch.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:106) …Run Code Online (Sandbox Code Playgroud)