는이 작업을 수행 할 구문 법적 :왜 자바가 이것을 허용합니까?
String [] s = new String[1];
Object [] o = s;
o[0] = new Integer(42);
하지만 물론 런타임시 충돌합니다.
제 질문은 무엇입니까? 처음부터이 과제를 허용하는 시점은 무엇입니까?
는이 작업을 수행 할 구문 법적 :왜 자바가 이것을 허용합니까?
String [] s = new String[1];
Object [] o = s;
o[0] = new Integer(42);
하지만 물론 런타임시 충돌합니다.
제 질문은 무엇입니까? 처음부터이 과제를 허용하는 시점은 무엇입니까?
문제는 할당 Object [] o = s;
입니다. 나는 이것이 "this"로 무엇을 의미하는지 생각합니다.
전문 용어는 array covariance이며,이 기술 용어가 없으면 일반적으로 배열을 처리하는 코드를 사용할 수 없습니다. 예를 들어 java.util.Arrays
의 비 프리미티브 배열 메서드 대부분은 실제 Object[]
인스턴스에만 사용할 수 있으므로 쓸모가 없습니다. 분명히 이것은 완벽한 유형의 안전보다 Java 설계자가 더 중요하게 생각했습니다.
Java 5에서 소개 된 Java의 제네릭 (와일드 카드를 통한 명시 적 공분산)을 볼 때 다른 해결책이 있습니다. 그러나 그로 인해 복잡성이 상당히 증가합니다 (?
와일드 카드에 대한 지속적인 질문을 참조하십시오). Java의 원래 설계자는 복잡성을 피하고자했습니다.
컴파일러는 o
이 실제로 String[]
임을 (정적 분석없이) 알 수 없으므로 런타임에 실패하더라도 할당 할 수 있습니다. 예를 들어 Integer[]
을 o
에 할당하면 문제가 발생하지 않습니다. 당신이 컴파일러는 그것을 허용하는 코드
를 실행할 때 [] 정확한지, [] 객체에 문자열을 캐스팅하고 있기 때문에
그것은 허용하지 않는다, 당신은 java.lang.ArrayStoreException: java.lang.Integer
얻을. 이것은
Integer i = new Integer(10);
Object o = i;
String s = (String) o;
컴파일러는 불평하지 않지만 런타임에 ClassCastExeption을 얻습니다.
컴파일러는 런타임에 배열 만 문자열을 보유 할 것인지 (보유하지 않을 것인지) 결정할 수 없으므로 할당을 허용해야합니다. 런타임시 확인되는 [ArrayStoreException][1]
을 던집니다.
String [] s = new String[1];
Object [] o = s;
o = new Integer[1];
o[0] = new Integer(1);
이 상황 유효 확인을 실행합니다
이것이 고려하십시오. 보다 넓은 시야를 제공하기 위해, IMHO 배열은 Java에서 낮은 레벨의 새는 추상화입니다.
할당 그런 종류의 수의 요점은 그것을 허용하지하면 다음과 불가능과 같은 일을 할 것입니다 : 컴파일러가 당신의 문자열을 금지
ArrayList[] lists = new ArrayList[10];
lists[0] = new ArrayList();
List[] genericLists = lists;
lists[0].add("someObject");
경우 -> 개체 경우, 그것은 또한 ArrayList를 금지해야 -> List 및 서브 클래스에서 수퍼 클래스 유형 중 하나로 할당하는 다른 모든 인스턴스. 이런 종류의 Java는 쓸모없는 객체 지향 언어의 많은 기능을 만듭니다. 물론,이 같은 일을 훨씬 더 일반적이다 : 관계없이
List[] lists = new List[10];
lists[0] = new ArrayList();
lists[0].add("someObject");
하지만, 그것을 만들기 위해 프로그래머에게 달려 있으므로, 동시에 많은 유용하고 합법적 인 사용 사례를 허용하지 않고 이러한 경우를 필터링 할 수 없습니다 컴파일러 그들이하는 일이 제정신이 아님을 확신하십시오.원하는 것이 Object[]
이면 변수를 선언하십시오. String[]
으로 선언하고 Object[]
으로 전송 한 다음 실제로 가지고있는 것이 String[]
인 것을 잊으면 간단히 프로그래머 오류가 발생합니다.
일반적으로 컴파일러는 o
이 String[]
으로 지정되었는지 여부를 알 수 없습니다. 이것을 고려하십시오 :
String[] s = new String[1];
Object[] o;
if (complexFunction(System.currentTimeMillis())) {
o = s;
} else {
o = new Integer[1];
}
o[0] = 42;
컴파일러는 o
이 걸릴 것입니다 어떤 종류의 디자인 타임에 알 수 없습니다 - 그냥 할당을 할 수 있도록.
하지만 질문에 전혀 대답하지 않습니다. 당신은 단순히 OP가 말한 것을 정확히 다시 말하고 있습니다. 또한 OP는 그것이 "허용"되었다고 결코 말하지 않았습니다 *, OP는 "구문 적으로"* 정확하고 런타임에 충돌하고 있다고 말했다. OP의 잘 공식화 된 질문은 매우 명확하며 대답은 아무 것도 대답하지 않습니다 ... – SyntaxT3rr0r
저는 컴파일러가 객체와 유추하여 오류나 경고를 생성하지 않는다는 것을 보여주고 있습니다. 더욱이, ArrayStoreException은 배열에 값을 할당 할 때 ClassCastExeception과 동등합니다. 형식이 호환되지 않을 때 throw됩니다. 그러나 의견이 맞지 않아도됩니다. – Augusto