자바의 정적 클래스


947

static class자바 와 같은 것이 있습니까?

그러한 클래스의 의미는 무엇입니까? 정적 클래스의 모든 메소드 static도 필요 합니까?

다른 방법으로 클래스에 모든 정적 메소드가 포함되어 있으면 클래스도 정적이어야합니까?

정적 클래스는 무엇입니까?


4
당신은에 관심이있을 것이다 stackoverflow.com/questions/3584113/java-static-class
Ishtar

정적 클래스는 기본적으로 클래스를 그룹화하는 데 사용됩니다.
RockingDev

답변:


847

Java에는 정적 중첩 클래스가 있지만 최상위 정적 클래스를 찾고있는 것처럼 들립니다. Java는 최상위 클래스를 정적으로 만드는 방법이 없지만 다음과 같이 정적 클래스를 시뮬레이션 할 수 있습니다.

  • 클래스 선언 final-정적 클래스 확장이 의미가 없으므로 클래스 확장을 방지합니다.
  • 생성자 만들기 private-정적 클래스를 인스턴스화하는 것이 의미가 없으므로 클라이언트 코드로 인스턴스화를 방지합니다.
  • 클래스의 모든 멤버와 함수 만들기 static-클래스를 인스턴스화 할 수 없으므로 인스턴스 메소드를 호출하거나 인스턴스 필드에 액세스 할 수 없습니다.
  • 컴파일러는 인스턴스 (비 정적) 멤버를 선언하지 못하게합니다. 인스턴스 멤버를 호출하려고 할 때만 문제가 나타납니다.

위의 제안 당 간단한 예 :

public class TestMyStaticClass {
     public static void main(String []args){
        MyStaticClass.setMyStaticMember(5);
        System.out.println("Static value: " + MyStaticClass.getMyStaticMember());
        System.out.println("Value squared: " + MyStaticClass.squareMyStaticMember());
        // MyStaticClass x = new MyStaticClass(); // results in compile time error
     }
}

// A top-level Java class mimicking static class behavior
public final class MyStaticClass {
    private MyStaticClass () { // private constructor
        myStaticMember = 1;
    }
    private static int myStaticMember;
    public static void setMyStaticMember(int val) {
        myStaticMember = val;
    }
    public static int getMyStaticMember() {
        return myStaticMember;
    }
    public static int squareMyStaticMember() {
        return myStaticMember * myStaticMember;
    }
}

정적 클래스는 무엇입니까? 정적 클래스를 잘 사용하면 인스턴스화가 적합하지 않은 일회성, 유틸리티 및 / 또는 라이브러리 클래스를 정의 할 수 있습니다. PI 및 E와 같은 수학적 상수를 포함하고 단순히 수학적 계산을 제공하는 Math 클래스가 좋은 예입니다. 이러한 경우 인스턴스화를 요구하는 것은 불필요하고 혼란 스러울 것입니다. Math클래스 및 소스 코드를 참조하십시오 . 그것 final과 그것의 모든 구성원이 임을 주목하십시오 static. Java가 최상위 클래스를 선언 할 수 있으면 staticMath 클래스는 정적 일 수 있습니다.


35
메소드 Foo만 있는 클래스 static는 다음과 동일하지 않습니다.static class Foo
craigb

12
@Evorlor : 클래스가 final로 선언되면 해당 메소드는 자동으로 (효과적으로) final입니다. 이는 최종 클래스를 서브 클래 싱 할 수 없으므로 해당 메소드를 재정의 할 수 없기 때문입니다 (즉, 실제로 최종 클래스 임). docs.oracle.com/javase/tutorial/java/IandI/final.html
jwayne

30
이 답변은 OP가 의미하는 바를 해결할 수 있지만 (현재) Java 정적 클래스를 설명하지 않으므로 질문에 전혀 대답하지 않습니다! 이것은 자바에서 정적 클래스가 무엇을 의미하는지 알아 내려고 노력하는 사람들에게는 매우 나쁩니다.
Tom

12
@ JBoy : Java에는 "정적 클래스"와 같은 것이 있습니다.이 질문에 관한 것이지만이 대답은 전혀 설명하지 않습니다. 대신 자바에서 응답이 "정적 클래스"라고 부르는 방법을 설명하지만 Java의 "정적 클래스"가 아닙니다 ! (어쩌면 다른 언어에서는 "정적 클래스"라고 할 수 있지만 Java 정적 클래스에 대해 배우기 위해 여기에 오는 사람들은 혼란스럽고 혼란 스러울 것입니다.)
Tom

