Java Netbeans 警告:通过公共 API 导出非公共类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18944336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 12:46:37  来源:igfitidea点击:

Netbeans warning: Exporting non-public type through public API

javaapistaticencapsulation

提问by nellykvist

I'm creating a Slick2D game. Right now, I'm creating a Video class, which contains inner classes (FrameSize, FPS, FullScreen..). So I had an OOD idea to crate in way, like we call System.out.println(). That means that I will have public Video class and public static instances of his inner clasess, but netbeans IDE throws me a hint with "Exporting non-public type through public API ". So, should I just ignore that and keep doing the way I was doing or it would be great if you could suggest me your idea?

我正在创建一个 Slick2D 游戏。现在,我正在创建一个 Video 类,其中包含内部类(FrameSize、FPS、FullScreen ..)。所以我有一个 OOD 的想法来打包,就像我们调用 System.out.println() 一样。这意味着我将拥有他的内部类的公共 Video 类和公共静态实例,但是 netbeans IDE 提示我“通过公共 API 导出非公共类型”。那么,我应该忽略这一点并继续做我正在做的事情,或者如果你能向我提出你的想法会很棒吗?

VIDEO

视频

public class Video {

    public static FrameSize frameSize;
    public static FullScreen fullScreen;
    public static FPS fps;

    private Video() {}

    public static void loadArguments(Scanner loadInput) {
        boolean isVideo = false;
        String readLine;

        while (loadInput.hasNext()) {
            readLine = loadInput.next();
            if (readLine.equalsIgnoreCase("video")) {
                isVideo = true;
                break;
            }
        }

        while (isVideo && loadInput.hasNext()) {
            readLine = loadInput.next();
            if (readLine.equalsIgnoreCase("end")) {
                break;
            }
            String[] line = readLine.split("=");

            String key = line[0];
            String value = line[1];

            switch (key) {
                case "width":
                    frameSize.setWidth(Integer.parseInt(value));
                    break;
                case "height":
                    frameSize.setHeight(Integer.parseInt(value));
                    break;
                case "fullscreen":
                    break;
                case "fps":
                    break;
                default:
                    System.err.println("Unknown video key: " + key);
                    break;
            }
        }
    }

    public static void saveArguments(String filePath) {
        Scanner saveInput;
        try {
            saveInput = new Scanner(new File(filePath));
        } catch (FileNotFoundException fne) {
            System.err.println("Invalid settings-file.");
            return;
        }

        // TO DO: save function

        saveInput.close();
    }

    class FrameSize {

        public final int[][] SIZE_VALUES = {
                {800, 600},
                {1000, 700},
                {1200, 800},
                {1400, 900}
        };

        private int index;
        private int width, height;

        private FrameSize() {}

        public void setSize(int width, int height) {
            this.width = width;
        }

        public int getWidth() {
            return width;
        }

        public void setWidth(int width) {
            this.width = width;
        }

        public int getHeight() {
            return height;
        }

        public void setHeight(int height) {
            this.height = height;
        }

        @Override
        public String toString() {
            return this.width + " x " + this.height;
        }

    }

    class FullScreen {

        private boolean fullScreen;

        private FullScreen() {}

        public boolean isFullScreen() {
            return fullScreen;
        }

        public void setFullScreen(boolean fullScreen) {
            this.fullScreen = fullScreen;
        }

        @Override
        public String toString() {
            return "" + fullScreen;
        }        
    }

    class FPS {

        private boolean FPS;

        private FPS() {}

        public boolean isFPS() {
            return FPS;
        }

        public void setFPS(boolean FPS) {
            this.FPS = FPS;
        }        

        @Override
        public String toString() {
            return "" + fps;
        }

    }

}

AUDIO

声音的

public class Audio {

    private static Sound sound;
    private static Volume volume;

    private Audio() {}

    public void loadArguments(Scanner loadInput) {
        boolean isAudio = false;
        String readLine;

        while (loadInput.hasNext()) {
            readLine = loadInput.next();
            if (readLine.equalsIgnoreCase("audio")) {
                isAudio = true;
                break;
            }
        }

        while (isAudio && loadInput.hasNext()) {
            readLine = loadInput.next();
            if (readLine.equalsIgnoreCase("end")) {
                break;
            }
            String[] line = readLine.split("=");

            String key = line[0];
            String value = line[1];

            switch (key) {
                case "sound":
                    break;
                case "volume":
                    break;
                default:
                    System.err.println("Unknown audio key: " + key);
                    break;
            }
        }
    }

    public void saveArguments(String filePath) {
        Scanner saveInput;
        try {
            saveInput = new Scanner(new File(filePath));
        } catch (FileNotFoundException fne) {
            System.err.println("Invalid settings-file.");
            return;
        }

        // TO DO: save function

        saveInput.close();
    }

    class Sound {

        private boolean sound;

        private Sound() {}

        public boolean isSound() {
            return sound;
        }

        public void setSound(boolean sound) {
            this.sound = sound;
        }

        @Override
        public String toString() {
            return "" + sound;
        }        
    }

    class Volume {

        private static final double PITCH = 0.1d;
        private double volume;

        private Volume() {}

        public double getVolume() {
            return volume;
        }

        public void setVolume(double volume) {
            this.volume = volume;
        }

        public void increaseVolume() {
            if (!isVolumeRange(this.volume)) {
                return;
            }
            this.volume = this.volume + PITCH;
        }

        public void decreaseVolume() {
            if (!isVolumeRange(this.volume)) {
                return;
            }
            this.volume = this.volume - PITCH;
        }

        public boolean isVolumeRange(double volume) {
            return volume >= 0.0 && volume <= 10.0;
        }

    }

}

采纳答案by krokodilko

Videoclass contains a declaration of a public class variable frameSizeof type FrameSize.
A publicmodifier means, that frameSizevariable is visible to all.

Videoclass 包含frameSize类型为公共类变量的声明FrameSize
一个public修改意味着,frameSize变量是大家有目共睹的。

package package1;

public class Video {
   public static FrameSize frameSize;
}
// private class
class FrameSize {
}

However FrameSizeis a local class - it is visible only to members of the same package. In the above example, only members of package package1can see that class, and below code compiles fine:

然而FrameSize是一个本地类——它只对同一个包的成员可见。在上面的例子中,只有包的成员package1才能看到那个类,下面的代码编译得很好:

package package1;

public class Test {

    void test(){
        FrameSize x = Video.frameSize;
    }
}

however this code (different package) gives a compilation error:

但是这段代码(不同的包)给出了一个编译错误:

package package2;
import package1.*;

public class Test {
  void test(){
    // this line won't compile - FrameSize class is unknown
    FrameSize x = Video.frameSize; 

    // but this line compiles fine - Object class is public
    Object y = Video.frameSize; 
   }
}

NetBeans warns you about this, because most likely it is unintentional error - why do you want to make some field value accessible to all without publishing the type of this field, that in effect prevents them from using that field ?

If you want make the variable accessible only to other classes within the same package, declare it as protected, not public.
But if it is an intentional declaration - then ignore the warning and leave it as is.

NetBeans 会就此向您发出警告,因为这很可能是无意错误 - 为什么要在不发布此字段类型的情况下让所有人都可以访问某些字段值,这实际上阻止了他们使用该字段?

如果您想让该变量只能被同一包中的其他类访问,请将其声明为protected,而不是public
但是,如果它是有意声明,则忽略警告并保持原样。