IDE가 너무 똑똑하다면 왜 "clone ()"을 캐스팅해야합니까?


13

코드를 입력하는 동안 IDE ( NetBeans ) 유형이 내 확인 Collections합니다. 그러나 왜 반환 된 객체를 캐스팅해야 Object.clone()합니까? 어느 것이 좋습니다. 파울이 없습니다. 그러나 여전히 이해가되지 않습니다.

유형 검사가 캐스팅없이 반환 된 객체를 Object.clone()불가능합니까? 제네릭 프레임 워크는 나를 IDE가 확인할 수 있습니다 생각하게 유형 은 "의 오른쪽에 객체 참조 = I 입력을 나는 동안 캐스팅없이"마크? 나는 그것을 얻지 못한다.

부록
나의 사용 사례는 pubdate 개인 Calendar필드 가 있다는 것 입니다. 나는 쓰려고했다 :

Calendar getPubdate() {
    return pubdate;
}

그러나 호출자가 내 pubdate를 수정할 수있는 위험이 있으므로 사본을 반환했습니다.

Calendar getPubdate() {
    return (Calendar) pubdate.clone();
}

그런 다음 왜 내가 캐스팅해야하는지 궁금했습니다 pubdate.clone(). 메소드 시그니처에는 바로 유형이 있습니다. NetBeans 는이를 알아낼 수 있어야합니다. 그리고 NetBeans는와 비슷한 일을하고있는 것 같습니다 Collections.


5
짧은 (!) 코드 예제가 도움이 될 것입니다.
Doc Brown

78
IDE는 언어 자체와 별개이므로 스마트 Netbeans가 Java가 작동하는 방식에 영향을 미치지 않습니다.
JacquesB

