【问题标题】:Java: unable to access static singleton methodJava:无法访问静态单例方法
【发布时间】:2009-11-11 09:08:40
【问题描述】:

我面临一个问题。我有一个名为“ReportingService”的类,它应该是单例的,并且正在扩展“CommonService”。

package MyApp.Services.ReportingService;

public class ReportingService extends CommonService {

    private static ReportingService instance = null;

    public static ReportingService getInstance() {
        if (instance == null) {
            instance = new ReportingService();
        }
        return instance;   

    }
}

并在我正在使用的其他类中访问该类

package MyApp.Services.WebReportingService;
@WebMethod(operationName = "registerUDP")
    public boolean registerUDP(
            @WebParam(name = "Friendly Name") String friendlyName,
            @WebParam(name = "Username") String username,
            @WebParam(name = "Password") String password,
            @WebParam(name = "Communication Protocol") CommunicationProtocol communicationProtocol,
            @WebParam(name = "IP Address") String ipAddress,
            @WebParam(name = "Port") int port) {

        Consumer client = new Consumer(friendlyName, username, password, communicationProtocol, ipAddress, port);

ReportingService rs = ReportingService.
        return true;

    }

在“ReportingService rs = ReportingService”中。它没有显示 ReportingService 类的 getInstance() 方法。我还导入了正确的包。

注意:两个类位于不同的包中。

【问题讨论】:

  • 您导入了 ReportingService 吗?
  • 但是即使在IDE中也不显示方法,可以手动添加并编译代码吗?
  • 看起来您只是在 IDE 中遇到了自动完成问题...尝试键入 ReportingService.getInstance() 并查看您是否有编译错误
  • 那是 IDE 中的确切代码吗?

标签: java static singleton


【解决方案1】:

如下更改:

package MyApp.Services.ReportingService;  // FIXME - Make package names lowercase!!
                                          // FIXME - Loopy package name

public class ReportingService extends CommonService {

    private static ReportingService instance = null;

    private ReportingService() { }

    public static synchronized ReportingService getInstance() {
        if (instance == null) {
            instance = new ReportingService();
        }
        return instance;   

    }
}

import MyApp.Services.ReportingService.ReportingService; 

package MyApp.Services.WebReportingService ; 
                        // FIXME - Make package names lowercase!!
                        // FIXME - Loopy package names.

public class WebReportingService {

    @WebMethod(operationName = "registerUDP")
    public boolean registerUDP(
            @WebParam(name = "Friendly Name") String friendlyName,
            @WebParam(name = "Username") String username,
            @WebParam(name = "Password") String password,
            @WebParam(name = "Communication Protocol") CommunicationProtocol communicationProtocol,
            @WebParam(name = "IP Address") String ipAddress,
            @WebParam(name = "Port") int port) {

        Consumer client = new Consumer(friendlyName, username, password,
                                       communicationProtocol, ipAddress, port);

        ReportingService rs = ReportingService.getInstance();
        return true;
    }
}

注意:根据定义ConsumerCommunicationProtocol类的包,您可能需要导入它们;例如在package 行之前添加这些行。

import some.package.Consumer;
import some.other.package.CommunicationProtocol;

注意 2:您当前选择的包名称存在一些严重的样式问题。

  • 包名应全部小写

  • 你的包名称的前缀应该是你的公司、组织等的(反向)DNS 样式标识符;例如in.com.yourcompany...。请注意,形成这种约定有很好的理由!

  • MyApp / myapp 内容免费,不应使用

  • services.reportingservice 是多余的/冗长的;例如改用services.reporting

  • 使用同名作为类和包名是多余的/冗长的

  • 除非reportingwebreporting 包中有很多类,否则它们可能应该合并到一个包中。大量包含 1 或 2 个类的包没有帮助。

【讨论】:

  • 这两个类在不同的包中
  • 那么你真的有一个名为 MyApp.Services.WebReportingService.WebReportingService 和 MyApp.Services.ReportingService.ReportingService 的类吗?这对我来说似乎有点循环。
  • 是的,有课程。看“MyApp.Services.ReportingService”是包名,“ReportingService”是这个包中的类。所以当我导入这个包时,我正在写“MyApp.Services.ReportingService.ReportingService”
  • 根据您的 cmets 更改。再试一次。
  • +1 表示synchronized getInstance()!此外,单例需要声明的 private 构造函数(以防万一这是整个代码)。
【解决方案2】:

我认为您的包裹名称已损坏。您似乎在包的末尾有类的名称 - 但类的名称仅在您导入时出现。

所以你会有:

package myApp.Services;

public class ReportService extends CommonService {/* code goes here */}

但是你会包括:

import myApp.Services.ReportService;

WebReportingService 也是如此。 package 语句不应包含类名

编辑:如果你真的想要 ReportService 在包 myApp.Services.ReportService 中,那么你需要导入 myApp.Services.ReportService.ReportService(或者,myApp.Services.ReportService.*,但不建议这样做,除非你需要包中的许多类)

【讨论】:

  • 仍然无法访问。我在 WebReportingService 的导入语句中尝试了完整的类名
  • 尝试在代码中写下整个包名;类似:myApp.Services.ReportService.ReportService rs = myApp.Services.ReportService.ReportService.getInstance()。还要检查Consumer 类,这似乎也有问题(它没有找到Observer 类,可能是另一个导入错误)
【解决方案3】:

不能确定,但​​我看到当导入的类与代码过时时会发生这种问题。

这可能发生在不同的 IDE 上,没有简单的解决方案:也许清理所有类并重新编译它们?

【讨论】:

    【解决方案4】:

    我会尝试手动输入 getInstance(),正如其他人在他们的 cmets 中所建议的那样。那应该行得通。我相信您的 IDE 在键入点 (.) 后不会向您显示该方法的原因可能仅仅是因为以下返回 true。正在阅读中

    ReportingService rs = ReportingService.return true;
    

    它认为代码损坏,因此不会提供代码补全。

    【讨论】:

      【解决方案5】:

      您必须在源文件顶部导入 ReportingService 类,如下所示:

      import MyApp.Services.ReportingService.ReportingService;
      

      编辑: 第二个代码 sn-p 也缺少类声明。如果这是完整源代码,则无法编译。

      基于编译器输出的另一个编辑:如果您在 Consumerclass 似乎依赖的类路径中有 xx.xx.Java.Common.DesignPattern.ObserverPattern.Observer 类,这也会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-28
        • 1970-01-01
        相关资源
        最近更新 更多