1주차 자바 기초
- Java 개발 환경 구성
- Java 프로그래밍 언어 기본 문법
25.01.10 (금)
강의 책 : 자바/스프링 개발자를 위한 실용주의 프로그래밍 (위키북스, 김우근 저)
아래의 내용은 [LG CNS AM CAMP 1기] 수업을 바탕으로 작성하였습니다.
<참조 자료형>
[배열]
- 동일한 자료형을 묶어 저장하는 참조 자료형
- 생성할 때 크기를 지정해야 하고, 한 번 크기를 지정하면 절대 변경할 수 없는 특징이 있음
- 자료형[] 변수명; 또는 자료형 변수명[];
int[] a; int a[];
String[] b; String b[];
[1차원 배열의 생성 및 값 대입]
방법1. 배열 객체의 생성 + 값 대입
int[] a = new int[3];
a[0] = 3;
a[1] = 4;
a[2] = 5;
방법2. 배열 객체의 생성 및 값 대입
방법3. 대입할 값만 입력
int[] a = { 3, 4, 5 };
=> 방법1과 2는 선언과 할당을 분리할 수 있지만, 방법3은 분리할 수 없다.
[코드 예시]
package com.test;
import java.util.Arrays;
<메모리 초기화>
[스택 메모리]
● 초기값을 부여하지 않는 경우 빈 칸으로 존재
● 읽기 불가능
int a;
System.out.println(a); // 오류 발생
[힙 메모리]
● 빈 칸으로 존재할 수 없으며, 디폴트 초기값이 강제 설정
● 기본 자료형 ⇒ 숫자 : 0 / boolean : false
● 참조 자료형 ⇒ null
- 배열은 참조자료형이기 때문에 스택메모리에 주소를 가지고 있기 때문에 값이 변하는 것.
<배열 데이터를 읽는 방법>
방법1. for 반복문 ⇒ 배열의 크기 만큼 루프를 돌면서 인덱스로 참조
방법2. for-each 반복문 ⇒ 루프를 돌면서 배열 데이터를 가져와서 사용
//=> for of 구문과 비슷
< main() 메서드의 입력 매개변수 >
public void static main(String[] args)
~~~~~~~~~~ 프로그램이 실행될 때 입력되는 값 (전달되는 값)
< 타입 변환 메서드>
- 문자열 → 정수 ⇒ Integer.parseInt(문자열)
- 문자열 → 실수 ⇒ Double.parseDouble(문자열)
- 정수 → 문자열 ⇒ String.valueOf(정수)
- 실수 → 문자열 ⇒ String.valueOf(실수)
<String>
[String 객체 생성 방법]
방법1. new 키워드 사용 (권장)
방법2. 문자열 리터럴 이용
String str = "안녕";
[String 클래스의 특징]
- 한 번 정의된 문자열은 변경할 수 없다. ⇒ 문자열의 내용을 변경하면 문자열을 수정하는 것이 아니고, 새로운 문자열을 포함하고 있는 객체를 생성해서 사용 (기존 문자열 객체는 버림)
- 문자열 리터럴을 바로 입력해 객체를 생성할 때 같은 문자열끼리는 객체를 공유
⇒ new 키워드를 이용해서 객체를 생성하면 항상 새로운 객체를 생성
⇒ 문자열 리터러로 생성하면 동일한 문자열을 포함하고 있는 객체가 있으면 그 객체를 공유
[문자열 + 문자열]
- [문자열 + 기본 자료형] 또는 [기본 자료형 + 문자열] ⇒ 기본 자료형을 문자열로 바꾸서 결합 연산
[ String 클래스의 주요 메서드 ]
- 문자열의 실제 내용을 비교하기 위해서는 == 보다는 equals를 사용해야한다.
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
<클래스>
- 객체(object)는 사용할 수 있는 실체를 의미 ⇐ 붕어빵
- 클래스(class)는 객체를 만들기 위한 설계도 ⇐ 붕어빵 틀
- 하나의 클래스를 이용해서 여러 개의 객체를 만들 수 있음
- 데이터가 임의로 변형되는 것을 막을 수 있다.
- 왼쪽은 절차지향, 오른쪽은 객체지향 flow
- 객체지향은 확장이 쉽다.
[자바에서 제공하는 객체지향 문법 요소]
- 인터페이스 : 명세만 존재.
- 클래스는 실질적인 동작이 구현되는 것. 추상클래스는 동작이 100% 구현되지 않는 것이다.
- 인터페이스는 프로그램을 유연하게 해준다. 두개의 다른 대상을 연결해주는 역할을 한다. 쉽게 연동이 가능해진다.
- 인터페이스의 가장 좋은 예시로 프린터가 있다.
[클래스 구조]
[클래스 멤버 = 필드 + 메서드 + 내부 클래스 ]
- 객체를 생성할 때는 new 키워드를 사용
- 클래스명 참조변수명 = new 생성자();
- 생성자는 객체를 사용할 때 사용하는 함수
- 포인트 연산자를 사용하여 메서드와 필드를 접근
- 자바에서는 힙 메모리에 직접 접근을 할 수 없음
- 참조변수명.필드명
참조변수명.메서드명()
[필드 vs 지역변수]
class A {
int m = 3; //필드
int n = 4;
void work1() {
int k = 5; //지역변수
System.out.println(k);
work2(3);
}
void work2(int i) { //매개변수 = 지역변수
int j = 4; // 지역변수
System.out.println(i + j);
}
}
- 프레임이라는 단위로 메소드 별로 생김
[필드와 지역변수의 초기값]
- 스택메모리는 초기화가 되지 않기 때문에 오류가 발생
- 필드는 기본 값으로 초기화 되고 지역변수는 초기화 되지 않아 오류 발생
<메서드>
- 여러 리턴 타입을 메서드는 가질 수 있다.
- 리턴 타입이 void일 때, 메서드 내에서 return을 사용 ⇒ 메서드를 종료한다는 의미
[메서드 호출]
1. 클래스 외부에서 메서드 호출 ⇒ 참조변수를 이용해서 메서드를 호출 ⇐ 객체를 먼저 생성
2. 클래스 내부에서 메서드 호출 ⇒ 객체를 생성하지 않고 호출이 가능 (단, static이 붙어 있는 메서드는 static이 붙어 있는 필드 또는 메서드만 호출이 가능)
- 해당 클래스 내에서는 호출이 자유롭지만, 외부에서는 인스턴스를 만들어서 호출해야한다.
[입력 매개변수가 배열인 메서드를 호출]
- printArray({1,2,3})은 정의와 호출을 분리할 수 없기 때문에 불가능하다.
- 기본 자료형을 매개변수의 값으로 전달하는 경우, 값을 복사해서 사용한다.
- 기본자료형의 경우 스택의 값을 복사해서 넘겨서 main frame의 값은 변경되지 않는다.
- 참조자료형의 경우 주소를 가리키게 돼므로, 4,5,6의 값으로 바뀌면 array의 값도 바뀌게 되는 것이다.
※ 참고: 관련된 보안약점
● public 메서드로부터 반환된 private 배열 ⇒ getter 메서드를 잘못 구현했을 때 발생
● private 배열에 public 데이터 할당 ⇒ setter 메서드를 잘못 구현했을 때 발생
=> 주소가 반환되어 private한 데이터도 외부에서 변경이 가능하게 됌 (보안약점)
[메서드 오버로딩]
- 메서드 시그니처(method signature) = 메서드명 + 매개변수의 자료형 ⇐ 메서드를 구부하는 기분
- 메서드 오버로딩 ⇒ 매개변수의 개수나 자료형이 다른 여러 개의 동일한 이름을 지닌 메서드를 같은 공간에 정의
⇒ return 타입은 포함되지 않는다.
ex. 가변 길이 배열 데이터를 매개변수로 받는 메서드
- 가변길이를 사용할 때는 ... 을 사용한다.
<클래스 내부 구성 요소 - 생성자 >
- 객체 생성에 사용
- 필드 초기화에 사용
- 클래스 이름과 동일한 이름을 가지고, 리턴 타입이 없음 (반환값이 없음)
- 기본 생성자 ⇒ 생성자를 포함하지 않은 클래스에서 컴파일러가 자동으로 추가하는 생성자 (기본 생성자는 매개변수가 없고 생성자 본문이 비어 있음)
- 기본생성자는 컴파일러가 생성해준다.
- this 키워드 ⇒ 자신이 포함된 클래스의 객체를 가리키는 참조 변수
⇒ 명시적으로 매개변수의 이름과 필드의 이름이 같을 때 사용한다.
⇒ this를 생랼하여도 컴파일러가 자동으로 this를 추가한다.
- this() 메서드
⇒ 자신이 속한 클래스 내부의 다른 생성자를 호출 ⇒ 생성자 내부에서만 사용할 수 있고, 생성자의 첫 줄에 위치해야 함
⇒ this() 메서드는 코드의 중복을 줄일 수 있다.
< 클래스 외부 구성 요소 - 패키지(package) >
- 동일한 목적으로 만들어진 클래스들을 묶어(동일한 공간(폴더)) 관리하는 것 ⇒ 클래스명의 충돌을 방지 ⇒ 클래스의 풀네임(full name) ⇒ 패키지명.클래스명
- 다른 클래스와 구분하기 위함
< 클래스 외부 구성 요소 - 외부 클래스(external class) >
- public 클래스 외부에 정의한 클래스
- 외부 클래스는 같은 패키지 안에서만 사용할 수 있음 ⇐ default 접근 지정자를 가지는 클래스
< 접근 지정자 >
- 자바 제어자의 한 종류로, 클래스, 멤버(필드, 메서드, 인너 클래스), 생성자 앞에 위치
- 사용 범위를 정의
- 멤버 및 생성자의 접근 지정자 ⇒ public, protected, default(=package), private
- 필드는 private, 메소드는 public, 외부에서 사용할 수 없는 메소드는 private를 주로 사용한다.
- 클래스의 접근 지정자 ⇒ public, default
~~~~~~~ 같은 패키지 내에서만 사용이 가능
- public은 다른 클래스에서 접근해서 사용할 수 있다.
- public이 아닌 defualt 클래스를 참조하려고하면 불가능하다.
< static 제어자 >
- 클래스 멤버(필드, 메서드, 이너 클래스)에 사용하는 제어자
- static이 붙어 있는 멤버 ⇒ 정적 멤버(static member) ⇒ 객체 생성 없이 "클래스명.멤버명"으로 사용이 가능
- static이 붙어 있지 않은 멤버 ⇒ 인스턴스 멤버(instance member) ⇒ "참조변수명.멤버명"
⇒ 정적 필드는 객체 간 고유 변수의 성격을 가짐
- static 변수는 클래스 영역 안에 별도의 공간이 만들어져 그곳에 값이 들어간다.
- 모든 클래스의 인스턴스에 동일한 값이나 규칙이 적용되어야 할 때 static을 사용한다.
[인스턴스 메서드와 정적 메서드]
- 정적 메서드 내에서는 정적 필드 또는 정적 메서드만 사용이 가능
- this 키워드를 사용할 수 없음 (this는 인스턴스가 있어야 사용가능하기 때문)
<정적 필드의 초기화 할때>
- 정적 초기화 블록 ⇒ 정적 필드를 초기화하기 위한 문법
<static main() 메서드>
<상속>
- 오늘 배운 것 중 가장 중요 ★ ★ ★
- UML 표현법
[장점]
장점1. 코드의 중복을 제거
장점2. 다형적 표현이 가능 ⇒ 다형성(polymorphism) : 객체를 여러 가지 모양으로 표현할 수 있는 특징
- extends로 상속을 표현한다.
- fruit를 정의하면 상속받은 과일들이 모두 들어올 수 있다. (따로따로 정의해야하는 것들이)
- 자바의 클래스는 다중 상속이 불가능 ⇒ class 자식클래스 extends 부모1클래스, 부모2클래스 { ... } (X)
- 클래스가 아니면 가능하다. (인터페이스는 다중 상속 가능)
- 부모를 먼저 만들고 다음에 자식 클래스를 만든다.
- 상속을 수행할 때 클래스의 내부 구성 요소 중에선 멤버(필드, 메서드, 이너 클래스)만 상속되고, 생성자는 상속되지 않음
[기본 자료형]
- 등호를 중심으로 데이터 타입이 일치되어야 한다. (왼쪽 = 오른쪽)
- 일치 되지 않으면 자동으로 형변환 되거나, 수동으로 바꿔주어야 한다.
- 객체에서 자식 클래스에서 부모 클래스 쪽으로 변환되는 것 업 캐스팅이라고 하고, 그 반대를 다운 캐스팅이라고 함
- 업 캐스팅은 명시적으로 하지 않아도 컴파일러가 자동으로 수행
- 다운 캐스팅은 개발자가 명시적으로 수행
- C가 만들어지지 않았기 떄문에 참조를 할 수 없다. 그렇기 때문에 불가능한 것 (힙메모리에서 C객체 찾을 수 없기 때문)
- B의 객체를 A 타입으로 선언했을 때 자식이 가지고 있는 것은 쓸수가 없다.
- 밖의 자식의 것을 쓰기 위해서는 캐스팅을 해야한다.
ex. B b = (B) a;
System.out.printlln(b.n);
b.bcd
위와 같이 캐스팅을 해야 사용할 수 있다.
- 그렇다면 캐스팅 가능여부를 확인 할 수 있어야 한다.
- 캐스팅 가능 여부를 확인 ⇒ instanceof 키워드
- 안전한 캐스팅을 하기 위해서는 instanceof를 이용해 캐스팅 여부 확인하고 다운캐스팅 해야한다.
※ 사용법
참조변수 instanceof 타입
⇒ true 캐스팅 가능
⇒ false 캐스팅 불가능
- 상속을 받는 이유는 다형성을 위해 받는 것이다.
- 그렇다면 데이터를 쉽게 관리 할 수 있다.
- 부모를 정의하면 자식들의 데이터를 여러가지 구현할 수 있어 데이터를 유연하게 받을 수 있다.
- 데이터를 사용하기 위해서는 캐스팅이 필요한데, 이때 필요한 것이 instanceof이다.
<메서드 오버라이딩(method overriding) >
- 부모 클래스에서 상속받은 메서드와 동일한 이름의 메서드를 재정의하는 것
- 부모 메서드를 자신이 만든 메서드로 덮어쓰는 개념
- 부모 클래스의 메서드와 시그니처와 리턴 타입이 동일해야 함
- 부모 클래스의 메서드다 접근 지정자의 범위가 같거나 넓어야 함 (public -> public)
- 오버라이딩 된 것을 명시적으로 알려주기 위해서 @Override 라고 사용한다. (annotation : 컴파일러에게 알려줌)
- A a b = n e w B ( ) ; a b . p r i n t ( ) ; / / B 클 래 스
- 오버라이딩 된 메소드가 호출된다. (다형성을 구현하는데 꼭 필요한 개념)
- 부모는 구조를 정의하고, 구현은 오버라이드 하도록 한 후 자식에서 만든 것을 내가 만든 것을 특정 시점에 구현할 수 있게 함 (캐스팅을 하지 않아도)
'LG CNS AM CAMP 1기 > AI 서비스 개발을 위한 백엔드 I' 카테고리의 다른 글
1일차_JAVA 개발 환경 & Java 프로그래밍 언어 기본 문법 (0) | 2025.01.09 |
---|