我在 Java 中使用静态方法是否正确?

Do I use static methods in Java properly?

我正在 Java 中创建简单的游戏,它在后台播放音乐。

音乐 class 包含那些静态方法:

一开始我创建了“Music”的新对象 class 并调用了静态方法“playMusic':

    new Music();    
    Music.playMusic();

之所以这些方法是静态的,是因为我想在应用程序启动时开始播放音乐,但您可以在设置中选择是否播放音乐。静态方法提供了最简单的方法,因为 'Settings' class 没有 'main' 方法。

音乐class代码:

public class Music {
/// ... variables   

public Music(){     
    try{
        /// ... Preparing clip to play
        } catch (Exception e){
            /// ... Catching exception
        }
}

public static void playMusic(){
     /// ... starting music       
}

public static void stopMusic(){
      /// stoping music
}

public static void changeVol(int vol){
    /// changing volume 
}}

它工作得很好,但我想知道它是否符合 OOP 和 Java 标准?

完整音乐class代码:http://pastebin.com/d9XYX1gG

您可能想要做的是这样的事情:

Music music = new Music();
music.playMusic();

这里不需要静态方法。

如果您只想要一个可以从多个地方访问的实例,请尝试使用 Singleton:

public class Music {

    private static instance Music instance;

    private Music() {
        // initialize your stuff here
    }

    // have your instance methods here

    /**
      * This is the method to access the Music singleton
      */
    public static Music getInstance() {
        if (instance == null) {
            instance = new Music();
        }
        return instance;
    }
}

不,您不需要创建对象来调用静态方法。所以...

Music.playMusic();

...无需先创建新实例即可正常工作。

我也不认为这里真的需要静态。您可以对程序进行初始化、读取设置等,然后创建一个 Music 对象并开始播放音乐——或不播放,具体取决于设置。

不,这不是使用 OOP 的正确方法。通过使用 static 关键字,您使 class 具有不需要对象且不会有任何数据封装(在实例级别)的方法。

如果你确实想使用静态方法,你可以只写 Music.playMusic(),但是你的构造函数不会被调用。当您使用静态方法时,您无权访问实例变量,因此无论您在构造函数中准备做什么,您的静态方法都可能无法访问,因为您不能使用 this 关键字。

理想情况下,您应该从每个方法中删除 static,将您想要的任何内容传递给构造函数(如果需要),然后这样调用:

//assume file is a music file
Music music = new Music(file);
music.playMusic();

这将使用传递的音乐文件,假设这是您在构造函数中准备的。如果您在整个程序中只有其中之一,则可以使用 Singleton Pattern

如果您仍然想走静态路线,并且需要在调用任何静态方法之前一次性准备一些东西,您应该使用所谓的 class initializer。要使用它,您需要删除构造函数,因为您不需要初始化对象,而是用 class:

中看起来像这样的方法替换它
static{
    try{
        /// ... Preparing clip to play
     } catch (Exception e){
        /// ... Catching exception
     }
 }

请记住,在您调用 class(静态或对象级别)中的任何方法之前,class 初始化程序保证 运行,但是 运行在加载 class 时,不一定是在第一次调用静态方法时。