[java] Java의 마커 인터페이스?

Java의 Marker 인터페이스는 빈 인터페이스 이며이 인터페이스를 구현하는 클래스의 객체가 직렬화, 복제 등과 같은 특별한 방식으로 처리되어야한다는 것을 컴파일러 또는 JVM에 신호하는 데 사용됩니다.

그러나 최근에는 실제로 컴파일러 또는 JVM과 관련이 없다는 것을 알게되었습니다. 예를 들어, 경우에 Serializable계면에있어서 writeObject(Object)ObjectOutputStream같은 것을 수행 instanceOf Serializable클래스 구현하는지 여부를 검출 Serializable및 드로우 NotSerializableException따라서. 모든 것이 코드에서 처리되며 이것은 디자인 패턴 인 것처럼 보이므로 자체 마커 인터페이스를 정의 할 수 있다고 생각합니다.

이제 내 의심 :

  1. 위에서 언급 한 마커 인터페이스의 정의가 1 점에서 잘못 되었습니까? 그러면 마커 인터페이스를 어떻게 정의 할 수 있습니까?

  2. 그리고 instanceOf연산자 를 사용하는 대신 writeObject(Serializable)런타임이 아닌 컴파일 타임 유형 검사가되도록 메소드를 사용할 수없는 이유는 무엇 입니까?

  3. 주석이 마커 인터페이스보다 나은 점은 무엇입니까?



답변

  1. 위에서 언급 한 마커 인터페이스의 정의가 첫 번째 점에서 잘못 되었습니까? -부분적으로는 (1) 마커 인터페이스가 비어 있어야하며 (2) 구현은 구현 클래스의 특별한 처리를 의미합니다. 잘못된 부분은 JVM 또는 컴파일러가 해당 클래스의 객체를 다르게 처리한다는 것을 암시한다는 것입니다. 이러한 객체를 복제 가능, 직렬화 가능 등으로 처리하는 Java 클래스 라이브러리의 코드인지 확인하는 것이 옳습니다. 컴파일러 또는 JVM과 관련이 없습니다.
  2. instanceOf 연산자를 사용하는 대신 writeObject(Serializable)컴파일 타임 유형 검사가 수행되도록 메서드를 사용할 수없는 이유는 무엇입니까 ? 이렇게하면 “일반 Object“이 필요할 때 마커 인터페이스의 이름으로 코드가 오염되는 것을 피할 수 있습니다 . 예를 들어, 직렬화 가능하고 객체 멤버가있는 클래스를 만드는 경우 Serializable컴파일 타임에 객체 를 캐스팅하거나 만들어야합니다 . 인터페이스에 기능이 없기 때문에 불편합니다.
  3. 주석이 마커 인터페이스보다 나은 점은 무엇입니까? -별도의 유형을 만들지 않고도 클래스에 대한 메타 데이터를 소비자에게 전달하는 것과 동일한 목적을 달성 할 수 있습니다. 주석도 더욱 강력하여 프로그래머가보다 복잡한 정보를 “소비하는”클래스에 전달할 수 있습니다.

답변

적용 할 수 없습니다 SerializablewriteObject직렬화 가능하지 않은 클래스의 아이들이 직렬화 될 수 있기 때문에, 그러나 그들의 인스턴스는 부모 클래스에 upcasted 다시 할 수있다. 결과적으로 직렬화 가능 Object하지 않은 무언가에 대한 참조를 보유 한다고해서 참조 된 인스턴스를 실제로 직렬화 할 수는 없습니다. 예를 들어

   Object x = "abc";
   if (x instanceof Serializable) {
   }

부모 클래스 ( Object)는 직렬화 할 수 없으며 매개 변수가없는 생성자를 사용하여 초기화됩니다. 참조하는 값은 x, String직렬화하고 조건문이 실행됩니다.


답변

Java의 마커 인터페이스는 필드 나 메소드가없는 인터페이스입니다. 간단히 말해서 Java의 빈 인터페이스를 마커 인터페이스라고합니다. (marker) 인터페이스의 예는이다 Serializable, CloneableRemote인터페이스한다. 이들은 정보를 컴파일러 또는 JVM에 표시하는 데 사용됩니다. 따라서 JVM이 클래스가 Serializable인 것을 발견하면 특별한 작업을 수행 할 수 있습니다. 마찬가지로 JVM에서 일부 클래스가 구현중인 것으로 확인되면 Cloneable복제를 지원하기 위해 일부 작업을 수행 할 수 있습니다. RMI와 Remote인터페이스도 마찬가지입니다 . 간단히 말해서 마커 인터페이스는 컴파일러 또는 JVM에 대한 신호 또는 명령을 나타냅니다.

