Java가 왜 형식 유추를하지 않습니까? VM이 매우

나는 언어가 언어이고 VM이 매우 성숙하다는 점에서 Java가 왜 형식 유추를하지 않는지 항상 궁금했습니다. Google의 Go는 형식 유추가 뛰어난 언어의 한 예이며 입력해야하는 양을 줄입니다. 이 기능 뒤에 Java의 일부가 아닌 특별한 이유가 있습니까?



답변

기술적으로 말하면 Java는 제네릭을 사용할 때 형식 유추를 가지고 있습니다 . A의 일반적인 방법 과 같은

public <T> T foo(T t) {
  return t;
}

컴파일러는 작성시 분석하고 이해합니다.

// String
foo("bar");
// Integer
foo(new Integer(42));

인수로 입력 된 내용에 따라 첫 번째 호출에 대해서는 문자열이 리턴되고 두 번째 호출에 대해서는 정수가 리턴됩니다. 결과적으로 적절한 컴파일 타임 검사를 받게됩니다. 할 때 또한 자바 7에서, 하나는 추론 몇 가지 추가 유형을 얻을 수있는 인스턴스 제네릭이 너무 좋아

Map<String, String> foo = new HashMap<>();

Java는 우리를 위해 빈 꺾쇠 괄호를 채울만큼 친절합니다. Java가 왜 변수 할당의 일부로 타입 추론 을 지원하지 않습니까? 한 시점 에서 변수 선언에 형식 유추에 대한 RFE 가 있었지만 “수정하지 않음”으로 닫혔습니다.

인간은 두 가지 방식으로 형식 선언의 중복성으로부터 혜택을받습니다. 먼저, 중복 유형은 유용한 문서 역할을합니다. 독자는 getMap () 선언을 검색하여 반환되는 유형을 찾을 필요가 없습니다. 둘째, 이중화를 통해 프로그래머는 의도 된 유형을 선언 할 수 있으므로 컴파일러가 수행 한 교차 점검의 이점을 얻을 수 있습니다.

이것을 닫은 기고자는 또한 그것이 “비자 바와 같지 않다”고 느끼며 이것이 내가 동의하는 것이라고 언급했다. 자바의 장황함은 축복이자 저주가 될 수 있지만 언어를 그대로 만들어줍니다.

물론 그 특정 RFE는 그 대화의 끝이 아니 었습니다. Java 7 동안이 기능은 다시 고려 되었으며 James Gosling의 테스트 구현을 포함하여 일부 테스트 구현이 작성되었습니다. 다시 말하지만이 기능은 결국 중단되었습니다.

Java 8이 출시되면서 이제 람다의 일부로 형식 유추를 얻습니다.

List<String> names = Arrays.asList("Tom", "Dick", "Harry");
Collections.sort(names, (first, second) -> first.compareTo(second));

자바 컴파일러 방법을보고 할 수있는 Collections#sort(List<T>, Comparator<? super T>)다음의 인터페이스 Comparator#compare(T o1, T o2)및 그 결정 firstsecondA가되어야 String하므로 프로그래머 람다 표현 유형을 재 작성하는 것을 포기 수.


답변

먼저, 형식 유추는 런타임이 30 년 된 CPU인지 또는 새로운 비트인지 여부에 관계없이 런타임의 성숙도와 는 아무런 관련없습니다 . 컴파일러에 관한 것입니다.

즉, 제네릭에 허용되며 제네릭이 아닌 유형에 허용되지 않는 이유는 철학 때문인 것으로 보입니다. 디자이너가 추가하지 못하게하는 것은 없습니다.

업데이트 : java 10에서 지원하는 것 같습니다 —- http://openjdk.java.net/jeps/286


답변

내가 아는 한, Java가 90 년대 초에 설계되었을 때 형식 추론은 주류 언어들 사이에서 인기가 없었지만 (ML과 같이 이미 잘 알려진 개념이었습니다). 따라서 Java가 C ++, Pascal 또는 기타 주류 언어를 사용하지 않는 프로그래머를 대상으로하기 때문에 유형 유추가 지원되지 않았다고 생각할 수 있습니다 (최소한의 놀람 원칙).

또한 Java의 디자인 원칙 중 하나는 프로그래머와 컴파일러가 코드에 대해 동일한 이해를 갖도록 명시 적으로 작성하는 것입니다. 정보를 복제하면 오류 가능성이 줄어 듭니다. 물론 더 많은 문자를 입력하는 것이 제공하는 추가 안전성의 가치가 있는지 여부는 맛의 문제 일 수 있지만 이것은 Java에 대한 디자인 철학이었습니다.

Java가 미래에 유형 유추를 얻을지 모르겠지만 IMO는 언어에 큰 혁명이 될 것입니다 (Glenn Nelson이 언급했듯이 “Java와 유사하지 않음”으로 설명 됨). 새로운 이름을 선호하는 Java 이름.

유형 유추와 함께 JVM 언어를 사용하려면 Scala를 사용할 수 있습니다.


답변

몇 가지 가능한 이유를 생각할 수 있습니다. 하나는 명시 적 타이핑이 자체 문서화라는 것입니다. Java는 일반적으로 이것을 결정보다 우선 순위로 만듭니다. 또 다른 이유는 유형이 다소 모호한 경우 일 수 있습니다. 유형 또는 하위 유형이 루틴을 만족시킬 수있는 경우와 같습니다. List를 사용하고 싶지만 누군가가 와서 ArrayList 전용 메소드를 사용한다고 가정 해 봅시다. JIT는 ArrayList를 유추하고 컴파일 오류를 원하더라도 계속 수행합니다.


답변

요구 사항에 맞는 가장 일반적인 인터페이스를 사용하여 변수를 선언하고 다음과 같이 적절한 구현 클래스로 변수를 초기화하라는 잘 확립 된 권장 사항과 모순됩니다.

Collection<String> names = new ArrayList<>();

효과적으로,

var names = new ArrayList<String>();

구문 설탕에 불과합니다

ArrayList<String> names = new ArrayList<String>();

원하는 경우 IDE에서 new ArrayList<String>()“원 클릭”(리 팩터 / 로컬 변수 작성)을 사용 하여 표현식 에서 생성 할 수 있지만 “인터페이스 사용”권장 사항과 모순된다는 점을 기억하십시오.


답변