430

Java에서 정적으로 클래스를 선언 할 수없는 이유는 무엇입니까?


  • 반대 질문 : 최상위 클래스를 다음과 같이 선언하면 효과가 어떻게 나타날 것이라고 기대할 수 있습니까?static? - Joachim Sauer
  • 아니요, 정적 인 내부 클래스를 제외하고는 할 수 없습니다. 하지만, 그걸로 무엇을 이루고 싶습니까? - manolowar
  • @ Joachim Sauer : 음, C #해석static수업abstract final즉, 인스턴스를 생성 할 수 없으며 확장 할 수 없습니다. 이는 정적 멤버 만 포함 할 수 있다는 것을 의미하며 이는 도우미 메서드 만 포함하는 클래스에 유용합니다. - bcat
  • @bcat 이것은 C #의 경우에 해당하지만 Java 클래스는 abstract 또는 final 둘 중 하나가 될 수 있습니다. 클래스가 인스턴스화되지 않게하려면 private 생성자를 선언 할 수 있습니다. - Lorenzo Polidori
  • @JoachimSauer 간단합니다. 클래스의 모든 멤버를 정적으로 설정하는 것을 좋아합니다 (각 메서드 또는 속성에 선언 할 필요조차 있습니다). - hmartinezd

14 답변


462

중첩 된 클래스 만 정적 일 수 있습니다. 이렇게하면 외부 클래스의 인스턴스가 없어도 중첩 클래스를 사용할 수 있습니다.

class OuterClass{
    public static class StaticNestedClass{
    }

    public class InnerClass{
    }

    public InnerClass getAnInnerClass(){
        return new InnerClass();
    }

    //This method doesn't work
    public static InnerClass getAnInnerClassStatically(){
        return new InnerClass();
    }
}

class OtherClass{
    //Use of a static nested class:
    private OuterClass.StaticNestedClass staticNestedClass = new OuterClass.StaticNestedClass();

    //Doesn't work
    private OuterClass.InnerClass innerClass = new OuterClass.InnerClass();

    //Use of an inner class:
    private OuterClass outerclass= new OuterClass();
    private OuterClass.InnerClass innerClass2 = outerclass.getAnInnerClass();
    private OuterClass.InnerClass innerClass3 = outerclass.new InnerClass();
}

출처 :

같은 주제에 대해 :


  • 첫 번째 문구가 정확하지 않더라도 +1. 이 자습서에서 " 비 정적 중첩 클래스는 내부 클래스라고합니다. " (JLS : "내부 클래스는 명시 적으로 또는 묵시적으로 정적으로 선언되지 않은 중첩 클래스입니다.") - Carlos Heuberger
  • 당신은 가장 확실하게 옳습니다; 그러나 이것이 질문에 어떻게 대답하는지 보지 못합니다. - Joeri Hendrickx
  • @Carlos Heuberger, 네 말이 맞다. 나는 그 글을 업데이트했다. @Joeri Hendrickx, 질문은 " 왜 수업을 정적으로 선언 할 수 없습니까? "라고 할 수 있으며, 여기에서 내 글을 읽을 수 있습니다. 정적 클래스의 사용법과 왜 중첩 클래스 여야하는지에 대한 설명입니다. - Colin Hebert
  • 여기에 주어진 해결책은 괜찮습니다 ...하지만 여전히 y ppl 논리적으로 설명하지 않은 정적 클래스는 자바에서 가능하지 않습니다 .. 일부 OOPs 개념 설명은 옳은 대답이 될 것입니다. 나는 그것을 기다리고있다. - Punith Raj
  • 그건 사실이지만, 당신이 생각하는 질문은 보통 "정적 클래스"가 무엇인지 자문하기 시작할 때 스스로 해결합니다. . 자바에서 정적 요소는 둘러싼 클래스의 인스턴스없이 액세스하거나 호출 할 수 있다는 것을 의미합니다. 키워드 자체를 클래스에 적용하면 무엇을 의미할까요? 당신의 의도는 무엇입니까? 너는 무엇을 기대 하느냐? 이제는 무엇이 될 수 있는지에 대한 아이디어를 얻었으므로 " 실제로 이해할 수 없음 " 또는 "먼 페치 (far fetched)"될 것이다. (그것은 의미가있을 것입니다 만, 그것이 끝난 것은 단지 선택되었습니다.) - Colin Hebert

31

그래서 나는 파티에 늦게 갈 것입니다. 그러나 여기에 나의 두 센트가 있습니다 - 철학적으로 콜린 헤 버트의 대답에 덧붙여서.

