Java의 마커 인터페이스?
Java의 Marker 인터페이스는 빈 인터페이스이며 컴파일러나 JVM에 이 인터페이스를 구현하는 클래스의 오브젝트를 시리얼화, 클로닝 등 특별한 방법으로 처리해야 한다는 신호를 보내는 데 사용된다는 것을 배웠습니다.
하지만 최근 컴파일러나 JVM과는 전혀 관계가 없다는 것을 알게 되었습니다.를 들어, 「」의 는,Serializable
를 writeObject(Object)
ObjectOutputStream
짓을 instanceOf Serializable
이 실행하는지 를 Serializable
NotSerializableException
모든 은 것 같기 때문에 인터페이스를 할 수 합니다.모든 것은 코드로 처리되며 이것은 디자인 패턴인 것 같기 때문에 독자적인 마커 인터페이스를 정의할 수 있다고 생각합니다.
이제 내 의심은
위의 첫 번째 포인트에서 언급된 마커 인터페이스의 정의가 잘못되었습니까?그러면 Marker 인터페이스를 정의하려면 어떻게 해야 합니까?
,, 그, 신, 신, 신, 신, and, and, 하지 않고
instanceOf
는 왜 그이 '아까운가'와 같은 이 될 수 없죠writeObject(Serializable)
런타임 대신 컴파일 타임 타입 체크가 이루어지도록 할 수 있습니까?주석 기능이 마커 인터페이스보다 나은 이유는 무엇입니까?
- 위의 첫 번째 포인트에서 언급된 마커 인터페이스의 정의가 잘못되었습니까? - (1) 마커 인터페이스가 비어 있어야 하는 부분과 (2) 구현 클래스의 특별한 취급을 암시하는 부분에서는 정확합니다.잘못된 부분은 JVM이나 컴파일러가 해당 클래스의 오브젝트를 다르게 취급한다는 것을 암시한다는 것입니다.이 오브젝트를 클론 가능, 시리얼 가능 등으로 취급하는 것은 Java 클래스 라이브러리의 코드입니다.컴파일러나 JVM과는 관계가 없습니다.
- instanceOf 연산자를 사용하는 대신 메서드는 컴파일 시간 유형 검사를 수행할 수 없습니다. 이렇게 하면 "일반"일 때 마커 인터페이스의 이름으로 코드가 오염되는 것을 방지할 수 있습니다.
Object
필요해요.' 라고 하다.를 들어,가능해야 를 만들고 있는 , 를 캐스팅하거나 됩니다.Serializable
합니다.인터페이스에는 기능이 없기 때문에 이것은 불편합니다. - 주석이 마커 인터페이스보다 나은 이유는 무엇입니까? - 주석을 사용하면 클래스에 대한 메타데이터를 별도의 유형을 만들지 않고도 소비자에게 전달하는 동일한 목적을 달성할 수 있습니다.주석도 더 강력하기 때문에 프로그래머가 더 정교한 정보를 "소비"하는 클래스에 전달할 수 있습니다.
할 수 .Serializable
writeObject
왜냐하면 컴포넌트할 수 없는 클래스의 자녀는 시리얼화할 수 있지만 인스턴스는 부모 클래스로 업캐스트될 수 있기 때문입니다.할 수 없는 것(예: 「」, 「」등)에 대한 를 보관 하는 것.Object
할 수 는 참조된 인스턴스를 실제로 시리얼화할 수 없는 것을 의미하지 않습니다.를 들면, 「」의 경우,
Object x = "abc";
if (x instanceof Serializable) {
}
클래스Object
할 수 가 없는 는 시리얼화할 수 없으며 파라미터가 없는 컨스트럭터를 사용하여 초기화됩니다.에 의해 되는 값x
,String
는 시리얼 가능하며 조건부 문이 실행됩니다.
1번과 2번 의혹을 해결하기 위해 간단한 데모를 했습니다.
Movable 인터페이스는 다음과 같이 구현될 것입니다.MobilePhone.java
1 class 。LandlinePhone.java
모바일 인터페이스를 구현하지 않음
마커 인터페이스:
package com;
public interface Movable {
}
LandLinePhone.java
★★★★★★★★★★★★★★★★★」MobilePhone.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
에러 메세지가 표시됩니다.
하면 .instanceOf
오퍼레이터 체크는 시리얼화 가능, 클론화 가능 등
Java의 마커 인터페이스는 필드나 메서드가 없는 인터페이스입니다.간단히 말하면 Java에서 빈 인터페이스를 마커 인터페이스라고 합니다.로는 '마커 인터페이스'가 .
Serializable
,Cloneable
★★★★★★★★★★★★★★★★★」Remote
인터페이스입니다. 또는에 대한 가 "JVM"이라고. 【JVM】Serializable
에 대해 을 할 수중에 있습니다. 있는 것을 .Cloneable
복제를 지원하기 위한 몇 가지 작업을 수행할 수 있습니다.와 RMI의 RMI도 입니다.Remote
인터페이스입니다. 또는 .
위의 내용은 블로그 투고 사본으로 시작되었지만 문법에 맞게 가볍게 편집되었습니다.
a/ 이름 그대로 마커 인터페이스는 클래스가 무언가를 선언한다는 것을 아는 모든 사용자에게 알리기 위해 존재합니다.모든 것이 JDK 클래스가 될 수 있습니다.Serializable
인터페이스 또는 커스텀 클래스용으로 작성한 클래스입니다.
b/ 마커 인터페이스인 경우, 어떤 메서드도 존재하지 않습니다.인터페이스에 암묵적인 메서드를 포함하는 것이 좋습니다.단, 필요한 이유를 알면 원하는 대로 설계할 수 있습니다.
c/ 빈 인터페이스와 값이나 파라미터를 사용하지 않는 주석의 차이는 거의 없습니다.그러나 다른 점은 주석으로 런타임에 액세스할 수 있는 키/값 목록을 선언할 수 있다는 점입니다.
JVM 및 컴파일러와는 (필요한) 관계가 없으며, 지정된 마커 인터페이스에 대해 관심이 있고 테스트 중인 코드와 관련이 있습니다.
이것은 설계상의 결정이며, 충분한 이유가 있습니다.Audrius Meshkauskas의 답변을 참조하십시오.
이 특정한 주제에 관해서, 나는 그것이 더 낫고 더 나쁜 것의 문제라고 생각하지 않는다.마커 인터페이스는 정상적으로 동작하고 있습니다.
a. 항상 디자인 패턴으로 봐왔으며 JVM-Special에서는 몇 가지 상황에서 그 패턴을 사용한 적이 없습니다.
c. 표식 인터페이스를 사용하는 것보다 주석을 사용하여 무언가를 표시하는 것이 더 나은 해결책이라고 생각합니다.단순히 인터페이스가 처음에 유형/클래스의 공통 인터페이스를 정의하는 것을 목적으로 하고 있기 때문입니다.그들은 계급 계급의 일부이다.
주석은 메타 정보를 코드에 제공하는 것을 목적으로 하고 있으며, 저는 이 마커가 메타 정보라고 생각합니다.즉, 그 사용 사례에 딱 들어맞는 것입니다.
마커 인터페이스의 주된 목적은 유형 자체가 독자적인 동작을 가지지 않는 특수한 유형을 작성하는 것입니다.
public interface MarkerEntity {
}
public boolean save(Object object) throws InvalidEntityFoundException {
if(!(object instanceof MarkerEntity)) {
throw new InvalidEntityFoundException("Invalid Entity Found, can't be saved);
}
return db.save(object);
}
여기서 저장 메서드는 MarkerEntity 인터페이스를 구현하는 클래스의 객체만 다른 유형의 InvalidEntity에 대해 저장됩니다.Found Exception이 느려집니다.여기서 MarkerEntity 마커인터페이스는 이를 구현하는 클래스에 특별한 동작을 추가하는 유형을 정의합니다.
지금은 일부 특수 처리의 클래스를 표시하기 위해 주석을 사용할 수도 있지만 마커 주석은 마커 인터페이스가 아닌 명명 패턴에 대한 대체입니다.
그러나 마커 주석은 마커 인터페이스를 완전히 대체할 수 없습니다. 마커 인터페이스는 위에서 설명한 바와 같이 유형을 정의하는 데 사용됩니다. 마커 주석은 그렇지 않습니다.
우선 Serializable과 Cloneable은 마커 인터페이스의 나쁜 예라고 생각합니다.물론 메서드를 사용하는 인터페이스이지만 다음과 같은 메서드를 의미합니다.writeObject(ObjectOutputStream)
( . ( )가 됩니다.writeObject(ObjectOutputStream)
method가 있습니다.clone()
의 컴파일러를 clone()
경고와 함께 방법을 제안합니다.둘 다 이상한 모서리 케이스이기 때문에 좋은 설계 예는 아닙니다.)
마커 인터페이스는 일반적으로 다음 두 가지 목적 중 하나로 사용됩니다.
1) 제네릭이 많을 때 발생할 수 있는 지나치게 긴 타입을 피하기 위한 지름길입니다.예를 들어, 다음과 같은 메서드의 시그니처가 있다고 합니다.
public void doSomething(Foobar<String, Map<String, SomethingElse<Integer, Long>>>) { ... }
그것은 타이핑하기에 지저분하고 짜증나며, 더 중요한 것은, 이해하기 어렵다.대신 다음 사항을 고려하십시오.
public interface Widget extends Foobar<String, Map<String, SomethingElse<Integer, Long>>> { }
다음으로 방법은 다음과 같습니다.
public void doSomething(Widget widget) { ... }
더 명확해질 뿐만 아니라 위젯 인터페이스를 Javadoc할 수 있으며 위젯 코드에서 발생하는 모든 항목을 더 쉽게 검색할 수 있습니다.
2) Java의 교차 유형 부족을 방지하는 방법으로 마커 인터페이스를 사용할 수도 있습니다.마커 인터페이스에서는 메서드시그니처 등 2종류의 것을 요구할 수 있습니다.어플리케이션에 위에서 설명한 바와 같이 몇 가지 인터페이스 Widget이 있다고 가정합니다.위젯을 반복해서 사용할 수 있는 방법이 있는 경우(작성되었지만 여기서 함께 작업함) 유일한 해결책은 두 인터페이스를 확장하는 마커 인터페이스를 작성하는 것입니다.
public interface IterableWidget extends Iterable<String>, Widget { }
그리고 당신의 코드:
public void doSomething(IterableWidget widget) {
for (String s : widget) { ... }
}
인터페이스에 메서드가 포함되어 있지 않은 경우 및 오브젝트가 어떤 기능을 얻을 수 있는 경우 해당 인터페이스를 구현함으로써 이러한 유형의 인터페이스를 마커 인터페이스라고 합니다.
언급URL : https://stackoverflow.com/questions/25850328/marker-interfaces-in-java
'IT' 카테고리의 다른 글
게터와 세터? (0) | 2022.10.29 |
---|---|
MySQL의 utf8mb4와 utf8 문자 집합의 차이점은 무엇입니까? (0) | 2022.10.29 |
MySQL 뷰에 데이터를 삽입할 수 있습니까? (0) | 2022.10.29 |
여러 개의 컬럼과 제한 2로 그룹화하시겠습니까? (0) | 2022.10.28 |
JPA getSingleResult() 또는 늘 (0) | 2022.10.28 |