4
private MyStaticClass () {// private constructor myStaticMember = 1; } 생성자가 호출되지 않기 때문에 전혀 영향을 미치지 않습니다. 그러나 이것은 요점이 아닙니다. Java의 정적 내부 클래스 유틸리티와 유틸리티 또는 부가 가치에 대해 여전히 혼란 스럽습니다.
moldovean

315

Java에는 "정적 중첩 클래스"가 있지만 C #의 정적 클래스와 동일하지는 않습니다. 정적 중첩 클래스는 암시 적으로 외부 클래스의 인스턴스에 대한 참조가없는 클래스입니다.

정적 중첩 클래스는 인스턴스 메소드와 정적 메소드를 가질 수 있습니다.

Java에는 최상위 정적 클래스와 같은 것이 없습니다.


12
Java에서 정적 중첩 클래스가 인스턴스 메소드를 허용하는 이유는 무엇입니까? 그러한 클래스에서 인스턴스 메소드를 사용하는 것은 무엇입니까?
Geek

19
@ eek : 내 대답을 읽었습니까? 두 번째 문장을주의 깊게 읽으십시오. 정적 클래스의 인스턴스 메소드를 가질 수 없는 이유는 무엇 입니까? 결국 인스턴스를 만들 수 있습니다.
Jon Skeet

17
@ eek : 예, 전적으로 허용됩니다. 정적 클래스가 유틸리티 클래스라는 "의해"는 기본적으로 올바르지 않습니다. 그것은 자바의 정적 클래스가 전혀 의미하는 것이 아닙니다.
Jon Skeet

14
@ eek : 예. 정답은 다음과 같습니다. "정적 중첩 클래스는 암시 적으로 외부 클래스의 인스턴스에 대한 참조가없는 클래스입니다."
Jon Skeet 14

6
@KhurramAli : 당신은 암시 적으로 의미 합니까? 키워드 를 선언 할 때 키워드를 사용하지 않으면 명시 적으로 정적이지 않습니다 static. 그것들을 구성하기 위해 다른 것에 대한 참조가 필요하지 않다는 점에서 암시 적으로 정적입니다. 개인적으로 정적 / 비 정적 용어가 중첩 클래스에 약간 이상하다는 것을 알았습니다 ... 행동이 무엇인지 이야기하는 것이 더 간단하다고 생각합니다.
Jon Skeet

157

정적 중첩 클래스가 있으며,이 [정적 중첩] 클래스는 인스턴스화되기 위해 둘러싸는 클래스의 인스턴스가 필요하지 않습니다.

이 클래스 [정적 중첩 클래스]는 포함 클래스의 정적 멤버에만 액세스 할 수 있습니다 (클로징 클래스의 인스턴스에 대한 참조가 없기 때문에 ...]

코드 샘플 :

public class Test { 
  class A { } 
  static class B { }
  public static void main(String[] args) { 
    /*will fail - compilation error, you need an instance of Test to instantiate A*/
    A a = new A(); 
    /*will compile successfully, not instance of Test is needed to instantiate B */
    B b = new B(); 
  }
}

1
그렇다면 내부 정적 클래스를 사용하여 공개 할 필요없이 인스턴스화 할 수 있다고 말할 수 있습니까?
moldovean

@moldovean 정적 컨텍스트 (예 : main) 에서 인스턴스화하기 위해 내부 정적 클래스를 사용합니다 . 나는 그것이 가시성과 관련이 없다고 생각합니다.
Michael Dorst

2
@moldovean 정적 / 비 정적은 가시성과 직교합니다. 정적 또는 비 정적으로 가시성을 가질 수 있습니다. 요점은 내부 클래스를 만들려면 엔 클로징 클래스의 인스턴스가 필요합니까?
amit

103

예, Java에는 정적 중첩 클래스가 있습니다. 중첩 클래스 정적을 선언하면 해당 클래스가 속한 외부 클래스를 인스턴스화하지 않고 인스턴스화 할 수있는 독립형 클래스가 자동으로됩니다.

예:

public class A
{

 public static class B
 {
 }
}

class Bstatic으로 선언 되었으므로 다음과 같이 명시 적으로 인스턴스화 할 수 있습니다.

B b = new B();

class B독립형으로 만들기 위해 정적으로 선언되지 않은 경우 인스턴스 객체 호출은 다음과 같습니다.

A a= new A();
B b = a.new B();

7
정적 클래스를 B b = new B();클래스 A자체 에서 인스턴스화하려는 경우 와 같이 비 정적 클래스를 정기적으로 인스턴스화 할 수 있습니다 .
Muhammed Refaat

33

내부 구성원 classstatic.. 로 선언되면 어떻게 되나요? 해당 멤버는을 인스턴스화하지 않고 액세스 할 수 있습니다 class. 따라서 외부 클래스 (최상위 클래스)를 만드는 것은 static의미가 없습니다. 따라서 허용되지 않습니다.

그러나 내부 클래스를 정적으로 설정할 수 있습니다 (최상위 클래스의 멤버이므로). 그러면 최상위 클래스를 인스턴스화하지 않고도 해당 클래스에 액세스 할 수 있습니다. 다음 예를 고려하십시오.

public class A {
    public static class B {

    }
}

이제 다른 클래스 안에서 class 인스턴스를 만들지 않고도 C클래스에 B액세스 할 수 있습니다 A.

public class C {
    A.B ab = new A.B();
}

static수업도 non-static회원이 될 수 있습니다 . 클래스 만 정적 상태가됩니다.

그러나 static 키워드가 클래스 B에서 제거 되면 인스턴스를 만들지 않고 직접 액세스 할 수 없습니다 A.

public class C {
    A a = new A();
    A.B ab = a. new B();
}

그러나 우리는 내부 수업에 static회원을 가질 수 없습니다 non-static.


정적 클래스를 인스턴스화 할 수 있습니까?
Supun Wijerathne 2016 년

6
다른 언어와 달리 staticJava에서는 하나의 의미 만 있습니다. static클래스에 무언가가 있으면 해당 클래스를 인스턴스화하지 않고 액세스 할 수 있습니다. 인스턴스 생성에 대해서는 아무 말도하지 않습니다.
Ramesh-X

죄송합니다. 이 경우에는 감사합니다 Ramesh-X라는 말을 피할 수 없습니다! 정적 내부 클래스와 내부 클래스에 대해 궁금했던 거의 모든 것을 다루었습니다.
moldovean

내부 클래스를 정적으로 설정할 수 없습니다. 이것은 용어모순입니다 . 중첩 클래스는 내부 또는 정적입니다.
user207421

13

이것이 "정적 클래스 java"에 대한 Google의 최고 결과이며 최고의 답변이 여기에 없다는 것을 알았습니다. OP의 질문을 C #의 정적 클래스와 관련하여 Java 세계에서 싱글 톤이라고하는 것으로 해석하고 있습니다. C #에서 "정적"키워드를 클래스 선언에 적용하면 결과 클래스를 인스턴스화 할 수 없습니다.

Joshua Bloch의 "Effective Java-Second Edition"에서 발췌 (일반적으로 사용 가능한 최고의 Java 스타일 안내서 중 하나로 간주 됨) :

릴리스 1.5부터 싱글 톤을 구현하는 세 번째 방법이 있습니다. 단순히 하나의 요소로 열거 형을 만드십시오.

// Enum singleton - the preferred approach
public enum Elvis {
    INSTANCE;
    public void leaveTheBuilding() { ... }
}

이 접근법은보다 간결하고 직렬화 기계를 무료로 제공하며 정교한 직렬화 또는 리플렉션 공격에도 불구하고 다중 인스턴스화에 대한 확실한 보증을 제공한다는 점을 제외하고는 공공 현장 접근 방식과 기능적으로 동일합니다. 이 방법은 아직 널리 채택되지 않았지만 단일 요소 열거 형 유형이 싱글 톤을 구현하는 가장 좋은 방법입니다. (강조 저자)

조슈아 블로흐 (2008-05-08). 효과적인 Java (Java Series) (p. 18). 피어슨 교육.

나는 구현과 정당화가 매우 자명하다고 생각합니다.


6
싱글 톤을 구현하는 좋은 방법입니다. 불행히도, 질문은 싱글 톤에 관한 것이 아니라 정적 클래스에 관한 것입니다
David SN

1
Java는 "정적"키워드에 대해 다소 고유 한 해석을합니다. "정적 클래스"가 Java의 싱글 톤에 해당하는 C #에서 OP가 나오는 것 같습니다. 질문에 대한이 해석을 명확하게하기 위해 답변을 업데이트했습니다.
Bennet Huber

1
AC # 정적 클래스는 싱글 톤이 아닙니다. Singleton 인스턴스는 객체이며 인터페이스를 구현할 수 있으므로 종속성 주입에 참여하고 조롱 할 수 있습니다. AC # 정적 클래스는 인터페이스를 구현하거나 어떤 식 으로든 삽입 할 수 없으며 C 함수에 훨씬 가깝고 확장 메서드도 허용합니다.
Novaterata 2016 년

13

Java에서 클래스가 정적 일 수 있습니까?

대답은 YES 입니다. java에서 정적 클래스를 가질 수 있습니다. 자바에는 정적 인스턴스 변수정적 메소드정적 블록이 있습니다. 있습니다. Java에서 클래스를 정적으로 만들 수도 있습니다.

자바에서는 최상위 (외부) 클래스를 정적으로 만들 수 없습니다. 중첩 클래스 만 정적 일 수 있습니다.

정적 중첩 클래스 대 비 정적 중첩 클래스

1) 중첩 정적 클래스에는 외부 클래스에 대한 참조가 필요하지 않지만 비 정적 중첩 클래스 또는 내부 클래스에는 외부 클래스 참조가 필요합니다.

