평소에는 주의를 기울이지 않는 오해가 많이 담겨 있는 "Java In-Depth Analysis"라는 책을 발견했습니다. 개발 중에는 사용하지 않을 수도 있지만 이러한 개념이 막연해서는 안 됩니다. 책의 내용은 여전히 매우 유용합니다. 여기에 몇 가지 요약 내용이 있습니다.
1. Java에는 goto 문이 없습니다. goto 문을 광범위하게 사용하면 프로그램의 가독성과 유지 관리성이 저하되므로 Java 언어에서는 goto 사용이 취소되었습니다. 동시에 프로그래머가 스스로 goto를 사용하여 발생하는 혼란을 피하기 위해 Java 언어는 여전히 goto를 키워드로 정의하지만 구문을 정의하지 않으므로 "예약어"라고 합니다.
2, true, false, null은 IDE에서 서로 다른 색상으로 표시되지만 키워드가 아니라 String 유형의 abc와 마찬가지로 "리터럴 상수"입니다.
3. 이름을 정의할 때 $를 사용하지 마세요. 컴파일러가 .java 파일을 컴파일할 때 "$"를 최상위 유형과 맨 아래 유형 사이의 커넥터로 컴파일하기 때문입니다. 다음 예를 참조하세요.
package com.laixintao.Test; public class Outer$Inner { public static void main(String[] args) { Outer o = new Outer(); Outer.Inner i = o.new Inner(); i.innerPrint(); } } class Outer { class Inner { void innerPrint() { System.out.println("Inner Print!"); } } }
이 코드를 컴파일(javac Test3.java)할 때 컴파일러는 다음 오류를 보고합니다. Test.java:12: Error: Duplicate class: com.laixintao.Test.Outer . 내부 클래스 Inner{ ^
4. 유니코드 이스케이프 문자는 구문 분석 프로그램 이전에 매우 일찍 처리됩니다. 예:
// char c1 = 'u00a'; // char c2 = 'u00d';
이 두 줄의 코드가 프로그램에 나타나면 컴파일 오류가 보고됩니다. 이 두 개의 유니코드 코드는 각각 "라인 피드"와 "캐리지 리턴"을 나타냅니다. 따라서 컴파일러가 컴파일할 때 코드는 다음과 같습니다.
// char c1 = ' '; // char c2 = ' ';
5 유니코드 코드는 16비트 문자 인코딩을 사용합니다. . Java에서는 char 유형으로 표시됩니다. 이제 유니코드는 100만 문자로 확장되었으며 16비트 제한을 초과하는 문자는 보조 문자가 됩니다. 모든 보조 문자는 문자 상수로 표현될 수 없습니다.
6. short, byte, char이 연산에 참여하면 결과는 상위 타입이 아닌 int 타입이 됩니다. 변수 유형이 byte, short 또는 byte이고 컴파일 시간 상수가 할당되어 있고 상수가 변수의 값 범위를 초과하지 않는 경우 컴파일러는 암시적 축소 변환을 수행할 수 있습니다. 이 암시적 축소 변환은 변수 할당에만 적용되고 메서드 호출 문에는 적용되지 않으므로 안전합니다. 즉, 메서드 호출 시 매개 변수 전달에는 적용되지 않습니다. (자세한 내용은 Java의 기본 유형 변환에 대한 사소한 문제를 참조하세요.)
7. unsigned 유형인 char 유형에 주의하세요. 따라서 char과 short 또는 char와 byte 간 변환에서는 유형 변환을 명시적으로 사용해야 합니다. 바이트에서 char로의 변환은 확장 및 축소 변환입니다. 즉, 바이트가 먼저 확장되고 int로 변환된 다음 char로 축소됩니다.
8. 정수 데이터 간의 확장 변환에서 피연산자가 char 유형(unsigned 유형)인 경우 unsigned 확장이 수행되고 확장 비트는 0입니다. 피연산자가 byte, short 또는 int(signed)인 경우 유형), 부호 확장이 수행되며 확장 비트는 변수의 부호 비트입니다.
9. 정수 데이터 간 축소 변환은 별도의 처리 없이 상위 비트만 잘라서 삭제합니다.
10.0.1+0.2는 0.3.System.out.println((double)0.1+(double)0.2); 이 문의 출력 결과는 0.30000000000000004입니다. 컴퓨터는 데이터를 저장하기 위해 이진수를 사용하기 때문에 십진수를 사용하면 1/3과 같은 분수를 정확하게 표현할 수 없는 것처럼 많은 소수는 이진수를 사용하여 정확하게 표현할 수 없습니다(사실 대부분의 소수는 근사치입니다). 대부분의 부동 소수점 유형은 정수만큼 정확하지 않고 대략적인 값만 컴퓨터에 저장합니다. 또 다른 예는 무한 루프입니다. for(float f = 10.1f;f != 11;f+=0.1f){}
11 float 유형은 7~8개의 유효 숫자를 유지할 수 있습니다. double 유형은 15~16개의 유효 숫자를 유지할 수 있습니다. 따라서 int 유형 또는 long 유형 값이 double 또는 float보다 유효 숫자가 더 많은 경우 값의 최하위 비트 중 일부가 손실되어 정확도가 떨어집니다. 이때 IEEE754 최근접 반올림 모드에서는 정수값에 가장 가까운 부동소수점 값을 추출한다. 정수를 부동 소수점으로 변환하는 것은 확장된 변환이지만 숫자 값이 매우 크거나 매우 작은 경우(절대 값이 매우 큰 경우) 특정 정밀도 손실이 발생합니다.
12. i+++j를 계산하는 방법은 무엇인가요? (이 문제는 C/C++에서 논의됨) C/C++는 구현된 하드웨어 구조에 따라 달라지고 환경에 따라 결과가 다르기 때문에 의미가 없습니다. 그러나 Java에서는 이 결과가 고정되어 실행되는 하드웨어 환경이나 플랫폼에 영향을 받지 않습니다.) 답변: 그리디 규칙에 따르면 접두사 ++가 접미사 ++보다 낫고 결과는 (i++) + j입니다.
13. i++ 및 ++i는 실제로 +1을 먼저 추가한 다음 값을 할당합니다. ++i 말할 것도 없습니다. j=i++; 기본 구현은 다음과 같습니다. 따라서 표현식은 i=15;i=입니다. i++; 결과는 15입니다. (1을 추가한 후 할당을 수행하므로 16에서 다시 15로 변경됩니다.)
14. 부동소수점형 변수저장소의 부호비트인 +0과 -0이 다릅니다. . -0과 +0이 부동 소수점 유형 관련 연산(예: 나누기 및 나머지 연산)에 참여하면 다른 결과가 생성될 수 있습니다.
15. 부동 소수점의 나누기 및 나머지 연산은 정수의 나누기 및 나머지 연산과 다릅니다. 제수가 0이면 부동 소수점 연산은 ArithmeticException을 생성하지 않습니다.
16. String 클래스는 변경이 불가능한 클래스입니다. 일단 객체가 생성되면 삭제할 수 없습니다. 문자 시퀀스를 수정하는 것처럼 보이는 String 클래스의 메서드는 실제로 객체 자체를 수정하는 대신 새로 생성된 String 객체를 반환합니다.
17. String 객체는 불변이므로 스레드로부터 안전하며 자유롭게 공유할 수 있습니다.
18 String 클래스 내에서는 문자 배열(char[])을 사용하여 문자 시퀀스를 유지합니다. String의 최대 길이는 문자 배열의 최대 길이이다. 이론적으로 최대 길이는 int 타입의 최대값인 2147483647이다. 실제로는 일반적으로 얻을 수 있는 최대값이 이론상의 최대값보다 작다. .
19. main() 메서드는 기본적으로 성능 동작 측면에서 다른 메서드와 동일합니다. 오버로드될 수 있고, 다른 메서드에 의해 호출될 수도 있고, 상속될 수도 있고, 유형 매개변수로 예외가 발생할 수도 있습니다. 프로그램의 리플렉션을 통해 기본 메서드(또는 다른 메서드)를 호출할 수도 있습니다.
20. 두 개 이상의 메소드가 이름은 같지만 매개변수 목록이 다른 경우 이러한 메소드는 오버로딩을 구성합니다. 오버로드된 메소드는 매개변수 목록에 해당하는 유형과 매개변수 개수로 구분할 수 있습니다. 단, 매개변수 이름, 메소드의 반환 유형, 메소드의 예외 목록, 유형 매개변수는 그대로 사용할 수 없습니다. 오버로드된 메소드를 구별하기 위한 조건
21. 어떤 메소드를 호출할지 순서는 다음과 같습니다.
1단계에서는 자동 박싱(unboxing)과 가변 매개변수를 고려하지 않고 해당 형식 매개변수 유형을 검색합니다. 실제 매개변수 유형과 형식 매개변수 개수를 일치시킬 수 있는 메서드는 실제 매개변수 개수와 동일합니다.
1단계에서 적합한 메서드가 없으면 두 번째 단계에서 자동 boxing 및 unboxing이 수행됩니다. 처형되다.
2단계에서 검증된 방법이 없으면 세 번째 단계에서는 가변 매개변수 방법을 고려합니다.
3단계에서 적격한 메서드를 찾을 수 없으면 컴파일 오류가 발생합니다. 조건을 지정하는 방법이 두 가지 이상인 경우 가장 구체적인 방법이 선택됩니다. 가장 명확한 메소드 정의는 다음과 같습니다. 메소드 A의 해당 형식 매개변수 목록 유형을 메소드 B의 형식 매개변수 목록 유형에 할당할 수 있는 경우 메소드 A가 메소드 B보다 더 명확합니다. 가장 명확한 방법을 선택할 수 없으면 컴파일 오류가 발생합니다.
22. 재작성과 숨김의 본질적인 차이점은 재작성은 동적으로 바인딩되며 관련 클래스를 호출하는 방법은 가리키는 객체의 실제 유형에 따라 결정됩니다. 런타임 참조로. Hidden은 정적으로 바인딩되며 호출할 관련 멤버는 컴파일 타임에 참조되는 정적 유형에 따라 결정됩니다. 즉, 하위 클래스가 상위 클래스 메서드를 재정의하는 경우 상위 클래스 참조가 하위 클래스 객체를 가리키면 하위 클래스 메서드는 상위 클래스 참조를 통해 호출됩니다. 하위 클래스가 상위 클래스의 메서드(멤버 변수)를 숨기더라도 상위 클래스의 메서드(멤버 변수)는 여전히 상위 클래스에 대한 참조를 통해 호출됩니다.
23. 생성자는 재귀적으로 호출됩니다. 하위 클래스의 생성자는 Object 클래스의 생성자가 호출될 때까지 상위 클래스의 생성자를 호출합니다.
24 생성자는 객체를 생성하지 않습니다. 생성자는 객체를 생성하기 위해 new를 사용할 때 시스템에 의해 호출되며 클래스의 인스턴스 멤버를 초기화하는 데 사용됩니다. 순서상 객체가 먼저 생성된 다음 생성자가 호출됩니다. (생성자는 새 객체를 생성하지 않습니다.)
25. 기본 생성자는 비어 있지 않습니다. 이 생성자는 부모 클래스의 매개 변수가 없는 생성자를 호출하고 인스턴스 멤버 변수의 초기화를 수행할 수 있습니다. 따라서 기본 생성자는 적어도 부모 클래스의 생성자를 호출하고, 생성자에서 모두 실행되는 인스턴스 변수 선언 초기화, 인스턴스 초기화 블록 등 더 많은 작업을 수행할 수 있습니다.
26 == 또는 != 연산자의 두 피연산자 중 하나가 기본 데이터 유형이고 다른 하나가 래퍼 클래스 참조 유형인 경우 참조 유형을 unbox하여 기본 데이터 유형으로 변환하고, 그런 다음 두 기본 데이터 유형의 값이 동일한지 비교합니다.
27. Java에서는 배열도 클래스이며, 배열에 선언된 참조 변수는 배열 유형의 객체를 가리킵니다. 모든 배열은 Object 클래스를 상속하고 java.lang.Cloneable 및 java.io.Serialized 인터페이스를 구현합니다. 배열의 멤버에는 가변 길이(암시적으로 존재함)와 Object 클래스에서 상속된 멤버가 포함됩니다. Cloneable 및 Serialized는 멤버를 명시적으로 선언하지 않는 두 개의 표시된 인터페이스입니다.
28. 인터페이스는 완전히 추상적인 디자인이므로 인스턴스화할 수 없습니다. A가 새로운 메소드를 사용하여 생성한 변명 유형을 사용하면 실제로 인터페이스 유형을 구현하는 익명 클래스가 생성됩니다.
29. 두 인터페이스가 동일한 변수를 선언하는 경우
30. 두 개의 인터페이스가 동일한 이름의 메서드 m을 선언하고 두 메서드가 오버로드를 구성하지 않는 경우 인터페이스가 두 인터페이스를 동시에 상속할 수 있거나 클래스가 두 인터페이스를 모두 상속할 수 있는 경우 시그니처가 동시에 두 개의 m 메소드 시그니처의 하위 시그니처인 메소드 시그니처여야 하며, 메소드의 반환 유형에는 해당 유형이 두 m 메소드의 반환 유형인 유형이 있어야 합니다. 동시에 교체 가능한 유형.
위 내용은 Java에 대한 일반적인 오해와 내용입니다. 자세한 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!