위의 내용 은 블로그 게시물 의 복사본으로 시작 되었지만 문법에 맞게 약간 수정되었습니다.


답변

의심의 여지없이 1과 2를 해결하기 위해 간단한 데모를 만들었습니다.

우리는 움직일 수에 의해 구현 될 것이다 인터페이스를 낳게 될 것이다 MobilePhone.java클래스 하나 개 더 클래스 LandlinePhone.java않습니다 하지 움직일 수있는 인터페이스를 구현을

마커 인터페이스 :

package com;

public interface Movable {

}

LandLinePhone.javaMobilePhone.java

 package com;

 class LandLinePhone {
    // more code here
 }
 class MobilePhone implements Movable {
    // more code here
 }

우리의 사용자 정의 예외 클래스 : package com;

public class NotMovableException extends Exception {

private static final long serialVersionUID = 1L;

    @Override
    public String getMessage() {
        return "this object is not movable";
    }
    // more code here
    }

우리의 테스트 클래스 : TestMArkerInterface.java

package com;

public class TestMarkerInterface {

public static void main(String[] args) throws NotMovableException {
    MobilePhone mobilePhone = new MobilePhone();
    LandLinePhone landLinePhone = new LandLinePhone();

    TestMarkerInterface.goTravel(mobilePhone);
    TestMarkerInterface.goTravel(landLinePhone);
}

public static void goTravel(Object o) throws NotMovableException {
    if (!(o instanceof Movable)) {
        System.out.println("you cannot use :" + o.getClass().getName() + "   while travelling");
        throw new NotMovableException();
    }

    System.out.println("you can use :" + o.getClass().getName() + "   while travelling");
}}

이제 메인 클래스를 실행할 때 :

you can use :com.MobilePhone while travelling
you cannot use :com.LandLinePhone while travelling
Exception in thread "main" com.NotMovableException: this object is not movable
    at com.TestMarkerInterface.goTravel(TestMarkerInterface.java:22)
    at com.TestMarkerInterface.main(TestMarkerInterface.java:14)

따라서 마커 인터페이스 Movable를 구현하는 클래스 는 테스트를 통과하지 않으면 오류 메시지가 표시됩니다.

이것은 Serializable , Cloneable 등에서 instanceOf운영자 확인이 수행 되는 방식입니다.


답변

a / 이름에서 알 수있는 마커 인터페이스 는 클래스가 무언가를 선언 한다는 사실을 아는 것만 알려 줍니다. Serializable인터페이스 의 JDK 클래스 이거나 사용자 정의 클래스를 작성하는 클래스 일 수 있습니다.

b / 만약 그것이 마커 인터페이스라면, 그것은 어떤 메소드의 존재를 암시해서는 안됩니다-인터페이스에 묵시적인 메소드를 포함시키는 것이 좋습니다. 당신이 알고있는 경우에 당신이 원하는 그러나 당신은 그것을 설계하는 결정할 수 있습니다 당신이 그것을 필요

c / 빈 인터페이스와 값이나 매개 변수를 사용하지 않는 주석에는 차이가 거의 없습니다. 그러나 차이점이 있습니다. 주석은 런타임에 액세스 할 수있는 키 / 값 목록을 선언 할 수 있습니다.


답변

ㅏ. 나는 항상 그것들을 디자인 패턴으로 보았고 몇 가지 상황에서 그 패턴을 사용한 JVM 스페셜은 없습니다.

씨. 나는 주석을 사용하여 무언가를 표시하는 것이 마커 인터페이스를 사용하는 것보다 더 나은 해결책이라는 것을 믿습니다. 단순히 인터페이스가 타입 / 클래스의 공통 인터페이스를 정의하는 것을 목표로하기 때문입니다. 그들은 계급 계층의 일부입니다.

주석은 코드에 메타 정보를 제공하기위한 것이며 마커는 메타 정보라고 생각합니다. 따라서 그것들은 정확히 그 유스 케이스를위한 것입니다.


답변

  1. JVM 및 컴파일러와 (필수적으로) 아무 관련이 없으며 주어진 마커 인터페이스에 관심이 있고 테스트하는 코드와 관련이 있습니다.

  2. 그것은 디자인 결정이며 정당한 이유가 있습니다. Audrius Meškauskas의 답변을 참조하십시오.

  3. 이 특정 주제와 관련하여, 나는 그것이 더 나빠질 문제라고 생각하지 않습니다. 마커 인터페이스는 제대로 된 일을하고 있습니다.