2) 내부 클래스 (또는 비 정적 중첩 클래스)는 외부 클래스의 정적 및 비 정적 멤버 모두에 액세스 할 수 있습니다. 정적 클래스는 Outer 클래스의 비 정적 멤버에 액세스 할 수 없습니다. 외부 클래스의 정적 멤버에만 액세스 할 수 있습니다.

여기를 참조하십시오 : https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html


또한 내측 "비 정적 '클래스는 정적 필드 나 메소드를 선언 할 수
Mr.Cat


2

간단히 말해서, Java는 클래스 선언을 내부 클래스에 대해서만 정적이지만 최상위 클래스에 대해서는 정적이 아닌 것으로 선언합니다.

최상위 클래스 : Java 프로젝트는 각 Java 소스 파일에 둘 이상의 최상위 클래스를 포함 할 수 있으며 클래스 중 하나는 파일 이름을 따라 이름이 지정됩니다. 최상위 클래스 앞에는 public, abstract 및 final의 세 가지 옵션 또는 키워드 만 허용됩니다.

내부 클래스 : 최상위 클래스 내부에있는 클래스를 내부 클래스라고하며 기본적으로 중첩 클래스의 개념입니다. 내부 클래스는 정적 일 수 있습니다 . 내부 클래스를 정적으로 만드는 아이디어는 최상위 클래스의 개체를 인스턴스화하지 않고 내부 클래스의 개체를 인스턴스화하는 이점을 이용하는 것입니다. 이것은 정적 메소드 및 변수가 최상위 클래스 내에서 작동하는 것과 정확히 같은 방식입니다.

