자료형과 메모리
- 기본자료형 && 지역변수 -> 스택에 저장됨, 자동으로 초기값이 설정되지 않음.
- 기본자료형 && 멤버변수/정적변수 -> 아직 안함
- 참조형 -> 값은 힙메모리에 저장됨
- 기본자료형이라도 참조형이면 자료형에 따라 자동 초기화
- 클래스들도 필드들이 자동 초기화됨
new 연산자
- String 클래스를 제외한 클래스, 배열, 인터페이스는 필수적으로 new 연산자 사용함
- 힙에 새로운 공간을 형성하라는 표시
참조형
- 클래스, 배열, 인터페이스, 열거타입(잘 쓰지 않음)
- 값이 힙메모리에 저장됨, 그 값이 저장된 영역의 시작주소를 스택메모리에서 가짐
- 힙메모리 : 동적으로 계속 공간을 늘릴 수 있는 특징
메모리 영역
- 스택 메모리 영역
- 힙 메모리 영역
- 메소드 메모리 영역
참조형
+ 인터페이스(자료구조)
- 대표적인게 List
배열 정리
- 동일한 자료형만 저장가능한 정적인 자료구조
- 정적 자료구조 = 크기가 딱 정해져 있음. new int[3] 하면 딱 3개만 생성
- 배열이름.length 속성 : 배열의 크기 = 배열 방의 개수
배열 매개변수 예시1
- 메소드의 매개변수가 기본자료형이 아니라 참조형 중 배열일때
public static void main(String[] args) {
int[] scores; // 여기 int[] scores ; 는 아직 주소를 가지지 않은 상태
scores = new int[] { 83, 90, 87 };
// int[] scores = new int[] {83,90,87}
int sum1 = 0;
for (int i = 0; i < 3; i++) {
sum1 += scores[i];
}
System.out.println("총합 : " + sum1);
// add 메소드를 호출해서, 리턴된 총합을 sum2에 저장
int sum2 = add(new int[] { 83, 90, 87 });
System.out.println("총합 : " + sum2);
} // main() end
// 사용자 정의 메소드 : 합을 구해주는 메소드 : 배열을 매개변수로
public static int add(int[] scores) {
int sum = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
}
return sum;
}
- int[] scores 는 주솟값을 가지지 못한 형태다
- 메소드의 매개변수가 참조형 중 배열이다.
- 이땐 배열의 주솟값을 전달해야함
- Call by Reference 방식으로 호출해야한다.
- 이 int 형 배열의 주솟값을 전달하자
- 매개변수자리에 클래스, 배열, 인터페이스 다 올 수 있다.
배열 매개변수 주의(위 예제의 부분)
public static int add(int[] scores) {
int sum = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
}
return sum;
}
public static void main(String[] args) {
int[] scores; // 여기 int[] scores ; 는 아직 주소를 가지지 않은 상태
}
- main의 int[] scores 는 주솟값을 가지지 못한 형태다
- new 연산자를 써야만 새로운 공간을 힙메모리에 할당받는데 아직 안썼으므로
아직 주솟값이 없는 상태
- add함수로 전달하는 건 주솟값을 전달해야함 = Call by Reference
public static void main(String[] args) {
int sum2 = add(new int[] { 83, 90, 87 });
}
- 이 경우엔 리턴받는게 없으니 이 공간은 재사용을 못한다
- 이렇게 해서 new를 써서 add 메소드로 주솟값을 전달함
- 힙 메모리 상에 있는 "같은 자료형 "(여기선 int형) 배열의 주솟값을 전달해야함
- new를 쓸때마다 새 공간이므로 이 sum2가 가리키는 new의 공간이랑 맨 위에 scores 이 가리키는 공간은 다른 주소이다
- 힙메모리상에 불필요하게 공간을 사용하는건 Garbage Collector 프로그램이 주소를 전달한 뒤 자동으로 지워버림 = 재사용 불가
+ 값 전달하는거보다 주솟값을 전달하는게 처리가 빠르다
+ C언어에선 이걸 포인터로 전달함
참조형인 매개변수 정리
- 주솟값을 할당받기 위해선 반드시 new 연산자가 있어야함
- String s= "자바" 가 가능하므로 String s 가 매개변수로 올때만 예외적으로 바로 check("자바") 로 호출 가능
- 또는 String s = new String("파이썬") 도 가능하므로 check(new String("파이썬") 으로 호출해도 된다.
- 다른 참조형 변수는 99% new를 써야함
메소드 정리
- 메소드 앞에는 return 자료형이 반드시 와야함
- 정적메소드이기 때문에 클래스명.add 또는 같은 클래스 내에선 .add 로 생략하고도 쓸수있다
- 정적메소드 아니면 객체를 생성후 호출해야한다.
배열 초기화 정리
- int뿐아니라 정수형 배열들은 다 0 으로 초기화 됨(char제외)
- 실수는 float 는 0.0f double 은 0.0
- 클래스/인터페이스/배열은 null로 초기화
* null : 주솟값이 없다는 의미
확장 for문 = 향상된 for문
- 순차적인 자료구조인 배열, 리스트같은 곳의 원소를 끄집어낼때 사용함
- 배열에 있는 값을 원소값이 더이상 없을떄까지 하나씩 왼쪽의 변수로 옮김
- 간결하기때문에 자주 씀
for( 타입 변수 : 순차적인 자료구조(배열,컬렉션)) {
실행문 ;
}
* 타입변수 : 전달 받을 값
* 컬렉션 = 자료구조(여기선 순차적인 자료구조를 의미), 대표적인게 리스트
확장 for문 예제
int[] score = { 95, 71, 84, 93, 87 };
// 확장 for문
int sum1 = 0;
for(int s : score) {
sum1 += s;
}
- 값을 받는 변수 s 도 배열의 자료형과 같은 int 형으로 받아야함
- score 배열에 들은 원소(값)들을 왼쪽의 s변수에 하나씩 전달, 이걸 원소값이 없을때까지 반복한다
- 전달된 값을 sum1 변수에 누적
+ 순차적인 자료구조 :List, Vector
+ stack은 순차적인 자료구조 아님 다른 방식
main 메소드의 매개변수
- public static void main(String[] args){}
- JVM에서 여태껏 main 실행할때 아무 값 전달하지 않았음
- 하지만 전달 할 수도 있다.
- 전달시 args[0]에 첫번째 값이, args[1]에 두번째 값이 들어감
- String 자료형이므로 숫자를 적어도 문자로 처리됨
main 메소드의 매개변수 활용
package p2022_06_27;
public class ArrayEx07 {
// 절대값을 구해주는 메소드
static int abs(int data) {
if (data < 0)
data = -data;
return data;
}
public static void main(String[] args) {
// args[0] = "-10", args[1] = "-20"
System.out.println("args[0] : " + args[0]);
System.out.println("args[1] : " + args[1]);
// args[0] = "-10" ---> -10 : 형변환(int로)
int num = Integer.parseInt(args[0]);
System.out.println("절대값 : " + abs(num));
}
}
- 이 코드를 그냥 실행시 오류
- main 메소드 통해서 값을 전달할땐 그냥 실행시 오류가 생김
- 실행시키는 방법이 다름 ! (자주 쓰는건 아니지만 알아두기)
이클립스로 실행법
1. RUN 초록 화살표 버튼 마우스 대고 있으면 Run Configuration 메뉴 잇다
2. 두번째 탭인 arguments 선택
3. 위칸 program arguments 에서 -10 -20 을 입력(뛰어쓰기로 args[0] args[1] 값 구분)
- args[0]에 -10, args[1]에 -20 이 전달됨
- (-10)을 써도 String[] 이 매개변수이므로 문자인 "-10" 인것임
+이클립스가 아닌 콘솔창 자바 가상머신에서 실행시
java ArrayEx07 -10 -20
- 이렇게 실행함
의미 설명
1. java : 자바 가상머신 JVM
2. ArrayEx07 :ArrayEx07.class 란 바이트 코드를 실행함
3. -10 -20 이렇게 구분해서 입력
- args[0]에 -10, args[1]에 -20 이 전달됨
- (-10)을 써도 String[] 이 매개변수이므로 문자인 "-10" 인것임
자료형 변환
- 형변환된 값을 abs 메소드에 전달해야하는데 abs는 매개변수가 int 형이므로 그래서 문자를 숫자로 일단 변경하고 메소드 호출해야함.
-이걸 절대값 구할때는 args[]에 들은 데이터는 String은 문자열 이므로 int 로 바꿔야함
- "-10"을 숫자 -10 으로 바꿀땐
int num = Integer.parseInt(args[0]); // 자주씀 외우기
- 자바의 3가지 자료형 변환 중 두번째 자료형 변환 방법임
Wrapper 클래스 (자료형 변환 원리)
- 기본자료형마다 Wrapper 클래스가 있다 .
- Integer 는 int 의 wrapper 클래스임
- 그래서 Integer.parseInt("20") 을 사용해서 문자 20을 숫자 20으로 변환
- Wrapper 클래스를 쓰면 기본자료형과 참조형 사이의 자료형 변환이 가능하다 (ex) string <-> int)
- 모두 java.lang 패키지안에 있어서 import 필요없다
- Wrapper 클래스 쓰면 다른 자료형으로 쉽게 변환 가능
Wrapper Class
- boolean 은 Boolean
- byte 는 Byte
- char 은 Character
- int는 Integer
Wrapper 클래스를 이용한 변환 방법 2가지
1.
int num = Integer.parseInt("20")
- pasreInt는 정적메소드라서 따로 객체 생성없이 클래스명. 으로 호출 parse() 안에는 String 자료형
2.
Integer in01 = new Integer("20");
int num01 - int01.intValue();
- 언박싱
wrapper클래스의 주요 2가지 기능
1. String -> int (이게 거의 대부분임)
2. int -> String ex) String s - String.valueOf(20);
Integer 클래스 구조 (api 문서)
java.lang.Object
java.lang.Number
java.lang.Integer
- 최상위 클래스 = 슈퍼클래스는 Object
- 부모 클래스는 Number
- 상속 관계가 이미 다 형성되어있다.
1. Integer 의 필드(변수, 상수 의 개념)
- MAX_VALUE 쓰면 int형 변수가 가질 수 있는 최대값을 구해줌(정적필드) 약 +21억
- MIN_VALUE 스면 int형 변수가 가질 수 있는 최솟값을 구해줌
2. Integer 의 생성자
- 2개뿐
3. Integer의 메소드
- 메소드 중 pasreInt 는 2개가 있다 = 메소드 오버로딩
* 메소드 오버로딩 에서 이름은 같아도 매개변수등 구분이 되어야 잘 사용한것
- parseInt (String s) : 우리가 쓴 메소드 . 타입은 static int다 정적메소드이므로 Integer.parseInt로 사용하고, int 형 변수에 결과를 저장해서 돌려줌 매개변수 안엔 String 형만 들어가야함
- parseInt (String s, int radix) 도 있다.
+ 오라클등의 DB 연동할때 java.lang.Class 클래스 사용
배열을 복사하기
- 여러 방법 있다
1. for문
2. System.arrayCopy() 메소드
3. Arrays 클래스 이용
for문으로 배열 복사하기
public class ArrayEx08 {
public static void main(String[] args) {
//p167~p168
//배열 복사 : for문으로 배열 복사
int[] oldArray = {10,20,30}; //원본 배열
int[] newArray = new int[5]; //새로운 배열
for (int i = 0; i < oldArray.length; i++) {
newArray[i] = oldArray[i]; //배열 복사
}
//복사된 배열 출력
for(int i : newArray) {
System.out.print(i + "\t");
}
}
}
- newArray는 배열이므로 0으로 다 초기화 된 상태
- oldArray -> newArray 로 복사할때 for문돌아가면서 10이 newArray[0] 으로 20이 newArra[1]으로 30이 newArray[2]로 복사됨
- 한줄 엔터키를 안쓰고 그냥 띄우기나 \t를 쓸때는 println이 아니라 print인점 주의
위 예제 그림
2차원 배열 정의방법 2가지
1.
int[][] score = new int[5][3];
- 메모리상에 값 저장위한 기억공간만 생성하고 그 값이 아직 뭔지 모를때 사용
- 2차원배열은 [][]처럼 2개임, [][]가 score 뒤에 가도 됨
- new란 연산자를 쓰는 형식
- 왼쪽, 오른쪽 자료형 같은걸로 맞추기
- 첫번째 괄호에 들어가는건 행의 수 (가로방향)
- 두번째 괄호에 들어가는건 열의 수 (세로방향)
- 4바이트짜리 기억공간을 행 5, 열 3으로 15개 생성하라는 뜻. 5행 3열짜리 기억공간 생성
그림
2.
int[][] score = {{0,0,0},{0,0,0},{0,0,0}};
- 값이 고정되어있을때 쓰는 방식
예시
int [][] score = { { 85, 60, 70}, //0 행
{ 90, 95, 80}, //1 행
{ 75, 80, 100}, //2 행
{ 80, 70, 95}, //3 행
{100, 65, 80} }; //4 행
- 0행 0열에 85, 4행 2열에 80이 들어감
2차원 배열 인덱스
- 행 = row = 가로번호
- 열 = colume = 세로번호
- 행 번호는 가로번호 의미
- 배열에 인덱스는 0번부터니까
배열 인덱스 예시
score[0][0] = 85; //0행0열에 85점을 할당하라
score[4][2] = 80; //4행2열에 80점을 할당하라
2차원 배열 입력/출력
public class Arr04 {
public static void main(String[] args) {
int [][]score = { { 85, 60, 70}, //0 행 = 1번학생
{ 90, 95, 80}, //1 행 = 2번학생
{ 75, 80, 100}, //2 행 = 3번학생
{ 80, 70, 95}, //3 행 = 4번학생
{100, 65, 80} //4 행 = 5번학생
};
int [] subject = new int[3]; //과목총점 저장할 1차원 배열
int [] student = new int[5]; //학생의 총점 저장
// subject[0]=0, student[0]=0;
int r, c;
System.out.println("각 과목별 총점구하기 "); //열방향으로 다 합쳐야
for(c = 0; c < 3 ; c++){ // 과목
for(r = 0; r < 5 ; r++){ //학생
subject[c] += score[r][c];
}//subject[c]=subject[c]+score[r][c];
System.out.println(subject[c]);
}
System.out.println("학생별 총점구하기");
for(r = 0; r < 5 ; r++){ //학생
for(c = 0; c < 3 ; c++){ //과목
student[r] += score[r][c];
}//student[r]=student[r]+score[r][c];
System.out.println(student[r]);
}
}//main() end
}// class end
- 행 열을 따로 처리해야하므로 중첩 for문을 쓴다
- 행번호는 0~4이기 때문에 for문으로 0부터 시작해서 <5까지 즉 4까지 함, == 학생수는 5명
- 그 학생 당 과목 성적을 위해서 안쪽 for문으로 0부터 2까지 3번 돌림 == 과목수 3개(국영수)
- 행과 열이 만나는 곳의 점수를 출력하면 score[row][col]
- 더 빨리 바뀌는 부분이 for문의 안쪽에 와야함 나중에 움직이는 부분이 바깥쪽에
- 과목 총점 구하기는 [0][0] [1][0] [2][0] ... 을 더해야하고 ->과목은 열이기 때문에 for문 안쪽에 r 가 와야함
- 학생별 총점 구하기는 [0][0] [0][1] [0][2] ... 를 더해야함 -> 학생은 행이기 때문에 for문 안쪽에 c가 와야함
- int [] subject = new int [3] 이나 int [] student = new int[5]; 는 자동초기화 0 이므로 sum = 0 같은
번거로운일 할 필요 X
객체지향언어
클래스
- 클래스도 자료형이다
- 배열과 메모리상 처리는 거의 비슷함
String 클래스
- 클래스 중에서 쉽게 이해할 수 있는 String 클래스로 예시들어서 설명
- 클래스 중 사용빈도 가장 높음
String 클래스와 메모리
- String 클래스로 String 객체를 만든다
- 객체를 만들면 배열과 마찬가지로 문자열 " " 들은 모두 힙메모리상에 저장됨(참조형이 가지는 공통적인 특징)
- 그 메모리의 시작주소값을 변수가 스택에서 가지고 있다
String name;
name = "신용권"
- 그냥 이름을 저장하는것같아 보이지만 "신용권"은 힙의 공간에 저장, 그 주소를 가진 name은 스택에서 주소를 가지고 있다.
String 클래스와 메모리2
- String 클래스의 경우에는 문자를 바로 할당해도 되고 new 연산자를 사용해도 된다
- 이 두가지 되는건 String 밖에 없다
- 보통의 클래스는 new 연산자를 써서만 객체 만들어야함
- 하지만 new 연산 썼을때와 쓰지 않았을때 메모리에 차이가 있다.
String name1 = "신용권";
String name2 = "신용권";
- new 연산자를 쓰지 않고 만들면 처음 한번은 "신용권"을 저장한 기억공간을 힙메모리에 만듬
- 두번째의 경우에는 새로운 공간 만들지 않고 이미 "신용권"이 저장된 공간의 주솟값을 리턴받음
- name1 == name2 주솟값이 같다
String name1 = new String("신용권");
String name2 = new String("신용권");
- new 연산자를 쓰면 매번 새로운 공간을 힙메모리에 생성하라는 명시적인 표시
- new 연산자를 2번 썼기 때문에 새로운 공간이 2번 만들어짐
- 그림을 보면 힙 메모리상에 공간이 따로 따로 만들어짐
- name1 != name2 주소가 다르다
참조형의 비교
- 참조형들은 비교대상이 2개다
- name1 == name2 처럼 비교연산자로 주솟값을 비교
- equals() 란 메소드로 값들끼리 비교
주솟값 비교 예시
String str1 = "자바";
String str2 = "자바";
if (str1 == str2) { //비교연산자(==)로 참조하는 주소를 비교
System.out.println("같은 주소"); //같은 주소
} else {
System.out.println("다른 주소");
}
String str3 = new String("자바");
String str4 = new String("자바");
if (str3 == str4) { //비교연산자(==)로 참조하는 주소를 비교
System.out.println("같은 주소"); //같은 주소
} else {
System.out.println("다른 주소");
}
- 비교연산자(==)로 참조하는 주소를 비교
그림
값 비교 예시
if(str1.equals(str2)){ // 참조하는 값(데이터)을 비교
System.out.println("같은 값"); //같은 값
}else {
System.out.println("다른 값");
}
- 값비교 equals() 메소드를 사용
- 같으면 true를 반환
참조형의 비교 정리
- 비교연산자(==) : 참조하는 주소를 비교
- equals() : 참조하는 값(데이터)을 비교
+ 메소드를 찾는 법
ex) equals() 메소드를 어디서 찾아야할까
1. 1차적으로 api에서 equals() 메소드가 어디 붙어있는지 보자 -> String
2. String클래스 찾아야
3. String클래스 안에 없으면 그거 조상들 클래스를 찾아야
- String의 경우엔 부모가 java.lang.Object가 최상위 클래스 , 자기 부모 클래스 임.
- String 안에 없더라도 조상이 그 메소드를 가지고 있으면 상속 받아 string 객체에서도사용할 수 있다.
- 만약 String클래스도 String의 부모클래스에도 equals()없다면 그건 없는 것임.
+ 클래스 구조
- 필드 1개 있고 생성자있다
- 생성자 : 객체를 생성할때 자동으로 호출되는 메서드, 클래스와 같은 이름이다.
String 클래스 구조 생성자
- 우리는 매개변수가 String으로 된 생성자를 호출해왔었음 String(String original) 을 써왔던것
String str3 = new String("자바")
- 에서 오른쪽은 String은 생성자를 호출하는 것임
- 생성자는 없으면 못씀 제공되는것만 쓸 수 있다
String 클래스 구조 메소드
- String 클래스 안 메소드 많다(기능 많다 )
- equals() 메소드의 리턴타입은 boolean, 값이 같으면 true, 다르면 false를 리턴해줌
- 그래서 이 메소드 자체를 if문 안에 넣었던 것
Object 클래스와 equals()
- equals() 메소드의 매개변수는 Object
- 자바의 가장 최상위 클래스가 Object임 = 슈퍼클래스= 최상위 부모 클래스
- 패키지가 엄청 많지만 그게 뭐든지 가장 위는 Object
- 즉, Object 는 모든 클래스의 최상위 부모, 조상
- equals() 메소드 매개변수가 equals(Object anObject)
- 값을 비교할때 Object의 자식들은 다 equals 안에 들어갈 수 있다. 모든 클래스 다 들어갈 수 있다.
- 즉, equals() 괄호 안에 int, boolean, String등 다 들어갈 수 있다
- String뿐만 아니라 Object의 자식들은 모두 비교 equals로 비교가능, 즉 모든 자료형 다 비교 가능
예시1
boolean b = "자바".equals("파이썬");
if(b) {
System.out.println("같은 값");
}else {
System.out.println("다른 값");
}
- 가능함
- 3번째 자료형형변환 방법, 레퍼런스 관련이 있다
예시2
if(new Integer(30).equals(30)){
System.out.println("같은 값");
}else {
System.out.println("다른 값");
}
- int형끼리 비교도 가능하다.
- int, double, boolean 등 모든 걸 equals 로 비교 가능
- wrapper 클래스 , 오토박싱,오토언박싱 등의 개념 앞으로 공부하는것과 연관
객체배열
- 객체의 주소를 참조하는(저장하는) 배열
- C++은 많이 쓰지만 String은 많이 쓰진 않음 객체배열보다 성능 좋은 list등이 있기 때문에
ex) String객체를 3개 저장하기 위한 배열 = 객체배열
String[] strArray = new String[3]; // 객체배열
strArray[0] = "Java";
strArray[1] = "Java";
strArray[2] = new String("Java");
- 이렇게 객체 생성시시에 2가지 방법 써서 가능
- 0번방, 1번방 가리키는 "Java"는 같은 곳임
- 0번방, 2번방 가리키는 "Java"는 서로 다른 곳음
System.out.println(strArray[0] == strArray[1]); //주소값을 비교, true
System.out.println(strArray[0] == strArray[2]); //주소값을 비교, false
System.out.println(strArray[0].equals(strArray[2])); //값을 비교, true
사용자 정의 클래스
- String 클래스와 비슷한 방식으로 메모리상 처리가 됨
객체 지향 프로그래밍(OOP)
- 부품 객체를 먼저 만들고 이것들을 하나씩 조립해 완성된 프로그램을 만드는 기법
객체
- 물리적으로 존재하는 모든게 객체가 될 수 있다 ex) 자동차, 사람, 책
- 추상적인 것도 객체가 될 수 있다 ex) 회사, 날짜
- 현실세계에선 사람이란 객체가 있을때 사람에 대한 속성이 있다 ex)나이, 이름 => 속성
- 사람이란 객체가 있을때 있는 동작 ex) 달린다, 걷는다 => 메소드
객체 모델링
- 자바같은 객체지향언어에선 객체 모델링이란 작업을 수행한다
- 사람이란 객체의 속성을 표현할때는 '필드'라는걸가지고 속성을 나타남
- 메소드 바깥쪽에 쓰는 변수 = 멤버변수 = 필드 변수 = 객체의 속성 나타냄
- 메소드를 가지고 객체의 동작을 표현함
현실세계의 자동차 객체
- 필드를 가지고 객체의 속성에 대한 것들을 표현
- 속성 : 색상, 속도 -> '필드' 로 표현함, 필드는 쉽게 말하면 멤버변수임
- 필드는 메소드 바깥쪽에 정의되는 변수로서 멤버변수라고 불린다. 자바에선 필드라고 불림
- 동작 : 메소드를 가지고 표현. 달린다 멈춘다 등의 동작을 메소드로 표현
객체 지향 프로그래밍이 가지는 특징
1. 캡슐화
- 한개의 클래스가 만들어져 있을때 외부클래스에서 접근하지 못하도록 캡슐로 보호를 한다.
- 캡슐화위해선 접근제어자로 접근을 허용을 하기도하고 허용을 하지않기도 한다.
ex) private 써서 외부로부터 접근 막음 = 캡슐화로 안전하게 안의 정보를 보호함
2. 상속
- api에서 제공되는 클래스는 이미 상속관계 정의 다 된 상태임.
- 상속을 함으로서 중복적인 코드를 많이 줄일 수 있다
- 또 유지보수를 편리하게 해주는 기능을 제공하기때문에 상속을 많이 사용함.
ex) 부모 클래스가 있고 자식 클래스가 있을떄
- 클래스 = 필드, 메소드, 생성자 로 구성
- 상속이 되는건 2가지 뿐! 필드와 메소드만 상속이 되고! 생성자는 상속되지 않음!
3. 다형성(Polymorphism)
- 부모로부터 상속받은 것들을 다양한 형태로 바꿔서 쓴다는 것
객체와 클래스
- 설계도 역할을 하는게 클래스다
- 현실세계 : 설계도 -> 객체 를 만들어냄 (ex)설계도로 자동차를만들어냄)
- 자바 : 클래스 -> 객체. 설계도역할하는게 클래스, 클래스 가지고 객체를 무한히 많이 만들어 낼수 있다.
클래스 이름
- 하나이상의 문자로 이루어져야
- 변수명과 마찬가지로 첫번째 글자는 숫자올수없다 ex) Car 3Car (x)
- $나 _ 외의 특수문자 사용불가
- 자바 키워드는 사용할 수 없다
- 변수명,함수명,클래스명등은 한글명으로 클래스 명 쓰는건 바람직하지 않다. 웹으로 가면 여러 문제 발생!
클래스와 소스파일
- 이클립스에서 클래스를 만들면 소스파일이 생성됨 클래스이름.java 가 생성됨
- 이걸 javac.exe가 컴파일 해줘서 클래스이름.class 생성됨
- 앞으로는 한개의 .java 파일에 클래스가 여러개가 들어가는 소스파일 .java 을 만들것
- 소스 파일 당 public class 는 1개만 사용가능함! 이 public 을 가진 클래스와 파일명을 일치시켜야함
- 클래스명과 파일명이 일치되어야하는데 단, 이때 메인메소드를 가진 클래스명과 파일명을 일치 시켜야함
- 컴파일이 되면 파일 안의 여러개 클래스가 각각 따로 따로 .class 파일들로 만들어짐(클래스 수만큼)
객체 생성
new 클래스();
- 클래스와 동일한 이름의 생성자를 호출하라는 코드
- 생성된 객체는 힙메모리상에 객체가 생성됨
- new 연산자는 객체를 생성후 객체 생성 주솟값을 리턴하므로, 왼쪽의 변수가 그 주솟값을 갖고있게됨
객체 생성 방법 2가지
1.
클래스 변수;
변수 = new 클래스();
2.
클래스 변수 = new 클래스();
- 한줄
클래스 구성 멤버와 역할
- 필드 : 변수기때문에 메모리상의 값을 저장하는 역할
- 생성자 : 객체가 생성시 호출되며 필드값을 초기화하는 역할
- 메소드 : 객체의 동작적인 걸 표현하는 역할
사용자 정의 클래스
- api 에 있는 클래스를 모방하여 생성
- 메소드 바깥쪽에 사용되는 변수 = 필드 = 멤버변수, 변수기때문에 값을 저장함, 속성을 표현
- 생성자는 클래스명과 동일한 이름으로 만들어야함. 객체가 생성될때 생성자가 호출되며
필드값을 초기화시키는게 생성자의 역할
- 메소드는 객체에 대한 동작을 나타냄, ex) public void static main
정리
메인 메소드 안의 변수 = 지역변수 = 스택메모리 = 메소드종료시 삭제
메소드 밖의 변수 = 멤버변수 = 필드 = 전역변수 = 힙 메모리 = 초기화
사용자정의 클래스 만들기 예시
public class Animal {
//Animal 은 사용자 정의 클래스(자료형)
int age; //자바에선 멤버변수, 필드(field) 라고 한다. C에선 전역변수라고 부른다.
// : 메소드 바깥쪽에 정의되는 변수
public static void main(String[] args) {
}
}
- age는 메소드 바깥에 있고, 이 클래스 전역에 사용 가능
- 멤버변수= 필드 = 전역변수 는 메모리 중 힙메모리 상에 저장됨!
- 클래스도 참조형이기 때문에 int age; 는 힙메모리상의 공간을 할당받고 초기화 0 으로 자동초기화됨
* JAVA구조 : 클래스 내에 메소드가 있다
생성자
- 멤버 함수 중 하나
- 반드시 클래스명과 동일한 이름으로 생성해야함.
- () 괄호가 반드시 있어야한다.
- 생성자명앞에는 접근제어자만 올 수 있다.
기본생성자(default constructor)
- 생성자 중 매개변수가 없는 생성자
int age;
public Animal() {
System.out.println("생성자 호출 성공");
}
사용자 정의 클래스와 클래스의 구조 3가지
public class Animal {
//Animal 은 사용자 정의 클래스(자료형)
int age; //필드
public Animal() { //생성자
System.out.println("생성자 호출 성공");
}
public static void main(String[] args) { //메소드
int a = 10;
}
}
- 필드, 생성자, 메소드가 다 있는형태
- 생성자는 주로 객체생성과 동시에 필드값의 초기화를 설정하기 위한 용도로 객체가 생성될때 호출되면서 실행
+ a는 지역변수, stack 메모리 영역에 저장, 이 메소드 안에서만 사용가능
+ 지역변수와 멤버변수는 스택과 힙 이라는 다른 공간에 저장되는것 뿐만 아니라 메모리상에 저장되는 영역과 할당되는 시점이 다름
public static void main(String[] args) {
int a = 10; //지역변수
String str = new String("자바");
Animal a1 = new Animal();
}
+ 이 main메소드는 Animal 클래스 내부임. Animal 클래스 내부에 Animal 클래스로 객체 만들어도 된다.
그림
필드 접근
Animal a1 = new Animal();
// 클래스 레퍼런스변수 연산자 생성자호출
- 이렇게 객체를 생성시 4바이트짜리 Animal 클래스의 '필드'를 저장하기 위한 기억공간을 힙에 생성함
- 그 필드는 age (=0 , 자동초기화) 이다. 그 주솟값을 a1이 가지고 있는 상태
- a1이 age가 저장된 힙메모리상의 시작주솟값을 가지고 있다.
- 이 a1으로 접근해야지만 이 age에 접근가능하다!
System.out.println(age); // 불가능
System.out.println(a1.age); // 로 해야함
- 반드시 a1이 가진 주소 이용해서 a1.age로 접근해야함!
- 객체 생성될때마다 새로운 age만들어지므로 어느 영역에 있는 age인지 알 수 없기 떄문이다
- age의 값을 수정하고 싶을때도 a1.age로 접근해서 수정해야한다
a1.age = 5;
System.out.println(a1.age); //5가 출력됨
생성자 호출
- 오른쪽의 Animal() 은 생성자를 호출하라는 코드임
public Animal() {
System.out.println("생성자 호출 성공");
}
- 출력이 됨
생성자를 안쓴다면?
- 기본으로 알아서 생성해줌
객체 생성2
ex) 이번에는 Animal 클래스로 다시 new 연산자로 다시 객체 생성해보자
Animal a2 = new Animal();
System.out.println(a2.age);
- 이러면 힙메모리상에 새로운 공간이 또 생성됨!
- 그림 참고
그림
- a1이 가진 주소와 a2가 가진 주소를 비교해보자
if (a1 == a2) {
System.out.println("같은 주소");
} else {
System.out.println("다른 주소");
}
출력 : 다른 주소
- new로 힙메모리에 새로운 공간을 만들었기 때문이다
'국비지원 과정 > JAVA' 카테고리의 다른 글
코딩 7일 / 2022.06.29 / JAVA의 접근제어자,메소드 오버로딩,정적 변수,정적 메소드 (0) | 2022.07.05 |
---|---|
코딩 6일 / 2022.06.28 / JAVA의 클래스,객체,필드,생성자 (0) | 2022.07.01 |
코딩 4일 / 2022.06.24 / JAVA의 제어문3,메소드,배열1 (0) | 2022.06.27 |
코딩 3일 / 2022.06.23 / JAVA의 제어문2, 난수발생 (0) | 2022.06.26 |
코딩 2일 / 2022.06.22 / JAVA의 변수,연산자,제어문1 (0) | 2022.06.23 |