높은 수준에서 질문은 객체와 유형의 차이점을 다룹니다. 많은 자동차 (개체)가 있지만 Car 클래스 (유형)는 하나뿐입니다. 정적으로 선언하는 것은 "유형"공간에서 작업하고 있음을 의미합니다. 하나만 있습니다. 최상위 클래스 키워드는 이미 "유형"공간에 유형을 정의합니다. 결과적으로 "public static class Car"는 중복됩니다.


  • 예. 다른 말로하면 최상위 수준 클래스는 기본적으로 정적이므로 키워드가 필요하지 않습니다. - Warren Dew
  • 글쎄, 워렌 듀 (Warren Dew)가 말한 것에 덧붙이 자면, "최상위 클래스는 정적 멤버에 액세스 할 때 기본적으로 정적입니다." - Dexter
  • 과소 평가 된 대답. 클래스의 모든 메소드를 정적으로 만들고 생성자를 비공개로 만드는 새로운 키워드. 혼란 스럽기 때문에 정적이라고 이름을 짓지는 않겠습니다. - G_V
  • @G_V 자바가 그런 괴물을 만들 수는 있겠지만 자바는 어리석은 일을 어렵게 만든다. 통계는 일반적으로 나쁜 생각입니다. 정적 클래스는 끔찍합니다 (그 자체가 안티 패턴으로 간주되는 싱글 톤보다 나쁩니다). 많은 사람들이 이것을 이해하지 못하므로 키워드를 부여하는 것은 매우 나쁜 생각입니다. 그 대신에 우리는 나쁜 일을 어렵게 만들고 그 일에 그냥 맡깁니다. "싱글 톤 (Singleton)"은 존재하지 않는다. 키워드 중 하나. Property 키워드가 없습니다. 이것들은 모두 나쁜 코드를 유발합니다 (사람들이 Java를 사용할 수있을만큼 속성을 많이 사용하지만) - Bill K

31

최상위 수준 클래스는 기본적으로 정적입니다. 내부 클래스는 기본적으로 비 정적입니다. 내부 클래스의 기본값은 명시 적으로 정적으로 표시하여 변경할 수 있습니다. 참조 할 상위 클래스가 없기 때문에 최상위 레벨 클래스는 최상위 레벨이기 때문에 비 정적 인 의미를 가질 수 없습니다. 따라서 최상위 클래스의 기본값을 변경할 방법이 없습니다.


  • » 최상위 수준 클래스는 기본적으로 정적입니다. « 이것이 최고의 대답입니다. 그것들을 참조 할 수있는 어떤 것도 필요로하지 않기 때문에 정적입니다. 어디서든 참조 할 수 있습니다. 그들은정적 저장소(C 스토리지 클래스에서와 같이). - 다른 사람들이 지적했듯이 (이안 엘더 (Iain Elder)는 다른 대답에 대한 논평에서), 언어 설계자는static키워드는 정적 멤버 만 포함 할 수 있고 인스턴스화되지 않을 수 있음을 나타 내기 위해 최상위 클래스의 키워드입니다. 그러나 그것은 사람들을 다음과 같이 혼란스럽게 만들 수 있습니다.static중첩 클래스에는 다른 의미가 있습니다. - Lumi

29

개인 생성자가있는 클래스는 정적입니다.

다음과 같이 클래스를 선언하십시오.

public class eOAuth {

    private eOAuth(){}

    public final static int    ECodeOauthInvalidGrant = 0x1;
    public final static int    ECodeOauthUnknown       = 0x10;
    public static GetSomeStuff(){}

}

초기화없이 사용할 수 있습니다.

if (value == eOAuth.ECodeOauthInvalidGrant)
    eOAuth.GetSomeStuff();