따라서 Java는 내부 클래스 수준 (중첩 클래스)에서 정적 클래스를 지원합니다.

그리고 Java는 최상위 클래스에서 정적 클래스를 지원하지 않습니다.

이것이 Java의 정적 클래스에 대한 기본적인 이해에 대한 질문에 대한 더 간단한 해결책을 제공하기를 바랍니다.



0

Java에는 클래스와 연관된 정적 메소드가 있습니다 (예 : java.lang.Math에는 정적 메소드 만 있음). 클래스 자체는 정적이 아닙니다.


0

정적 키워드는 내부 클래스가 아닌 한 클래스와 함께 사용할 수 없습니다. 정적 내부 클래스는 외부 클래스의 정적 멤버 인 중첩 클래스입니다. 다른 정적 멤버를 사용하여 외부 클래스를 인스턴스화하지 않고 액세스 할 수 있습니다. 정적 멤버와 마찬가지로 정적 중첩 클래스는 외부 클래스의 인스턴스 변수 및 메서드에 액세스 할 수 없습니다.

public class Outer {
   static class Nested_Demo {
      public void my_method() {
          System.out.println("This is my nested class");
      }
   }
public static void main(String args[]) {
      Outer.Nested_Demo nested = new Outer.Nested_Demo();
      nested.my_method();
   }
}

중첩 클래스 static가 아닌 경우 클래스와 함께 키워드를 사용할 수 없습니다 . '정적 내부'는 용어의 모순입니다 .
user207421

0

정적 메소드는 public과 달리 클래스의 오브젝트를 작성하지 않고 액세스 할 수 있음을 의미합니다.

public class MyClass {
   // Static method
   static void myStaticMethod() {
      System.out.println("Static methods can be called without creating objects");
   }

  // Public method
  public void myPublicMethod() {
      System.out.println("Public methods must be called by creating objects");
   }

  // Main method
  public static void main(String[ ] args) {
      myStaticMethod(); // Call the static method
    // myPublicMethod(); This would output an error

    MyClass myObj = new MyClass(); // Create an object of MyClass
    myObj.myPublicMethod(); // Call the public method
  }
}

질문에 대답하지 않습니다.
user207421

-1

모든 좋은 대답이지만 정적 요소 메소드에 정적 내부 클래스 톤을 사용하는 java.util.Collections에 대한 참조를 보지 못했습니다. 그래서 같은 것을 추가합니다.

정적 내부 클래스가 여러 개인 java.util.Collections에서 예제 추가 내부 클래스는 외부 클래스를 통해 액세스해야하는 코드를 그룹화하는 데 유용합니다.

/**
 * @serial include
 */
static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
                             implements Set<E>, Serializable {
    private static final long serialVersionUID = -9215047833775013803L;

    UnmodifiableSet(Set<? extends E> s)     {super(s);}
    public boolean equals(Object o) {return o == this || c.equals(o);}
    public int hashCode()           {return c.hashCode();}
}

다음은 java.util.Collections 클래스의 정적 요소 메소드입니다.

public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
    return new UnmodifiableSet<>(s);
}


귀하의 의견이 없습니까? 정교하게 할 수 있습니까? 귀하의 의견을 이해하려고합니다.
Jay Rajput
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.