자바 의 기초 개념 사용 에 대한 상세 한 설명
우선 코드 보기:
class Parent
{
public static StaticVarible staticVarible= new StaticVarible("父类-静态变量1");
public StaticVarible instVarible= new StaticVarible("父类-成员变量1");
static
{
System.out.println("父类-静态块");
}
{
System.out.println("父类-初始化块");
}
public static StaticVarible staticVarible2= new StaticVarible("父类-静态变量2");
public StaticVarible instVarible2= new StaticVarible("父类-成员变量2");
public Parent()
{
System.out.println("父类-实例构造函数");
}
}
class Child extends Parent
{
public static StaticVarible staticVarible= new StaticVarible("子类-静态变量1");
public StaticVarible instVarible= new StaticVarible("子类-成员变量1");
static
{
System.out.println("子类-静态块");
}
public Child()
{
System.out.println("子类-实例构造函数");
}
{
System.out.println("子类-初始化块");
}
public static StaticVarible staticVarible2= new StaticVarible("子类-静态变量2");
public StaticVarible instVarible2= new StaticVarible("子类-成员变量2");
}
class StaticVarible
{
public StaticVarible(String info)
{
System.out.println(info);
}
}
그리고 다음 문장 을 실행 합 니 다:
Child child = new Child();
출력 결 과 는 다음 과 같 습 니 다.
父类-静态变量1
父类-静态块
父类-静态变量2
子类-静态变量1
子类-静态块
子类-静态变量2
父类-成员变量1
父类-初始化块
父类-成员变量2
父类-实例构造函数
子类-成员变量1
子类-初始化块
子类-成员变量2
子类-实例构造函数
결론.
상기 결 과 를 통 해 알 수 있 듯 이 한 대상 을 예화 할 때 각 부분의 로드 순 서 는 다음 과 같다.
부모 클래스 정적 구성원/부모 클래스 정적 초기 화 블록 -> 하위 클래스 정적 구성원/하위 클래스 초기 화 블록 -> 부모 클래스 구성원 변수/부모 클래스 초기 화 블록 -> 부모 클래스 구조 함수 -> 하위 클래스 구성원 변수/하위 클래스 초기 화 블록 -> 하위 클래스 구조 함수
String 과 관련 된 일 들 이 있 습 니 다. 우선 자바 의 더미 와 스 택 에 대해 이야기 해 보 겠 습 니 다.
• 스 택: 기본 형식 을 저장 합 니 다. char/by te/short/int/long/float/double/boolean • 더미: 인용 형식 을 저장 하 는 동시에 스 택 에 가리 키 는 지침 을 보관 합 니 다. 쓰레기 수 거 는 대상 이 회수 할 수 있 는 지 여 부 를 판단 합 니 다. 스 택 에 포인터 가 있 는 지 여 부 를 판단 하 는 것 입 니 다.String 은 특수 한 데이터 형식 으로서 기본 유형 과 완전히 같 지 않 고 모든 인용 유형 도 아니 며 많은 면접 문제 가 그 모습 을 가지 고 있다.
String 형식 변수의 저장 구조 String 의 저장 구 조 는 두 부분 으로 나 뉘 는데 우 리 는 String a = "abc"로 나 뉜 다.예 를 들 어 String 형식의 저장 방식 을 설명 합 니 다.
1) 스 택 에 char 배열 을 만 들 고 값 은 'a', 'b', 'c' 로 나 뉜 다.
2) 더미 에 String 대상 을 만 듭 니 다.
자바 의 문자열 풀 은 공간 과 자원 을 절약 하기 위해 JVM 은 문자열 풀 을 유지 하거나 나타 난 문자열 의 일 부 를 캐 시 합 니 다.
예 를 들 어 다음 코드:
String v1 = "ab";
String v2 = "ab";
실제로 v1 = = v2 는 JVM 이 v1 성명 후 'ab' 에 캐 시 를 했 기 때문이다.
그러면 JVM 이 문자열 을 캐 시 하 는 근 거 는 무엇 입 니까?우 리 는 아래 의 코드 를 보 았 습 니 다. 매우 재 미 있 습 니 다.
public class StringTest {
public static final String constValue = "ab";
public static final String staticValue;
static
{
staticValue="ab";
}
public static void main(String[] args)
{
String v1 = "ab";
String v2 = "ab";
System.out.println("v1 == v2 : " + (v1 == v2));
String v3 = new String("ab");
System.out.println("v1 == v3 : " + (v1 == v3));
String v4 = "abcd";
String v5 = "ab" + "cd";
System.out.println("v4 == v5 : " + (v4 == v5));
String v6 = v1 + "cd";
System.out.println("v4 == v6 : " + (v4 == v6));
String v7 = constValue + "cd";
System.out.println("v4 == v7 : " + (v4 == v7));
String v8 = staticValue + "cd";
System.out.println("v4 == v8 : " + (v4 == v8));
String v9 = v4.intern();
System.out.println("v4 == v9 :" + (v4 == v9));
String v10 = new String(new char[]{'a','b','c','d'});
String v11 = v10.intern();
System.out.println("v4 == v11 :" + (v4 == v11));
System.out.println("v10 == v11 :" + (v10 == v11));
}
}
출력 결과 에 주의 하 십시오:
v1 == v2 : true
v1 == v3 : false
v4 == v5 : true
v4 == v6 : false
v4 == v7 : true
v4 == v8 : false
v4 == v9 :true
v4 == v11 :true
v10 == v11 :false
모든 판단 이 트 루 로 돌아 가 는 것 은 아니 라 는 것 을 알 게 될 것 이다. 이것 은 우리 위의 말 과 모순 되 는 것 같다.사실은 그렇지 않다.
결론 1. JVM 은 컴 파일 할 때 확인 할 수 있 는 상수 만 캐 시 할 수 있 고 실행 할 때 상수 가 아 닙 니 다.
상기 코드 중의 constValue 는 컴 파일 시 상수 에 속 하고 staticValue 는 실행 시 상수 에 속한다.
2. new 방식 으로 생 성 된 문자열 은 JVM 캐 시 방식 이 다 릅 니 다.
그래서 상기 코드 에서 v1 은 v3 와 같 지 않다.
String 의 이런 디자인 은 향 원 모드 에 속 합 니까?이 화 제 는 비교적 재 미 있 습 니 다. 대부분 디자인 모델 을 이야기 하 는 글 은 향 원 에 대해 이야기 할 때 보통 String 을 예 로 들 지만 향 원 모델 에 속 합 니까?
문자열 과 향 원 의 관 계 는 다음 과 같은 글 을 참고 할 수 있 습 니 다. C\# 문자열 과 향 원 (Flyweight) 모드 에 깊이 들 어가 문자열 의 반전 출력 을 분석 하 는 경우 문자열 을 문자 배열 로 보고 반전 배열 방식 으로 문자열 을 반전 시 킵 니 다.
현란 한 방법 으로 상속 관계 구조 에서 의 방법 을 호출 하여 계승 을 호출 하 는 것 은 대상 을 대상 으로 하 는 디자인 에서 흔히 볼 수 있 는 방식 으로 '코드 재 활용' 을 효과적으로 실현 할 수 있 으 며, 자 류 는 부모 류 방법 을 재 작성 하 는 자유 도 있 기 때문에 부모 류 방법 을 호출 하 는 것 인지, 하위 방법 을 사용 하 는 것 인지 에 문 제 를 가 져 왔 다.
다음 코드 보기:
public class PropertyTest {
public static void main(String[] args)
{
ParentDef v1 = new ParentDef();
ParentDef v2 = new ChildDef();
ChildDef v3 = new ChildDef();
System.out.println("=====v1=====");
System.out.println("staticValue:" + v1.staticValue);
System.out.println("value:" + v1.value);
System.out.println("=====v2=====");
System.out.println("staticValue:" + v2.staticValue);
System.out.println("value:" + v2.value);
System.out.println("=====v3=====");
System.out.println("staticValue:" + v3.staticValue);
System.out.println("value:" + v3.value);
}
}
class ParentDef
{
public static final String staticValue = "父类静态变量";
public String value = "父类实例变量";
}
class ChildDef extends ParentDef
{
public static final String staticValue = "子类静态变量";
public String value = "子类实例变量";
}
출력 결 과 는 다음 과 같 습 니 다.
=====v1=====
staticValue:父类静态变量
value:父类实例变量
=====v2=====
staticValue:父类静态变量
value:父类实例变量
=====v3=====
staticValue:子类静态变量
value:子类实例变量
결론 은 부모 클래스 를 호출 하 는 방법 이 냐, 하위 클래스 를 호출 하 는 방법 이 냐, 변수의 성명 유형 과 만 관계 가 있 고, 실례 화 된 유형 과 는 관계 가 없다.
값 전달 인지, 인용 전달 인지, 이 화제 에 대한 제 관점 은 값 전달 입 니 다. 스 택 에 저 장 된 내용 을 전달 하기 때 문 입 니 다. 기본 유형의 값 이 든 더미 에 있 는 대상 을 가리 키 는 지침 이 든 모두 인용 이 아 닌 값 입 니 다. 또한 값 전달 과정 에서 JVM 은 값 을 복사 한 다음 에 복 사 된 값 을 호출 방법 에 전달 합 니 다.
이런 방식 으로 우 리 는 아래 의 코드 를 살 펴 보 자.
public class ParamTest {
public void change(int value)
{
value = 10;
}
public void change(Value value)
{
Value temp = new Value();
temp.value = 10;
value = temp;
}
public void add(int value)
{
value += 10;
}
public void add(Value value)
{
value.value += 10;
}
public static void main(String[] args)
{
ParamTest test = new ParamTest();
Value value = new Value();
int v = 0;
System.out.println("v:" + v);
System.out.println("value.value:" + value.value);
System.out.println("=====change=====");
test.change(v);
test.change(value);
System.out.println("v:" + v);
System.out.println("value.value:" + value.value);
value = new Value();
v = 0;
System.out.println("=====add=====");
test.add(v);
test.add(value);
System.out.println("v:" + v);
System.out.println("value.value:" + value.value);
}
}
class Value
{
public int value;
}
출력 결과:
v:0
value.value:0
=====change=====
v:0
value.value:0
=====add=====
v:0
value.value:10
우 리 는 change 방법 을 호출 할 때 우리 가 전달 하 는 것 이 대상 을 가리 키 는 지침 이 라 고 해도 최종 대상 의 속성 은 변 하지 않 는 것 을 보 았 다. 이것 은 change 방법 체 내 에 대상 을 새로 만 든 다음 에 '복 제 된 대상 을 가리 키 는 지침' 을 '새로운 대상' 을 가리 키 고 새로운 대상 의 속성 을 조정 하기 때문이다. 그러나'복사 전의 원래 대상 을 가리 키 는 지침' 은 여전히 '원래 대상' 을 가리 키 고 속성 은 변화 가 없다.
final/finally/finalize 의 차이 final 은 클래스, 구성원 변수, 방법 및 방법 매개 변 수 를 수식 할 수 있 습 니 다. final 수식 클래스 를 사용 하면 계승 할 수 없습니다. final 수식 방법 을 사용 하면 다시 쓸 수 없습니다. final 수식 변 수 를 사용 하면 한 번 만 할당 할 수 있 습 니 다.
final 선언 변수의 할당 시기 사용 하기:
1) 성명 을 정의 할 때 값 부여
2) 초기 화 블록 이나 정적 초기 화 블록 중
3) 구조 함수
다음 코드 보기:
class FinalTest
{
public static final String staticValue1 = "静态变量1";
public static final String staticValue2;
static
{
staticValue2 = "静态变量2";
}
public final String value1 = "实例变量1";
public final String value2;
public final String value3;
{
value2 = "实例变量2";
}
public FinalTest()
{
value3 = "实例变量3";
}
}
finally 는 보통 try... catch 와 함께 사용 하 는데 주로 자원 을 방출 하 는 데 사 용 됩 니 다.
다음 코드 를 살 펴 보 겠 습 니 다.
public class FinallyTest {
public static void main(String[] args)
{
finallyTest1();
finallyTest2();
finallyTest3();
}
private static String finallyTest1()
{
try
{
throw new RuntimeException();
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
System.out.println("Finally语句被执行");
}
try
{
System.out.println("Hello World");
return "Hello World";
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
System.out.println("Finally语句被执行");
}
return null;
}
private static void finallyTest2()
{
int i = 0;
for (i = 0; i < 3; i++)
{
try
{
if (i == 2) break;
System.out.println(i);
}
finally
{
System.out.println("Finally语句被执行");
}
}
}
private static Test finallyTest3()
{
try
{
return new Test();
}
finally
{
System.out.println("Finally语句被执行");
}
}
}
실행 결 과 는 다음 과 같 습 니 다.
java.lang.RuntimeException
at sample.interview.FinallyTest.finallyTest1(FinallyTest.java:16)
at sample.interview.FinallyTest.main(FinallyTest.java:7)
Finally语句被执行
Hello World
Finally语句被执行
Finally语句被执行
Finally语句被执行
Finally语句被执行
Test实例被创建
Finally语句被执行
순환 하 는 과정 에서 어떤 순환 에 대해 서 는 break 나 contine 을 호출 하 더 라 도 finally 가 실 행 됩 니 다.
finalize 는 주로 자원 을 방출 하 는 데 사용 되 며 GC 방법 을 호출 할 때 이 방법 이 호출 됩 니 다.
아래 의 예 시 를 보십시오.
class FinalizeTest
{
protected void finalize()
{
System.out.println("finalize方法被调用");
}
public static void main(String[] args)
{
FinalizeTest test = new FinalizeTest();
test = null;
Runtime.getRuntime().gc();
}
}
실행 결 과 는 다음 과 같 습 니 다.
finalize方法被调用
기본 유형 에 관 한 일 들
기본 유형 은 9 가지 로 나 뉘 는데 byte/short/int/long/float/double/boolean/void 를 포함 하고 모든 기본 유형 은 하나의 '포장 류' 에 대응 하 며 다른 기본 정 보 는 다음 과 같다.
. 基本类型:byte 二进制位数:8
. 包装类:java.lang.Byte
. 最小值:Byte.MIN_VALUE=-128
. 最大值:Byte.MAX_VALUE=127
. 基本类型:short 二进制位数:16
. 包装类:java.lang.Short
. 最小值:Short.MIN_VALUE=-32768
. 最大值:Short.MAX_VALUE=32767
. 基本类型:int 二进制位数:32
. 包装类:java.lang.Integer
. 最小值:Integer.MIN_VALUE=-2147483648
. 最大值:Integer.MAX_VALUE=2147483647
. 基本类型:long 二进制位数:64
. 包装类:java.lang.Long
. 最小值:Long.MIN_VALUE=-9223372036854775808
. 最大值:Long.MAX_VALUE=9223372036854775807
. 基本类型:float 二进制位数:32
. 包装类:java.lang.Float
. 最小值:Float.MIN_VALUE=1.4E-45
. 最大值:Float.MAX_VALUE=3.4028235E38
. 基本类型:double 二进制位数:64
. 包装类:java.lang.Double
. 最小值:Double.MIN_VALUE=4.9E-324
. 最大值:Double.MAX_VALUE=1.7976931348623157E308
. 基本类型:char 二进制位数:16
. 包装类:java.lang.Character
. 最小值:Character.MIN_VALUE=0
. 最大值:Character.MAX_VALUE=65535
기본 유형 에 대한 결론 (자바 면접 해 혹 에서 온 것) • 문자 접미사 표지 가 없 는 정 수 는 기본적으로 int 형식 이 고 문자 접미사 표지 가 없 는 부동 소수점 은 기본적으로 double 형식 입 니 다.
• 하나의 정수 값 이 int 형식 이 표시 할 수 있 는 범 위 를 초과 하면 접미사 'L' (대소 문 자 를 구분 하지 않 고 대문자 로 사용 하 는 것 을 권장 합 니 다. 소문 자의 L 과 아라비아 숫자 1 이 헷 갈 리 기 쉽 기 때 문 입 니 다) 을 늘 려 long 형 으로 표시 해 야 합 니 다.
• 'F' (대소 문자 구분 없 음) 접 두 사 를 가 진 정수 와 부동 소수점 은 모두 float 형식 이 고 'D' (대소 문자 구분 없 음) 접 두 사 를 가 진 정수 와 부동 소수점 은 모두 double 형식 입 니 다.
• 컴 파일 러 는 컴 파일 기간 에 byte, short, int, long, float, double, char 형 변수의 값 을 검사 하고 그들의 수치 범 위 를 초과 하면 오 류 를 보고 합 니 다.
• int 형 값 은 모든 수치 유형의 변 수 를 부여 할 수 있 습 니 다. long 형 값 은 long, float, double 형식의 변 수 를 부여 할 수 있 습 니 다. float 형 값 은 float, double 형식의 변 수 를 부여 할 수 있 고 double 형 값 은 double 형식 변수 에 만 부여 할 수 있 습 니 다.
기본 유형 간 의 전환 에 대해 아래 의 전환 은 무 손실 정밀도 의 전환 입 니 다.
• byte -> short • short -> int • char -> int • int -> long • float -> double 아래 의 전환 은 정밀도 손실:
• int -> float • long -> float • long -> double 은 이 를 제외 한 전환 은 불법 입 니 다.
날짜 와 관련 된 일 들 자바 에는 날짜 와 관련 된 두 가지 종류 가 있 습 니 다. 하 나 는 Date 이 고 하 나 는 Calendar 입 니 다. 아래 의 예 를 살 펴 보 겠 습 니 다.
public class DateTest {
public static void main(String[] args) throws ParseException
{
test1();
test2();
test3();
}
private static void test1() throws ParseException
{
Date date = new Date();
System.out.println(date);
DateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(sf.format(date));
String formatString = "2013-05-12";
System.out.println(sf.parse(formatString));
}
private static void test2()
{
Date date = new Date();
System.out.println("Year:" + date.getYear());
System.out.println("Month:" + date.getMonth());
System.out.println("Day:" + date.getDate());
System.out.println("Hour:" + date.getHours());
System.out.println("Minute:" + date.getMinutes());
System.out.println("Second:" + date.getSeconds());
System.out.println("DayOfWeek:" + date.getDay());
}
private static void test3()
{
Calendar c = Calendar.getInstance();
System.out.println(c.getTime());
System.out.println(c.getTimeZone());
System.out.println("Year:" + c.get(Calendar.YEAR));
System.out.println("Month:" + c.get(Calendar.MONTH));
System.out.println("Day:" + c.get(Calendar.DATE));
System.out.println("Hour:" + c.get(Calendar.HOUR));
System.out.println("HourOfDay:" + c.get(Calendar.HOUR_OF_DAY));
System.out.println("Minute:" + c.get(Calendar.MINUTE));
System.out.println("Second:" + c.get(Calendar.SECOND));
System.out.println("DayOfWeek:" + c.get(Calendar.DAY_OF_WEEK));
System.out.println("DayOfMonth:" + c.get(Calendar.DAY_OF_MONTH));
System.out.println("DayOfYear:" + c.get(Calendar.DAY_OF_YEAR));
}
}
출력 결 과 는 다음 과 같 습 니 다.
Sat May 11 13:44:34 CST 2013
-05-11
Sun May 12 00:00:00 CST 2013
Year:113
Month:4
Day:11
Hour:13
Minute:44
Second:35
DayOfWeek:6
Sat May 11 13:44:35 CST 2013
sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null]
Year:2013
Month:4
Day:11
Hour:1
HourOfDay:13
Minute:44
Second:35
DayOfWeek:7
DayOfMonth:11
DayOfYear:131
주의해 야 할 것 은 Date 의 getxxx 방법 이 deprecated 로 바 뀌 었 기 때문에 우 리 는 가능 한 한 calendar. get 방법 으로 날짜 의 세부 정 보 를 얻 습 니 다.
또한 DateFormat 에 주의 하 십시오. 날짜 의 출력 을 포맷 할 수 있 을 뿐만 아니 라 역방향 으로 조작 하여 Format 에 맞 는 문자열 을 날짜 형식 으로 변환 할 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.