응용 프로그램 프로그래밍 인터페이스
자바 시스템을 제어하기 위해서 자바에서 제공하는 명령어들을 의미한다.
선배 개발자들이 JAVA에서 코딩을 쉽게 할 수 있도록 만들어 놓은 것.
java.lang
자바 프로그래밍을 위한 가장 기본적인 패키지와 클래스를 포함하고 있다.
java.utill
프로그램을 제어하기 위한 클래스와 데이터를 효율적으로 저장하기 위한 클래스들을 담고 있다.
java.io
키보드,모니터,프린터,파일 등을 제어할 수 있는 클래스들의 모음
java.net
통신을 위한 기능들을 담고 있다.
처음 보는 거라도 보고 어떤 기능을 담당하는지를 분석해서 직접 사용할 줄 알아야 한다. 팀프로젝트 중 모르는 건 직접 검색해서 사용하는 훈련을 하는 것이다. 단순히 모든 영역에 대한 이해와 암기가 아니라, 이제는 남들이 만들어 놓은 메서드와 클래스들을 분석해서 알맞은 목적으로 사용하는 것에 의의를 두어야 하는 것.
javadoc(클래스, 메서드에 대한 도움말)
JAVA API문서는 javadoc로 만들어진 문서라고 볼 수 있다.
@author 개발자
@exception 메소드에서의 예외 확인
@param 메소드의 매개변수
@return 메소드의 반환값
@see 다른 주제에 관한 링크 지정(관련있는 주제)
@serial 직렬화 필드
@throws 메소드에서 예외
@version 클래스의 버전
하지만 주석을 작성해도 자동으로 javadoc 문서가 만들어지지 않는다.
직접 API를 만들어보자.
두 주소값이 같은지 확인하는 메서드
단, String 클래스에서 equals()를 재정의 하였기 때문에
String 타입이라면 값을 비교한다. (String은 Object 클래스)
String data1 = new String("ABC");
String data2 = new String("ABC");
data1,2는 출력했을 때 주소값으로 들어가 ABC라는 값을 가져오는 참조변수라고도 한다.
그 주소값을 직접 들어가서 안에 있는 값을 가져오기 때문에.
System.out.println(data1 == data2); // false. ==는 주소값을 비교.
stack 영역에 data1 과 data2라는 저장공간이 생겼다.
당연히 주소가 다를 수 밖에 없다.
각각의 흰 메모리 영역에 다른 주소값이 생긴 것.
그리고 그 공간의 주소값을 비교하기 때문에. (값이 들어있는 공간인 stack영역을 비교)
System.out.println(data1.equals(data2)); // true 주소값에 들어있는 값을 비교
equals는 String에 있는 애이다. 그런데 사실 object에 이미 equals가 있다. object클래스에서는 주소값을 비교하게 되어있다.
하지만 이건 String클래스에서 오버라이딩(재정의)되어진 것이다. 즉 값(heap 영역)을 비교하게끔 재정의 되어진 것.
뭘 이용해서 값을 비교하는 걸로 만들었을까?
String타입은 주소값을 저장한다. 객체이기 때문에.
A라는 클래스에 abc를 담으면 String pool이라는 문자열 수영장에 이 값이 존재하게 된다.
B를 만들어 내가 똑같은 문자열을 쓰면 비효율적이 된다.
(똑같은 문자열이 pool에 10000개가 있다 생각하면 그렇잖아요?)
그런데 .inturn이라는 메서드가 있다. A의 값이랑 같은 위치에 있는 것을 찾아주는 것이다.
그리고 그걸 찾으면 그 주소값을 리턴한다.
즉 주소값을 공유하는 것. 고로 주소값이 같다가 나오게 된다.
String str = "Hello";
위와같이 리터럴로 생성하게 되면 str 변수는 stack 메모리에,
"Hello" 라는 값은 Heap 메모리 내에 String pool이라는 곳에 저장되고 그 주소가 str 변수에 저장된다.
String pool 에 저장이 될 때는 intern() 메소드가 실행이 되게 되는데
같은 값이 있을 경우 기존값의 메모리 주소를, 다른 값일 경우 새롭게 객체를 생성해 값을 저장하고 그 메모리 주소를 리턴
System.out.println(data3.intern() == data4); // true
를 하게 되면 true가 나옴.
System.out.println(data3 == data4); // true
data3과 data4는 .inturn을 붙이지 않아도 true가 나온다 왜그럴까?
앞서 말했듯이 값이 이미 있으면 그 친구에 가서 그 주소값을 같이 기억해준다.
이미 기존에 있는 값들이 중복이 안된다.
같은 주소값을 가지고 있기 때문에 같다고 나오는 것.
기존에 이미 inturn 이 먼저 실행이 되서 찾아온 다음 그 주소값을 리턴하고 있기 때문에 true가 나온다. 주소값 공유
System.out.println(data3.equals(data4)); // true
Random r = new Random();
Random r2 = new Random();
System.out.println(r.equals(r2)); //false
System.out.println(r == r2); //false
equals는 Object에 있는 equals이고 주소값을 비교한다.
r = r2; // 를 붙이게 되면
System.out.println(r.equals(r2)); //true
System.out.println(r == r2); //true
내부적으로 공유하고 있는 값의 주소값이 같다.
배열은?
두 객체가 같은지 확인하는 메서드(Collection에서 다시 다룸)
데이터 관리 기법 중 하나이며 다량의 데이터를 저장하는 것이 가능하고
빠른 검색이 가능하다.
String 클래스에서 오버라이딩 했으며, 값이 같으면 같은 해쉬코드를 갖는다. (pool 이야기와 동일)
그 안에 있는 값의 주소값을 뽑아내는 것
주소값이라 부르지 않고 hashcode라 부른다.
System.out.println(data1.hashCode()); // 64578
System.out.println(data2.hashCode()); // 64578
System.out.println(data3.hashCode()); // 64578
System.out.println(data4.hashCode()); // 64578
System.out.println(data1.hashCode() == data2.hashCode()); // true
정리
기본 자료형이 (int, double, byte, long, boolean 등) 저장되는 공간은 Stack(스택) 영역.
LIFO(Last In First Out)의 구조를 갖고 하나의 변수에 새로운 데이터가 할당되면 이전 데이터는 지워진다.(가장 나중에 들어온 데이터가 가장 먼저 인출된다.) 해당 메서드가 호출될 때 메모리에 할당되고, 종료되면 메모리에서 사라진다.
참조형 (Reference Type)의 데이터 타입을 갖는 객체(인스턴스), 배열 등은 Heap 영역에 데이터가 저장된다. 이때 변수(객체, 객체변수, 참조변수)는 Stack영역의 공간에서 실제 데이터가 저장된 Heap영역의 참조값을 new 연산자를 통해 리턴받는다.
다시 말하면 실제 데이터를 갖고 있는 Heap영역의 참조 값(주소 값)을 Stack 영역의 객체가 갖고 있다.
정리하자면, Stack에 쌓이는 변수 중 참조변수에 저장되는 메모리 주소는 스택 영역에 저장되고 그 주소가 가리키는 참조값은 HEAP 영역에 저장된다.
String str1 = new String("joker");
String str2 = new String("joker");
이 둘은 저장된 주소가 다르기 때문에 "=="으로 비교 시 다른 주소값을 비교하기에 false가 된다.
equals는 heap 영역의 주소값을 비교하기에 equals 를 하였을 때에는 true가 나온다.
참고로 Heap에 저장된 데이터가 더 이상 사용이 불필요하다면 메모리 관리를 위해 JVM(자바 가상머신)에 의해 알아서 해제된다. 이러한 기능을 가비지컬렉션(GC, 쓰레기 수집)이라고 한다.
static 영역
Static 이라는 키워드를 사용하여 Static 변수(정적 필드)와 Static 메서드(정적 메서드)를 만들 수 있는데, 두 가지를 합쳐서 정적 멤버라고 한다. (= 클래스 멤버)
정적 필드와 정적 메소드는 객체(인스턴스)에 소속된 멤버가 아니라 클래스에 고정된 멤버.
하나의 Java 파일은 크게 필드(field), 생성자(constructor), 메서드(method)로 구성되어 있고, Static Area(스태틱 메모리 영역)에서는 그중 필드 부분에서 선언된 변수(전역 변수)와 정적 멤버 변수(static이 붙은 자료형)의 데이터를 저장.
Static Area(스태틱 메모리 영역)에 데이터는 프로그램의 시작부터 종료가 될 때까지 메모리에 남아있게 된다. 즉, 프로그램이 종료될 때까지 어디서든지 사용이 가능하지만, 주의할 점은 전역 변수를 무분별하게 많이 사용하게 되면 메모리가 부족한 문제가 발생할 수 있다. 따라서 필요한 변수만 전역 변수로 사용할 필요가 있다.