...


  • 정적은 아니지만 정적 속성을 포함합니다. public final int를 쓰는 경우 ECodeOauthUnknown = 0x10; 더 이상 정적이 아닙니다. - user1883212
  • 누군가가 여기서 무슨 일이 일어나고 있는지 궁금해하는 경우, 이것은 "정적 클래스"의 C #정의와 일치합니다. -msdn.microsoft.com/en-us/library/79b3xss3%28v=vs.90%29.aspx. "정적 클래스"의 Java 정의를 감안할 때, 모든 비 내부 클래스는 정적이다 (형제 응답 참조). - Calum
  • @ user1883212를 제외하고는 개인 설득자가 중요하다고 여기는 독자에게이 대답이 혼란 스럽지만 전혀 문제가되지 않는다고 말하기까지합니다. - tlwhitec
  • .NET 세계에서 클래스가 추상 및 최종으로 표시되는 경우 (static classC #의 선언), 컴파일러는 코드가 해당 유형의 변수를 선언하거나 일반 유형 매개 변수로 사용하지 못하게합니다. 인스턴스화되거나 상속 될 수있는 클래스에서 액세스 가능한 생성자가 부족한 경우 해당 유형의 변수 선언이나 generic 형식 매개 변수의 사용을 배제하지 않습니다. - supercat
  • 이 대답은 완전히 잘못되었습니다. 사적 생성자는 그것과 아무 상관이 없다. 이 코드는 정적 속성과 메소드 만 갖는 클래스의 예일뿐입니다. 정적 클래스와는 아무런 관련이 없습니다. - user207421

12

물론 가능하지만안의중첩 된 클래스 여기서, 중첩 된 클래스의 인스턴스에는 외부 클래스의 둘러싼 인스턴스가 필요하지 않음을 의미합니다.

그러나 최상위 클래스의 경우 언어 디자이너는 키워드와 관련하여 유용하다고 생각할 수 없으므로 허용되지 않습니다.


  • 첫 번째 문구가 정확하지 않더라도 +1. JLS에서는 "내부 클래스는 명시 적으로 또는 암시 적으로 정적으로 선언되지 않은 중첩 클래스입니다." (그냥 용어, 나도 알아 ...) - Carlos Heuberger
  • 최상위 클래스를 선언 할 수는 없지만static, 때로는 할 수있는 것이 의미가 있습니다. 예를 들어, 정적 헬퍼 메소드 만 포함하는 클래스는 인스턴스화하는 데 의미가 없지만 Java 언어는 사용자를 중지시키지 않습니다. 기본 생성자를 선언하여 클래스를 다른 클래스에 인스턴스화 할 수 없도록 설정할 수 있습니다 (실제로 &static ').private생성자가 표시되지 않기 때문에 인스턴스화를 금지합니다. - Iain Samuel McLean Elder

12

인스턴스가없는 enum 유형을 선언하여 유틸리티 클래스 (인스턴스를 만들 수 없음)를 만들 수 있습니다. 즉 인스턴스가 없다는 것을 명시하고 있습니다.

public enum MyUtilities {;
   public static void myMethod();
}


  • 타입으로서의 열거 형은 특정한 기대치이다 : 이것은 열거 된 아이템 세트이다. "유틸리티 클래스"를 위해 그것을 사용하면, 그렇지 않으면 개인 생성자를 가진 클래스를 가질 수있을 때, 의미 론적으로 혼란 스럽습니다. - Visionary Software Solutions
  • @VisionarySoftwareSolutions 저에게이 특이성은 클래스의 인스턴스를 생성하는 것을 간접적으로 불가능하게하는 것이 아니라이 클래스의 인스턴스가 없다고 말합니다. - Peter Lawrey

8

public class Outer {
   public static class Inner {}
}

... 그것은 멤버 클래스 인 한 정적이라고 선언 될 수 있습니다.

JLS에서 :

멤버 클래스는 정적 일 수 있으며이 경우 주변 클래스의 인스턴스 변수에 액세스 할 수 없습니다. 또는 내부 클래스 (8.1.3) 일 수 있습니다.

그리고 여기:

static 키워드는 비 내부 클래스 T의 본문 내에서 멤버 유형 C의 선언을 수정할 수 있습니다.그 효과는 C가 내부 클래스가 아니라는 것을 선언하는 것입니다.T의 정적 메소드가 본문에 T의 현재 인스턴스를 갖고 있지 않은 것처럼 C도 T의 현재 인스턴스가 없으며 어휘를 둘러싸는 인스턴스도 없습니다.

정적 키워드는 최상위 레벨 클래스에 아무런 의미가 없습니다. 최상위 클래스에 둘러싸인 유형이 없기 때문입니다.



5

위에서 설명한 것처럼 클래스는 다른 클래스의 멤버가 아닌 한 정적 일 수 없습니다.

"여러 인스턴스가있을 수없는"클래스를 디자인하려는 경우 "싱글 톤"디자인 패턴을 조사해야 할 수 있습니다.

초심자 싱글 톤 정보이리.

경고:

당신이   싱글 톤 패턴, 모두와 저항   너의 힘. 가장 쉬운 방법 중 하나입니다.   이해해야 할 디자인 패턴   가장 인기 있고 확실히   가장 많이 학대받는(출처 : 위에 링크 된 JavaRanch)


4

Java가 정적 내부 클래스를 정의하는 방법 외에도 C #세계에 따라 정적 클래스에 대한 또 다른 정의가 있습니다[1]. 정적 클래스는 정적 메서드 (함수) 만 가지고 있으며 프로 시저 프로그래밍을 지원하기위한 클래스입니다. 이러한 클래스는 클래스의 사용자가 도우미 함수에만 관심이 있고 클래스의 인스턴스를 만드는 데 관심이없는 점에서 실제로 클래스는 아닙니다. C #에서는 정적 클래스가 지원되지만 Java에서는 그러한 직접적인 지원이 없습니다. 그러나 열거 형을 사용하여 C #정적 클래스를 Java로 모방 할 수 있으므로 사용자는 리플렉션을 사용하여도 지정된 클래스의 인스턴스를 만들 수 없습니다.[2]:

public enum StaticClass2 {
    // Empty enum trick to avoid instance creation
    ; // this semi-colon is important

    public static boolean isEmpty(final String s) {
        return s == null || s.isEmpty();
    }
}


2

정적 일 수있는 유일한 클래스는 내부 클래스입니다. 다음 코드는 잘 작동합니다.

public class whatever {
    static class innerclass {
    }
}

정적 내부 클래스의 핵심은 외부 클래스 객체에 대한 참조가 없다는 것입니다.


  • ' 정적 내부 ' 용어는 모순이다. ' 정적 ' ' 내부 ' 상호 배타적입니다. 찾으려는 단어는 ' 내부 '가 아닌   중첩 '입니다. - user207421

2

자바로 코딩 한 모든 것은 클래스로 들어갑니다. 클래스를 실행할 때마다 JVM은 객체를 인스턴스화합니다. JVM은 정의에 따라 여러 객체를 만들 수 있습니다. 정적이란 모든 객체에 대해 동일한 사본 세트를 가짐을 의미합니다.

따라서 Java가 프로그램을 실행할 때마다 최상위 클래스가 정적 인 것을 허용하면 Object를 만들고 동일한 메모리 위치에 우선 적용합니다.

당신이 그것을 실행할 때마다 당신이 그것을 실행할 때마다 단지 객체를 대체하고 있다면?

이것이 바로 Java가 최상위 클래스에 정적을 제거한 이유입니다.

더 구체적인 이유가있을 수도 있지만 이것이 나에게 많은 논리적 의미를 가졌습니다.


  • 내부 클래스는 외부 클래스와 연관되어 있으며 의존 할 다른 객체가 있기 때문에 정적 클래스가 될 수 있습니다. - user2626445
  • 그들이 할 수있는 이유는아니정적 일 것. - user207421

1

나는 이것이 커피 한 잔 마시는 것만 큼 쉽다라고 생각한다. 이걸 한번보세요. 클래스를 정의 할 때 static 키워드를 명시 적으로 사용하지 않습니다.

public class StaticClass {

    static private int me = 3;
    public static void printHelloWorld() {
       System.out.println("Hello World");
    }



    public static void main(String[] args) {
        StaticClass.printHelloWorld();
        System.out.println(StaticClass.me);
    }
}

정적 클래스의 정의가 아닌가? 방금 클래스에 바인드 된 함수를 사용합니다. 이 경우에는 중첩 된 클래스에 다른 클래스를 사용할 수 있습니다. 이것 좀봐:

class StaticClass1 {

    public static int yum = 4;

    static void  printHowAreYou() {
        System.out.println("How are you?");
    }
}

public class StaticClass {

    static int me = 3; 
    public static void printHelloWorld() {
       System.out.println("Hello World");
       StaticClass1.printHowAreYou();
       System.out.println(StaticClass1.yum);
    }



    public static void main(String[] args) {
        StaticClass.printHelloWorld();
        System.out.println(StaticClass.me);
    }
}


  • 정적 키워드를 한정자로 사용하는 것이 아니라 정적 클래스 정의를 참조하여 정적 클래스와 같은 클래스를 고려할 수 있다고 생각합니다. - Erfankam
  • 개인 생성자를 만들어야합니다. 그렇지 않으면 말할 수 있습니다.new StaticClass()정말로 많은 의미를 지니지는 않습니다. 개인 생성자를 사용하면 인스턴스가 허용되지 않습니다. - grinch

1

사람이 볼 수있다.PlatformUI이클립스에서는 정적 메서드를 사용하는 클래스와 자체적으로 최종 생성자 인 private 생성자를 사용합니다.

public final class <class name>
{
   //static constants
   //static memebers
}


0

정적 클래스를 사용하는 이점이 객체를 인스턴스화하지 않고 메소드를 사용하지 않는다면 클래스를 public으로 선언하고이 메소드를 정적으로 선언하십시오.

연결된 질문


관련된 질문

최근 질문