2024. 8. 11. 20:49ㆍ■ JAVA REVIEW & PRACTICE/LECTURE1 - SPROUT
가볍게 자바 특징 리마인드하기
1. 독립성(호환성)
- JVM 메모리 영역 중 Runtime Data Area에 아래 세가지가 존재함
[Method Area] .class 파일 바이트코드가 여기에 도서관처럼 잘 정리되어 쌓임
[Stack Area] 메인에 있는 지역변수들과 호출한 메서드들을 순서대로 트래킹해서 넣고 빼주는 곳. 그래서 지역변수가 많아지면 그릇의 크기가 두꺼워지기도 함
[Heap Area] 객체 생성할 때 new 라고 쓴 객체들이 담기는 곳, 데이터 크기가 가변적으로 변하는 객체들이 들어감. 여기도 마찬가지로 크기가 각기 다름
2. 객체지향
- 모든것이 객체
ex) 커피(색깔,크기,재질 같은 것들의 속성들로 구성되어있음)
- 객체 == 클래스
코드 흐름을 트랙하기 전에 먼저 반드시 알고 있어야할 내용
- 재생버튼 누르면 소스코드(Main.java)가 자바컴파일러(javac)를 통해 컴파일이 되어 바이트코드(Main.class)로 변환되어 생성된 바이트코드를 JVM이 읽어서 프로그램이 시작되는 것 인지 먼저 하기
(바이트코드가 어디있는지 궁금하다면 Main class 파일을 선택하고 view에서 Show Bytecode 누르면 나옴-원본은 아님) - 지역변수(=Local Variable)와 전역변수(=Global Variable) 차이 알기
지역변수는 메서드 안에서 생성되고 메서드가 끝나면 얘도 사라짐, 다른 메서드는 이 지역변수를 알 수 없음
전역변수는 메서드 밖인 클래스 내부에 생성되고 모든 메서드들이 자유롭게 사용가능, 프로그램 끝날때 까지 살아있는 변수
// 지역변수 예
void 인사하기() {
String 이름 = "Alice"; // '이름'은 지역변수
System.out.println("안녕, " + 이름);
}
// 전역변수 예
class 인사 {
String 이름 = "Alice"; // '이름'은 전역변수
void 인사하기() {
System.out.println("안녕, " + 이름);
}
void 이름바꾸기() {
이름 = "Bob"; // '이름'이라는 전역변수를 다른 메서드에서 사용하고 있음
}
}
- 매개변수(Parameter)에 대해 정확히 알고가기 (형식 매개변수/ 실제 매개변수)
아래 챗지피티에서 설명한 매개변수의 정의 다시 읽어보기
- { } -> 이 중괄호(스코프) 안에서는 이 스코프 안에 있는 것들만 찾을 수 있음.
보통 함수 선언을 클래스에서 하게되는데 메인메서드에서 클래스에 선언된 함수를 부를 때(호출할 때) 에는 당연히 그 함수가 클래스에 없기에 호출을 해서 불러와야함. 이 때 호출은 객체이름(주머니)를 부르고 그 주머니 안에서 원하는 메서드 이름을 쩜 연산자를 통해 이어서 불러오면 됨. 그리고 클래스안에 있는 메서드에서 그 클래스 안에 있는 다른 메서드를 불러올 때는 같은 스코프안에 있기에 메인메서드에서 따로 객체이름.함수이름(); 의 형태를 호출하지 않아도 되고 그 클래스 안에 있는 메서드 스코프 안에서 그냥 함수이름(); 만 해주면 됨. 같은 스코프 안에 있으니까!
- 메소드는 크게 선언과 호출로 나뉨
선언한 메서드의 반환값은 부른 호출에게로 감
메서드 선언 | 메서드 호출 (선언한 메서드를 사용하기 위해 호출을 하는 것) |
반환자료형 함수이름 ( ) { 리턴값(=반환 데이터); -> 이부분은 있을수도 없을수도 } 또는 반환자료형 함수이름 ( 매개변수1, 매개변수2 ... ) { 메서드 내용; 리턴값(=반환 데이터); -> 이부분은 있을수도 없을수도 } |
함수이름 ( ); 또는 함수이름 (매개변수1); 또는 반환자료형 반환한값넣고싶은 속성이름 = 객체이름.함수이름 (넣고싶은값); System.out.println("노트: " + 반환할 값 넣고싶은 속성 이름); |
int add ( ) { return ret; } 또는 int add (int a, intb) { int ret = a + b; return ret; } |
add ( ); 또는 add (1,2); 또는 int ret = objectName.methodName(2); System.out.println("현재 값: " + objectName); |
아래 작성된 코드의 번호(라인)와 설명 함께 따라 읽어보며 흐름 익히기
- #37: 자바는 프로그램이 실행될 때 가장 먼저 호출되는 main method 부터 시작인걸 인지하고 있기
- #4: 메인메소드 스코프(중괄호) 안에 말고 그 위에 클래스 하나 만들어주기
그리고 Adventurer 클래스의 스코프안에 이 클래스와 관련된 속성들
(우선 static, public 깊게 알려고하지 말고 따라서 써보기)
static class 클래스이름 {
} - #5,6,7: 변수를 사용해서 속성 만들어주기(=선언하기) -> 이름, 나이, 남은식량 갯수
데이터타입 변수이름 = 값; - #41: Adventurer 클래스 소환하기(=객체를 초기화 또는 생성한다고도 말할 수 있음)
이때 Adventurer 클래스를 소환하기 위해선 Adventurer 객체를 생성하고 'new' 라는 키워드 반드시 객체 앞에 작성
그리고 이 객체를 Adventurer 클래스라는 주머니에 담아주고 옆에 이름 지어주기
클래스이름 이클래스에있는모든값을담아줄객체의 이름(주머니) = 초기화/생성 한다는의미의 new키워드작성 클래스이름과같게객체생성 - 이제 Adventurer 의 행동을 정해줄거라 1.식량조회 메서드를 넣을거임 (=선언하기)
#10: 리턴을 해야할지 말아야할지 모르면 반환자료형이 무엇일지 모르니 void라고 먼저 적어주고 이름 지어주기
작성하고 보니 food의 값을 반환해야 하는걸 알 수 있어서 return food; 이라고 적고 갯수를 말하는거니까 void를 int로 바꿔주기
데이터타입 식량조회에알맞는이름지어주기() {
반환 이값을어느주머니에넣어줄지;
} - #44: 이제 호출해야하는데 Adventurer 클래스의 gygim이란 이름을 가진 주머니에(새싹,18,0이 담겨있음) 나중에 꺼내 쓰려고 담아놓았으니 gygim을 먼저 불러주고 쩜 연산자를 통해 접근하여 식량조회 메서드를 가져오기 (=호출하기)
그리고 이 값을 food에 다시 넣어줘야 하니 food의 반환값을 숫자로 나타낼거라 int 데이터타입을 적어줌
데이터타입 값을담아줄주머니이름 = 클래스의이름.클래스안에선언된메서드의이름(); - #46: 현재 가지고 있는 식량의 갯수를 알아보기 위해 호출된 메서드의 결과를 출력해야하니 메모를 "현재 식량: " 이라고 적어 프린트하고 재생눌러보기 (아래 0의 값을 확인할 수 있음)
System.out.println("보여줄노트" + 값이담긴주머니이름); - #15: 식량 추가 메서드 만들어보기(=선언하기) 일단 데이터타입이 뭔지 모르니 void 적고 이름 addFood 지어주기
더해진 식량의 값을 food 에 또 넣어줘야 하는데 이때 우리는 '매개변수'를 활용할 수 있음
매개변수는 필요할 때 넣어주는 됨. 여기서는 추가된 식량의 양을 확인하고 싶은거라 int amount 라고 매개변수 적어줌
그리고 이 받은 값을 다시 food 에 넣어줘서 계속 업데이트 가능 하지만 여기서 return을 쓰지 않았으니 호출했을 때 다시 돌려받지 않고 그냥 값만 저장한것이라고 생각하면 됨
여기서 return을 안써준 이유는 우리가 이미 위에서 조회할 때 return을 시켰는데 여기도 return을 쓴다면 값도 더해주고 조회까지하게되어 이 메서드는 2가지 일을 하게되는거라 이것은 별로 선호되지 않음. 메서드는 한가지 일만 하게 해주는 것이 바람직
둘의받은값을넣어줄주머니 = 현재값이저장되어있는주머니이름 + 매개변수이름; - #49: 식량 추가 메서드 부르기(=호출하기)
식량추가 메서드가 담긴주머니 gygim 에 Adventurer 객체 (=Adventurer 클래스 안에 있는 속성들) 를 넣어주었으니
객체주머니(이름 gygim)에서 쩜으로 속성들에게 접근하기
주머니.들어갈메서드이름(넣고싶은 식량의 수 넣기); - #51: 추가된 값 맞게 잘 들어갔는지 식량조회 메서드 부르기 (=호출하기)
우선 접근해야하니까 객체주머니(이름 gygim) 입력하면 이 안에 들어있는것들이 쭉 나오는데 getFood 엔터쳐주고 이 메서드의 반환자료형이 뭔지 확인하고 int 를 넣어줌. 그리고 이름은 업데이트 된 식량의 양을 보여주는거니까 거기에 맞게 updateFood 적기
여기서 중요하게 알아야 할 점은 2개를 addFood에 넣어줬고 현재 addFood 메서드를 가보면 food = food + amount; 인걸 확일할 수 있음 결국 현재 food는 2가 저장되어 있는데 #51에 보면 getFood에 있는 값을 updateFood 라고 해준다고 했으니 getFood 메소드를 가보면 food의 값을 리턴하라는걸 보여줌. 그래서 결론은 food의 값을 리턴하라는 것과 같음. 우리 눈에는 안보이지만 자바가 뒤에서 계속 계산하고 저장해놓고 본인의 할일을 하고 있는 중임.
데이터타입 변경된값을저장할변수의이름 = 객체이름.객체의 속성 중 선언된 메서드 중에 가져올 메서드의 이름( ); - #52 업데이트된 식량 프린트하기
System.out.println("업데이트 된 식량: " + 값이 저장되어있는 객체의 속성의 이름); - 이제 위에 설명으로 인해 어느정도 흐름을 따라갈 줄 알게 되었으니 아래부터는 간단하게 작성해보기
- #20,21,23 explore에 대한 메서드 선언 후 출력문
- #55 explore에 대한 메서드 호출
- #27-34 explore 메소드 안에서 선언할 요구사항 들어간 함수 작성해주기
- #22 메서드 안에서 doSomething 메서드 호출하기
- #23 doSomething 메서드 모두 실행 되었으니 그 다음 순서인 23번이 실행 되는 것
- #55번 처럼 #56,57 두번 더 호출하였으니 두번 더 반복
- #59 마지막으로 호출된 메서드이기까지 가서 getFood 메서드로 이동해보면 return food를 하라고 하니 결국 계속 업데이트 되었던 food 의 값들의 최종값이 출력이 됨
코드 흐름을 알아보고 싶을 때 강추하는 툴
주소에 uwaterloo 라고 써져있는데 waterloo 대학교 졸업한 학생이 만든건가? 너무 감사한 프로그램! 덕분에 이해가 가능해졌다 알려주신 기용튜터님께 너무 감사하다. 이걸 진작에 알았더라면 코드의 흐름을 알기까지 소요된 시간들을 아낄 수 있지 않았나 싶다.
https://cscircles.cemc.uwaterloo.ca/java_visualize/
Java Visualizer
Write your Java code here: args: +command-line argument stdin (also visualizes consumption of StdIn) x <!-- Execute code using Python 2.7 Python 3.3 , --> <!-- these two make sense, but are not implemented yet hide frames of exited functions show frames of
cscircles.cemc.uwaterloo.ca
Frames: 메모리 스택area 에 들어가는 애들을 보여주는 곳
Objects: 메모리 힙area 에 들어가는 애들을 보여주는 곳
Program output: intelliJ에서 콘솔창과 같은 곳
'■ JAVA REVIEW & PRACTICE > LECTURE1 - SPROUT' 카테고리의 다른 글
final 과 불변객체 그리고 String( ) (0) | 2024.08.12 |
---|---|
동등성과 동일성의 차이 (0) | 2024.08.12 |