7
반품 유형 공분산으로 인해 이보다 는 전체 MyObject에서 반품하는 것이 좋습니다 . 이렇게하면 전체 문제가 제거됩니다. 더 이상 사용하지 않는 것이 좋습니다 (유효한 Java 항목 # 11). clone()Objectclone()
Boris the Spider

또는 'cast "clone ()"' 에 대한 귀하의 질문을 강조하고 있습니까? 전자에서 나온 질문은 실제로 후자의 질문보다 훨씬 더 나은 질문 일 수 있기 때문입니다.
user541686

질문 제목을 읽을 때 내가 생각하는 유일한 것은 this.clone()프로그래머 대상에 관한 것입니다 . 특히 Tue가 릴리스 된 후 Wed 's night에 있습니다. 죄송하지만이 의견을 작성해야합니다. 스마트 IDE가 왜 우리를 위해 모든 버그를 수정하지 못하는가 LOL
Mai

답변:


53

왜 반환 된 객체를 캐스팅해야 Object.clone()합니까?

를 반환하기 때문 Object입니다.

제네릭 프레임 워크는 나를 IDE가 확인할 수 있습니다 생각하게 유형 은 "의 오른쪽에 객체 참조 = I 입력을 나는 동안 캐스팅없이"마크? 나는 그것을 얻지 못한다.

Object.clone 일반이 아닙니다.

clone디자인 할 때 제네릭이 존재했다면 아마도 F-Bounded Polymorphism을 사용하여 다음과 같이 보일 것입니다.

interface Cloneable<T extends Cloneable<T>> {
  T clone();
}

Java에 MyType 기능이있는 경우 다음과 같습니다.

interface Cloneable {
  this clone();
}

그러나 제네릭 Object.clone은 디자인 되었을 때 존재 하지 않았고 Java에는 MyType이 없으므로 안전하지 않은 유형의 버전이 Object.clone우리가 사용해야 합니다.


방금 저를 혼란스럽게 한 IDE 기능이 백그라운드 컴파일이라는 것을 깨달았습니다. 즉, 제네릭을 사용하여 코드 완성 및 자동 유형 검사가 가능합니까? 개인적으로 명시 적 컴파일까지 유형 검사를 지연시키고 싶습니다. 그러나 나는 코드 완성을 좋아합니다.
konishiki

1
Java 8 (및 Java 7) 유형 유추 를 가진 @konishiki는 도움을 제공하기 위해 IDE가 유형을 유추해야합니다. 부분 컴파일이 필요합니다. 형식 유추하기 전에 자동 완성에 대한 컴파일이 필요하지 않습니다.
Boris the Spider

@BoristheSpider 의견을 보내 주셔서 감사합니다! 나는 더 많은 테스트 / 사고를해야합니다. 대단히 감사합니다.
konishiki

왜 통과해야 original합니까?
Clashsoft

@Clashsoft : 명백한 기능적 프로그래밍 버전을 수정하면서 바보 같은 생각. 감사.
Jörg W Mittag 2016 년

26

이것은 IDE의 기능이 아니라 언어 정의의 기능입니다.

IDE는 프로그래밍 언어를보다 효율적으로 사용하도록 도와 주며 해당 언어의 의미를 변경하지 않습니다. 즉, 에디터 헬퍼는 원하는 것이 확실 할 때 캐스트를 자동으로 삽입 할 수 있지만, 언어의 규칙을 어 기고 컴파일되지 않은 코드가 유효한 척하는 것은 아닙니다.

편집 IDE가 자체 컴파일러를 번들로 묶을 수 있다는 것은 사실이며, 예를 들어 부분 구문 분석 트리에 더 많은 내부 정보가 포함 된 오류보고를 개선하기 위해 많은 사람들이 정확히 그렇게합니다. 그러나이 내부 컴파일러가 공식 SDK와 다른 언어 의미를 구현하게 하는 것은 매우 나쁜 생각입니다. 즉 개발에서 작동하는 코드가 프로덕션 환경에 설치 될 때 신비하게 실패 할 수 있기 때문에 정의에 따라 문제가 발생합니다. 디버깅 가능!


이것이 일어난 일입니다 : 코드 완성이 IDE 기능 (반사를 통해 완료)이라고 확신합니다. 그리고 내가 말한 자동 유형 검사는 IDE에서 발생합니다 (배경 컴파일을 통해). 나는 그것이 일어나고 있기를 바랍니다.
konishiki

1
IDE 언어 사양의 모든 규칙을 쉽게 위반하고 어쨌든 코드를 컴파일 할 수 있습니다. 예를 들어 NetBeans와 Eclipse 모두 ​​자체 컴파일러를 사용한다는 것을 알고 있습니다. 따라서 이러한 경우 IDE와 컴파일러는 사실상 동일한 것입니다. 좋은 생각은 아니지만 C 컴파일러는 항상 그렇게합니다.
MichaelS

@MichaelS C 언어 사양은 구현간에 상당한 차이를 허용하도록 설계되었으므로 서로 다른 공급 업체가 서로 다른 가능한 방법 중에서 선택하고 추가 기능을 추가 할 수 있습니다. 이는 본 명세서에서 이러한 다양한 변형을 허용하는 데 필요한 다양한 모호한 영역을 생성한다. "C"라는 이름은 상표가 아니므로 아무도이 용어의 사용을 통제하지 않습니다. Java 사양은 가능한 한 많은 모호성을 제거하도록 설계되었으며 Java는 상표로 등록되어 있으며 상표 소유자는이를 준수하는 구현에서만 사용할 수 있습니다.
Jules

현대 IDE에는 어쨌든 컴파일러가 필요합니다. 코드 완성 힌트를 사용하려면 커서를 구문 분석하기 전에 코드를 작성해야합니다. 그리고 파서뿐만 아니라 전체 컴파일러가 필요한 제네릭 (또는 C ++ 템플릿)이 있습니다.
MSalters

3

Object.clone 메서드의 형식 서명 때문입니다. 형식 서명은 메서드가 Object 형식의 개체를 반환 할 것임을 나타냅니다.

protected Object clone() throws CloneNotSupportedException

컬렉션은 소위 제네릭 형식을 사용하여 캐스팅 유형을 자동으로 대체합니다.

따라서이 코드가 있다면 :

List<Integer> ints = Arrays.asList(1,2,3);
int x = ints.get(0);`

컴파일러는 배후에 캐스트를 추가하므로 코드는 실제로 다음과 같습니다.

List ints = Arrays.asList(1,2,3);
int x = (Integer)ints.get(0);

0

완전성을 위해 Java 5부터 공변량 리턴 유형이 허용 됩니다. 따라서 다음을 작성할 수 있습니다.

public MyObject implements Cloneable {
  @Override
  public MyObject clone() {
    try {
      return (MyObject)super.clone();
    } catch (CloneNotSupportedException e) {
      throw new AssertionError();
    }
  }
}

이를 통해 다음 코드는 합법적입니다.

MyObject original = new MyObject();
MyObject clone = original.clone();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.