All top-level classes are, by definition, static.

What the static boils down to is that an instance of the class can stand on its own. Or, the other way around: a non-static inner class (= instance inner class) cannot exist without an instance of the outer class. Since a top-level class does not have an outer class, it can't be anything but static.

Because all top-level classes are static, having the static keyword in a top-level class definition is pointless.

Some code to play around with:

public class Foo {

    public class Bar {
         // Non-static innner class
    }

    public static class Baz {
         // Static inner class
    }
}

public class Example {
    public static void main(String[] args) {
        new Foo(); // this is ok
        new Foo.Baz(); // this is ok
        new Foo.Bar(); // does not compile!

        Foo f = new Foo();
        Foo.Bar bar = f.new Bar(); //this works, but don't do this
    }
}

 

I put the "but don't do this" in there because it's really ugly code design. Instance inner classes should not be visible outside the outer class. They should only be used from within the outer class.

 

 

Inner class는 그 안에서만 사용. 그러니까 inner로 만들었자나아아아

Top level class는 static 사용 못함.

 

 

 

 

 

Ref. https://stackoverflow.com/a/7370832

자바에서는 Object Oriented Programming의 특징 중에 하나인 다형성(Polymorphism)을 지원하는 방법으로 메소드 오버로딩과 오버라이딩을 지원한다. (물론 다른 언어들도...)

 

Overloading

  • 같은 이름의 메소드를 여러 개 가지면서 매개변수의 유형과 개수가 달라서, 메모리에 같은 이름의 메소드가 여러 개 로딩되는 형태
  • 메소드 오버로딩, 생성자 오버로딩

 

overloading

Overriding

  • 상속에서 상위 클래스가 가지고 있는 메소드를 하위 클래스가 재정의하여 사용.
  • 부모 객체의 메소드는 숨겨지기 때문에, 자식 객체에서 메소드를 호출하면 오버라이딩된 자식 메소드가 호출
  • 접근 제한을 더 강하게 오버라이딩 할 수 없음

 

목차

  1. Collection Framework
  2. Collection Framework의 핵심 인터페이스 - List, Set, Map
  3. Collection Frmawork의 동기화(synchronization)

1. Collection Framework

  • Collection
    - 다수의 데이터, 즉, 데이터 그룹을 의미한다.

  • Framework
    - 표준화, 정형화된 체계적인 프로그래밍 방식
  • Collection framework
    - 데이터 군(群)을 저장하는 클래스들을 표준화한 설계
    - 다수의 데이터를 쉽게 처리할 수 있는 방법을 제공하는 클래스들로 구성
    - JDK1.2부터 제공
  • Collection class
    - 다수의 데이터를 저장할 수 있는 클래스(예, Vector, ArrayList, HashSet)
  • Collection method
    - int size();
    - boolean isEmpty();
    - boolean add(Object element);
    - boolean remove(Object obj);
    - boolean removeAll(Collection other);
    - boolean contains(Object obj);
    - Iterator iterator(); // iterator 인터페이스를 얻어냄
    - Object[] toArray(); // 컬렉션에 들어있는 요소를 배열 객체로 바꿈 

 

 

2. Collection Framework의 핵심 인터페이스

List interface

순서가 있는 데이터 집합. 데이터 중복 허용

구현 클래스: ArrayList, LinkedList, Stack, Vector ...

 

Set interface

순서를 유지하지 않는 데이터 집합. 데이터 중복 허용x

구현 클래스: HashSet, TreeSet, ...

 

Map interface

키(key)와 값(value)의 쌍으로 이루어진 데이터 집합. 순서유지되지 않으며, 키 중복 허용되지 않음. 값 중복 허용

구현 클래스: HashMap, TreeMap, HashTable, Properties ...

 

1) List Interface

- Sequence(연속된 상태) 라고도 함.

- 순서 보장, 중복 허용

- 구현 클래스: Stack, Vector, ArrayList ...

- 배열과의 차이점: 배열은 크기가 고정, List 구조는 가변적 길이

 

 

Method

Element get(int index)  // element 가져오기

void set(int index, Element e);  // element 교체

boolean contains(Element e)

int indexOf(Element e)

int lastIndexOf(Element e)

...

 

Iterator pattern

// 기본 list의 element 값 가져오기
for (int i = 0; i < list.size(); i++) {
	System.out.print(list.get(i) + "\t");
}

// interator 객체로 element 얻어오기 => Iterator Pattern
Iterator elements = list.iterator();	
while (elements.hasNext()) {
	System.out.print(elements.next() + "\t");
}

// LinkedList에 있는 메소드 사용하여 element가져오기
int i = 0;
while (!linkedList.isEmpty()) {
	System.out.println(i + "->" + linkedList.poll());	// 메모리에서 삭제하면서 element를 가져옴.
	i++;
}

 

ArrayList와 LinkedList 비교

컬렉션 읽기(접근시간) 추가 / 삭제  
ArrayList 빠르다 느리다 순차적인 추가삭제는 빠름.
비효율적인 메모리 사용
LinkedList 느리다 빠르다 데이터가 많을수록 접근성이 떨어짐.

 

...더보기

ArrayList와 LinkedList 성능 비교 코드

// 입력 성능이 필요한 곳에서는 Linkedlist를 사용하는 것이 성능면에서 좋다.
List<String> list1 = new ArrayList<String>();
List<String> list2 = new LinkedList<String>();

long startTime;
long endTime;

startTime = System.nanoTime();

for (int i = 0; i < 10000; i++) {
	list1.add(0, String.valueOf(i));
}

endTime = System.nanoTime();
System.out.println("ArrayList 걸린 시간: " + (endTime - startTime) + "ns");

startTime = System.nanoTime();

for (int i = 0; i < 10000; i++) {
	list2.add(0, String.valueOf(i));
}

endTime = System.nanoTime();
System.out.println("LinkedList 걸린 시간: " + (endTime - startTime) + "ns");

 

2) Set Interface

- 중복된 element가 발생하지 않도록 내부에서 관리 => 중복허용X

- 정렬되지 않음. => 순서유지X

- 구현 클래스: HashSet, TreeSet

 

HashSet

정렬저장 X

 

TreeSet

정렬저장 O (오름차순)

이진 검색 트리(binary search tree) 의 구조로 되어있음

검색과 정렬에 유리하지만, HashSet보다 데이터 추가, 삭제시간이 더 걸림

 

...더보기

Member.java

public class Member {
	public String name;
	public int age;
	
	public Member(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	/* 
        equals: 최상위 클래스인 Object가 가지고 있는 메소드
        Overriding하여 조건에 맞는 equals 구현 가능
        (ex. HashSet에서 같은 값이면 추가되지 않는 조건 지정 가능)
        */
	public boolean equals(Object obj) {
		if (obj instanceof Member) {
			Member member = (Member) obj;
			 return member.name.equals(name) && (member.age == age);
		} else {
			return false;
		}
	}
	
	// 메모리가 생성된 주소값
	public int hashCode() {
		return this.name.hashCode() + age;
	}
}

 

 

3) Map Interface

- Key와 Value를 매핑하는 객체

- Key는 절대 중복될 수 없음.

- 정렬 기준이 없음.

- 구현 클래스: HashMap, TreeMap ...

 

Hash Map

저장되는 value와 key가 null 허용

동기화가 포함되지 않았으므로 나중에 배우는 multi-thread 환경에서의 구현이 아니라면 Hashtable에 비해서 처리 속도가 빠름.

...더보기

HashTableExample.java

Map<String, String> map = new Hashtable<String, String>();
		
map.put("spring", "12");
map.put("summer", "123");
map.put("fall", "1234");
map.put("winter", "12345");

Scanner sc = new Scanner(System.in);

while (true) {
  System.out.println("아이디와 비밀번호를 입력해주세요.");
  System.out.println("아이디: ");
  String id = sc.nextLine();

  System.out.println("비밀번호:");
  String pw = sc.nextLine();
  System.out.println();

  if (map.containsKey(id)) {
    if (map.get(id).equals(pw)) {
      System.out.println("로그인 되었습니다.");				
      break;
      } else {
      	System.out.println("비밀번호가 일치하지 않습니다.");
      }
    } else {
    	System.out.println("입력하신 아이디가 존재하지 않습니다.");
  }		
}

sc.close();

 

Tree Map

...더보기

TreeMapExample1.java - 원하는 값을 가져오거나, 정렬을 원할 경우 entry로 뽑아옴.

TreeMap<Integer, String> scores = new TreeMap<>();
scores.put(new Integer(87), "홍길동");
scores.put(new Integer(98), "이동수");
scores.put(new Integer(75), "발길순");
scores.put(new Integer(95), "신용권");
scores.put(new Integer(80), "김자바");

Map.Entry<Integer, String> entry = null;

entry = scores.firstEntry();
System.out.println("가장 낮은 점수 : " + entry.getKey() + "-" + entry.getValue());
entry = scores.lastEntry();
System.out.println("가장 높은 점수 : " + entry.getKey() + "-" + entry.getValue());
entry = scores.lowerEntry(new Integer(95));
System.out.println("95점 아래 점수 : " + entry.getKey() + "-" + entry.getValue());
entry = scores.higherEntry(new Integer(95));
System.out.println("95점 위의 점수 : " + entry.getKey() + "-" + entry.getValue());

entry = scores.floorEntry(new Integer(95));
System.out.println("95점 이거나 바로 아래의 점수: " + entry.getKey() + "-" + entry.getValue());
entry = scores.ceilingEntry(new Integer(85));
System.out.println("85점 이거나 바로 위의 점수: " + entry.getKey() + "-" + entry.getValue());

while (!scores.isEmpty()) {
  entry = scores.pollFirstEntry();
  System.out.println(entry.getKey() + "-" + entry.getValue() + "(남은 객체 수 : " + scores.size() + ")");
}

 

TreeMapExample2.java

TreeMap<Integer, String> scores = new TreeMap<>();
scores.put(new Integer(87), "홍길동");
scores.put(new Integer(98), "이동수");
scores.put(new Integer(75), "발길순");
scores.put(new Integer(95), "신용권");
scores.put(new Integer(80), "김자바");

NavigableMap<Integer, String> descendingMap = scores.descendingMap();
Set<Map.Entry<Integer, String>> descendingEntrySet = descendingMap.entrySet();

for (Map.Entry<Integer, String> entry : descendingEntrySet) {
	System.out.print(entry.getKey() + "-" + entry.getValue() + " ");
}

System.out.println();

NavigableMap<Integer, String> ascendingMap = descendingMap.descendingMap(); 	// descending 번갈아가며 수행
Set<Map.Entry<Integer, String>> ascendingEntrySet = ascendingMap.entrySet();

for (Map.Entry<Integer, String> entry : ascendingEntrySet) {
	System.out.print(entry.getKey() + "-" + entry.getValue() + " ");
}

 

Map Collection - Properties 가져오기

public static void main(String[] args) throws FileNotFoundException, IOException{
	
    Properties pt = new Properties();
    String path = PropertiesExample.class.getResource("database.properties").getPath();
	  // /C:/Java%20Programming/Sources/och11/bin/och11/database.properties
    System.out.println("1 path : " + path);		
    path = URLDecoder.decode(path, "utf-8");
    pt.load(new FileReader(path));
    String driver = pt.getProperty("driver");
    String url = pt.getProperty("url");
    String userName = pt.getProperty("username");
    String password = pt.getProperty("password");

	  // /C:/Java Programming/Sources/och11/bin/och11/database.properties
    System.out.println("2 path : " + path);		
    System.out.println("driver: " + driver);
    System.out.println("url1 : " + url);
    System.out.println("username : " + userName);
    System.out.println("password: " + password);
}

 

 

3. Collection Framework의 동기화(synchronization)

추후 예정

 

 

목차

  1. 추상 클래스 (abstract class)
  2. 인터페이스 (interface)
  3. 추상클래스와 인터페이스의 비교

1. 추상 클래스(abstract class)

  • 클래스의 프레임만 구성
  • 하나 이상의 추상 메소드 포함
    (추상 메소드: 선언 부분만 있고 구현 부분이 없는 메소드)
  • 직접 객체 생성 불가능
  • 추상 클래스에서 정의된 추상적인 기능은 하위 클래스에서 상세 구현

 

추상 클래스 용도

1. 실체 클래스들의 공통된 필드와 메소드의 이름을 통일할 목적

2. 실체 클래스를 작성할 때 시간 절약

 

2. Interface

특징

  • 실제 구현된 것이 전혀 없는 기본 설계도.(알맹이 없는 껍데기) - 설계와 구현 분리 가능
  • 멤버는 추상메서드와 상수만을 가능 => public static final, public abstract 키워드 생략 가능
  • 인스턴스를 생성할 수 없고, 클래스 작성에 도움을 줄 목적으로 사용됨.
  • 미리 정해진 규칙에 맞게 구현하도록 표준을 제시하는 데 사용됨.
  • 인터페이스끼리는 다중 상속 가능

장점

  • 개발시간을 단축시킬 수 있다.
    - 일단 인터페이스가 작성되면, 이를 사용하여 프로그램을 작성하는 것이 가능. 
    - 인터페이스가 공통이므로 동시 개발 가능
  • 표준화가 가능하다.
    - 프로젝트에 사용되는 기본 틀을 인터페이스로 작성한 후 개발되도록 함. 일관되고 정형화된 프로그램 개발 가능.
  • 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
    - 하나의 인터페이스를 공통적으로 구현함으로써 관계 매핑

  • 독립적인 프로그래밍이 가능하다.
    - 클래스의 선언과 구현을 분리시킬 수 있음.
    - 클래스와 클래스 간의 직접적인 관계를 인터페이스를 이용해서 간접적인 관계로 변경하면, 한 클래스의 변경이 관련된 다른 클래스에 영향을 미치지 않는 독립적인 프로그래밍이 가능

 

3. 추상 클래스와 인터페이스 비교

구분 추상 클래스 인터페이스
선언 abstract class 클래스명 {
    변수;
    메서드() {...}
    abstract 메서드();
}
interface 인터페이스명 {
     상수;       // public final static
     메서드(); // public abstract
}
상속 class Sub extends super {
   메서드 재정의 // overriding
}
class Sub implements Interface1, Interface2 {
    메서드 재정의 // overriding
}
장점 프레임 제공 프레임 제공, 다중 상속

 

 

목차

  1. 상속 (클래스간의 관계)
  2. Overriding (메소드 재정의)
  3. final 클래스와 final 메소드
  4. instanceof 연산자
  5. 참조변수와 인스턴스의 연결

1. 상속 (클래스간의 관계)

: 기존의 클래스를 재사용해서 새로운 클래스를 작성부모클래스(객체)의 멤버들을 자식클래스(객체)가 물려받는것

class Parent {}
class Child extends Parent {}

 

  1. 상속을 사용하는 이유 - 기존에 만들어놓은 클래스의 재사용, 확장을 위해 사용. 

  2. 자바에서는 단일상속만이 가능

  3. 부모클래스(super)와 자식클래스(sub)가 존재

  4. Object 클래스 - 모든 클래스의 최상위

    : 모든 클래스는 Object 클래스에 정의된 11개의 메소드를 상속. toString(), equals(Object obj), hashCode() ...

  5. private 객체변수는 상속 안됨

  6. super: 상위 클래스의 멤버나 메소드에 접근하기 위함.

 

2. Override (메소드 재정의)

자식 클래스에서 동일한 매소드를 재정의.

부모 객체의 메소드는 숨겨지기 때문에, 자식 객체에서 메소드를 호출하면 오버라이딩된 자식 메소드가 호출

 

- 접근 제한을 더 강하게 오버라이딩 할 수 없음

- 새로운 예외를 throws할 수 없음

 

 

 

3. final 클래스와 final 메소드

해당 선언이 최종 상태이고, 결코 수정될 수 없음. final 키워드 지정시 상속과 관련됨.

 

- final class: 상속할 수 없는 클래스(ex. String)

- final method: Overriding 할 수 없는 메소드

- final field: 초기값 설정 후, 더 이상 값을 변경할 수 없는 필드

 

 

4. instanceof 연산자

참조변수가 참조하는 인스턴스의 실제 타입을 체크하는데 사용.

if ( c instanceof Car) { ... }

 

 

 

5. 참조변수와 인스턴스의 연결

  • 멤버변수가 중복정의된 경우, 참조변수의 타입에 따라 연결되는 멤버변수가 달라진다. (참조변수타입에 영향받음)
  • 메서드가 중복정의된 경우, 참조변수의 타입에 관계없이 항상 실제 인스턴스의 타입에 정의된 메서드가 호출된다.
    (참조변수타입에 영향받지 않음) -> Overriding

목차

  1. class 구성 멤버
  2. 인스턴스 멤버와 정적 멤버
  3. final 필드와 상수
  4. 패키지
  5. 접근 제한자 (Access modifer)
  6. 중첩 클래스 (Inner class)
  7. 어노테이션 (Annotation)

1. Class의 구성 멤버

Field

- = 멤버 변수 = 인스턴스 변수

- dot(.) 연산자: 객체 접근 연산자

 

Constructor

new 연산자와 같이 사용되어 클래스로부터 객체를 생성할 때 호출되어 객체의 초기화 담당

- default constructor: {}, 클래스 내부에 생성자 선언이 없다면 컴파일러가 바이트코드에 자동으로 추가

- 생성자 오버로딩(Overloading): 매개변수를 달리하는 생성자를 여러개 선언하는 것

 

Method

- 메소드가 호출되면 수행에 필요한 메모리를 스택에 할당, 마치면 메모리 반환

- 매개변수: call by value(값을 전달), call by reference(객체 참조 주소 전달)

- 메소드 오버로딩(Overloading): 클래스 내에 같은 이름의 메소드를 여러개 선언하는 것

 

Overloading

 

2. 인스턴스 멤버와 정적 멤버

=> 언제 사용해주면 좋을까?! 객체마다 가지고 있어야 할 데이터라면 instance field, 공용적인 데이터라면 static field

 

인스턴스 멤버와 this

- instance member: 객체(instance)를 생성한 후 사용할 수 있는 필드와 메소드 (instance field, instance method)

- 참조변수 this

: 인스턴스 자신을 가리키는 참조변수
: 인스턴스의 주소가 저장되어 있음

 

정적 멤버와 static

- = 클래스 변수 or 메소드 = 정적 변수 or 메소드 = 공용 변수 or 메소드

클래스에 고정된 멤버. 클래스 로더가 클래스(바이트 코드)를 로딩해서 메소드 메모리 영역에 적재할 때 클래스별로 관리. 따라서 클래스 로딩이 끝나면 바로 사용 가능

- 클래스이름.필드 or 클래스이름.메소드(매개변수) 로 접근하여 바로 사용

public class 클래스 {
    static 타입 필드;	// 정적 필드
    static 리턴 타입 메소드(매개변수 ...) {...} // 정적 메소드
}

 

- 정적 초기화 블록: 정적 필드 초기화 작업을 위해 제공

static {
....
}

- 정적 메소드나 정적 블록의 내부에는 인스턴스 필드나 인스턴스 메소드를 사용할 수 없다.
-> 사용하고 싶다면 메소드 안에 객체를 먼저 생성하고 참조변수로 접근

 

 

3. final 필드와 상수

- final 필드: 초기값이 저장되면 최종적인 값이 되어 수정할 수 없는 것

- 초기값 주는 방법: 1) 필드 선언시 2) 생성자 호출시

 

- 상수(final static)

: 불변의 값. 객체마다 저장할 필요가 없는 공용성을 띔.

: final만은 상수는 아님. 객체마다 다른 값을 가질 수 있기 때문

: static block으로 초기화 가능

: 상수 이름은 대문자로 작성이 관례

 

 

4.  패키지

- 자바에서는 클래스를 체계적으로 관리하기 위해 패키지(package)를 사용

- 패키지의 물리적인 형태는 파일 시스템 폴더

- 클래스 이름이 동일하더라도 패키지가 다르면 다른 클래스로 인식.

=> 클래스의 전체 이름: 상위패키지.하위패키지.클래스

- 소문자로 작성하는 것이 관계

 

 

5. 접근 제한자(access modifier)

접근 제어자가 사용될 수 있는 곳 - 클래스, 멤버변수, 메서드, 생성자

 

- public: 접근 제한 없음

- protected: 같은 패키지내에서, 다른 패키지의 자손클래스에서 접근 가능

- default: 같은 패키지내에서만 접근 가능

- private: 같은 클래스내에서만 접근 가능

 

...더보기

제어자의 조합

  1. 메서드에 static과 abstract를 함께 사용할 수 없다.
    - static메서드는 몸통(구현부)이 있는 메서드에만 사용할 수 있기 때문
  2. 클래스에 abstract와 final을 동시에 사용할 수 없다.
    - 클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고, abstract는 상속을 통해서 완성되어야 한다는 의미이므로 서로 모순되기 때문
  3. abstract메서드의 접근제어자가 private일 수 없다.
    - abstract메서드는 자손클래스에서 구현해주어야 하는데 접근 제어자가 private이면, 자손클래스에서 접근할 수 없기 때문
  4. 메서드에 private과 final을 같이 사용할 필요 없음
    - 접근 제어자가 private인 메서드는 오버라이딩될 수 없기 때문
    - 이 둘 중 하나만 사용해도 의미가 충분.

 

6. Getter와 Setter 메소드

객체지향 프로그래밍에서는 외부에서 직접적으로 객체의 데이터 접근을 막는다.

-> 객체의 무결성(결점이 없는 성질)이 깨질 수 있기 때문. - 매개값을 검증해서 유효한 값만 데이터 저장함.

 

: 메소드를 통해서 데이터 변경 => Getter / Setter

 

 

7. Inner class

: 특정 클래스 내에서만 주로 사용되는 클래스를 내부 클래스로 선언

: 장점: 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근가능, 코드의 복잡성 줄일 수 있음(캡슐화)

 

특징

  • 클래스 내부에 또 다른 클래스를 가짐으로 클래스 관리의 효율을 높인 것
  • 형식과 생성파일
    - 형식: class Outer { class Inner {...} } 
    - 생성파일) Outer.class, Outer$Inner.class
  • 객체 생성
    - Outer.Inner oi = new Outer().new Inner();
class InnerEx1 {
	class InstanceInner {
    	int iv = 100;
        // static int cv = 100;		// *error! static 변수 선언할 수 없음.*
        final static int CONST = 100;	// *final static은 상수이므로 허용*
    }
    
    static class StaticInner {
    	int iv = 200;
        static int cv = 200;		// *static class만 static 멤버 정의 가능*
    }
    
    void myMethod() {
    	class LocalInner {
        	int iv = 300;
            // static int cv = 300;	// error! static 변수 선언할 수 없음.
            final static int CONST = 300; // final static은 상수이므로 허용
        }
    }
}

 

Anonymous inner class (익명 중첩 클래스)

  • - 기존 클래스의 특정 메서드를 오버라이딩하여 원하는 형태로 재정의하여 사용하는 방식
    - 외부 멤버 중 final만 포함할 수 있음.
  • 형식과 생성파일
    - 형식: class Outer {method() { new Inner() { ... }}}
    - 생성파일: Outer.class, Outer$숫자.class
  • 객체 생성: new Inner() 자체가 객체 생성임.
import java.awt.*;
import java.awt.event.*;

class InnerEx8 {
	public static void main(String[] args) {
    		Button b = new Button("Start");
        	b.addActionListener(new ActionListener() {
        		public void actionPerformed(ActionEvent e) {
            		System.out.println("ActionEvent occured!");
            	}
        	});	// 익명 클래스의 끝
	} // main메서드의 끝
} // InnerEx8클래스의 끝

 

7. 어노테이션(Annotation)

추가예정

 

목차

  1. Variable (변수)
  2. Primitive Type (기본 타입)
  3. Reference Type (참조 타입)

1. Variable (변수)

하나의 값을 저장할 수 있는 메모리 공간

int score; 	// 공간 할당
score = 90; 	// 값 저장

Literal: 직접 입력된 값

  • 정수 리터럴
    - 10진수(기본), 8진수(0으로 시작), 16진수(0x or 0X로 시작)
    - byte, char, short, int, long
  • 실수 리터럴
    - ex) 3e6 // 3*10⁶ (e or E: 10의 지수)
    - float, double
  • 문자 리터럴
    - 작은 따옴표(‘’)로 묶은 텍스트, 하나의 문자 리터럴
    - escape character: 역슬래쉬(\)가 붙은 문자 리터럴 ex) ‘\t’, ‘\n’ …
    - char
  • 문자열 리터럴
    - 큰 따옴표(“”)로 묶은 텍스트
    - String
  • 논리 리터럴
    - boolean

 

2. Primitive Type (기본 타입)

  • Java언어에 이미 존재하고 있는 데이터 타입
  • 실제값 변수에 저장

메모리 사용 크기(정수타입): -2^(n-1) ~ 2^(n-1)-1

정수 타입

  • char Type
    - 2 byte
    - 자바는 모든 문자를 유니코드(Unicode)로 처리 (Unicode:세계 각국의 문자들을 코드값으로 매핑한 국제 표준 규약)
    - 0 ~ 127까지는 ASCII 문자 할당
    - 음수 저장 안됨
char var1 = 'A' // 유니코드 0x0041 -> 2진수: 00000000 01000001
char var2 = 65;
char var3 = '\u0041';  // '\u + 16진수값'

 

  • int Type
    - 변수에 어떤 진수(10,8,16진수)를 입력하더라도 동일한 값이 2진수로 변환되어 저장
  • long Type
    - 수치가 큰 데이터를 다루는 프로그램에서 필수적
    - 변수 초기화: 정수값 뒤에 l 또는 L 붙임.

실수 타입

  • float과 double의 메모리 사용 크기는 각각 int와 long의 크기와 같지만, 정수 타입과는 다른 저장 방식 때문에 훨씬 더 큰 범위의 값을 저장할 수 있음.
  • 자바의 실수 리터럴의 기본 타입: double

 

타입 변환 (Type Casting)

  • 자동 타입 변환 (promotion) : 큰 크기 타입 <- 작은 크기 타입 (메모리 크기)
    - byte(1) < short(2) < int(4) < long(8) < float(4) < double(8)
      float가 뒤인 이유?! 표현할 수 있는 값의 범위가 float이 더 크기 때문
    - char type의 경우 int type으로 자동 변환. 
     but! 음수 저장이 안되므로 byte타입은 자동 변환 안됨.
char charValue = 'A';
int intValue = charValue; // 65 저장
byte byteValue = 65;
char charValue2 =byteValue; // compile error

 

  • 강제 타입 변환

강제 타입 변환에 의한 값 손실

 

자바는 코드에서 데이터 값을 검사하기 위해 boolean과 char을 제외하고 모든 기본 타입에 대해 최대값과 최소값을 상수로 제공

// 값의 손실이 발생하는지 체크
if ( (i<Byte.MIN_VALUE) || (i>Byte.MAX_VALUE)) {
 // 값 손실 발생
}

 

3. Reference Type (참조 타입)

  • Array, Enum, Class, Interface 
  • 변수(스택)에 메모리 번지를 저장 -> 실제 값은 힙영역에 저장
  • 참조 변수에서의 ==, != : 주소값 비교 연산
  • null: 힙 영역의 객체를 참조하지 않는다 (참조 타입 변수에서 사용)
    NullPointerException:  참조타입 변수가 null을 가지고 있을 경우(사용할 수 없는 경우) 접근할 때 생기는 오류
  • new 연산자 (객체 생성 연산자): 힙영역에 새로운 객체를 만드는 연산자 

참조변수의 형변환

- Up-casting: 조상 <- 자손 : 자동형변환 (생략 가능)

- Down-casting: 조상 -> 자손  : 강제 형변환 

 

String

- 자바는 문자열 리터럴이 동일하다면 String객체를 공유

 

String name1 = "신용권";

String name2 = "신용권";

 

Array

  • 다차원 배열: 
    int[][] a = new int[2][3]             // 2(행)*3(열) 배열
    int a[][] = {{1,2,3,4,5}, {11,12,13,14,15}, {21,22,23,24,25}}; // {{ -> 차원의 개수
  • element별로 다른 길이의 배열을 가질 수 있음.
    int a[][] = {{1,2}, {1,2,3}};
  • 배열 복사
    System.arraycopy(a, 1, b, 0, a.length-1); // SourceArray, SPosition, TargetArray, TPosition, length
  • Shallow copy(얕은 복사) vs. Deep copy(깊은 복사) -> 추후 예정

element는 힙영역에 할당됨

 

Enum

- ...

 

 

 

 

 

 

 

Ref. 이것이 자바다 - 신용권의 Java 프로그래밍 정복

목차

  1. 자바 특징
  2. JDK (Java Development Kit)
  3. JVM (Java Virtual Machine)
  4. 자바 프로그램 실행 단계
  5. 메모리 사용 영역

1. 자바 특징

1) 이식성이 높은 언어

2) 객체지향 언어

3) 함수적 스타일 코딩 지원

4) 메모리를 자동으로 관리 : 개발자가 직접 메모리에 접근할 수 없도록 설계. 객체 생성 시 자동적으로 메모리 영역을 찾아서 할당하고, 사용이 완료되면 Garbage collector를 실행시켜 자동적으로 사용하지 않는 객체를 제거

5) 멀티스레드를 쉽게 구현

6) 동적 로딩을 지원

 

 

2. JDK (Java Development Kit)

1) JDK 란?

- 자바 프로그램 개발 도구 
- 개발을 위한 클래스, 컴파일러, 실행 및 배포도구를 포함 등 개발을 위한 전반적인 환경 제공

 

2) 플랫폼

- 프로그래밍이나 컴퓨터 실행을 위한 기본적인 기능을 제공하는 것.
- Java의 JVM은 이런 다양한 플랫폼 위에서 동일한 Java 소스코드를 이용할 수 있는 환경 제공
- 플랫폼 종류: J2SE(Java 2 Standard Edition), J2EE(Java 2 Enterprise Edition), J2ME(Java 2 Micro Edition)

 

3) JDK 디렉터리 구조

JDK 디렉터리 구조

 

4) JVM, API, JRE, JDK 관계

- JDK(Java Development Kit) = JRE + 개발에 필요한 도구
- JRE(Java Runtime Environment) = JVM + 표준 클래스 라이브러리

JVM, API, JRE, JDK 관계

 

 

3. JVM (Java Virtual Machine)

자바 프로그램은 완전한 기계어가 아닌, 중간 단계의 바이트 코드이기 때문에 이것을 해석하고 실행할 수 있는 가상의 운영체제(JVM)가 필요

 

- 장점: Write once, run anywhere.

- 단점: 한번의 컴파일링으로 실행 가능한 기계어가 만들어지지 않고 JVM에 의해 기계어로 번역되고 실행되기 때문에, C와 C++의 컴파일 단계에서 만들어지는 완전한 기계어보다는 속도가 느림.

 

 

 

4. Java 프로그램 실행 단계

javac Hello.java	// 1) 컴파일러(javac.exe)로 자바 소스 파일 컴파일, *.class 파일 생성
java Hello		// 2) JVM을 구동시키는 명령어(java.exe)

1) Java 소스 파일을 컴파일러로(javac.exe)로 컴파일하면 확장자가 .class인 바이트 코드 파일이 생성됨. 
2) java.exe 명령어가 실행되면서 JVM은 바이트 코드 파일(Hello.class)을 메모리로 로드하고, 해당 운영체제에 맞게 기계어로 번역. 그리고 main() 메소드를 찾아 실행

 

main() method

- Program entry point (실행 진입점)
- java.exe로 JVM을 구동시키면 제일 먼저 main() 메소드를 찾아서 실행시킴.

 

자바 실행 단계
자바 실행 단계(자세히)

 

프로그램 동작 순서

 

5. 메모리 사용 영역

java.exe로 JVM이 시작되면 JVM은 운영체제에서 할당받은 메모리영역(Runtime Data Area)을 다음과 같이 세부 영역으로 구분하여 사용

=> 메소드 영역, 힙 영역, JVM 스택 영역

 

메소드 영역

  • 코드에서 사용되는 클래스(~.class)들을 클래스 로더로 읽어 클래스별로 런타임 상수풀(runtime constant pool), 필드(field) 데이터, 메소드(method) 데이터, 메소드 코드, 생성자(constant) 코드 등을 분류하여 저장.
  • JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역

 

힙 영역

  • 객체와 배열이 생성되는 영역
  • JVM 스택 영역의 변수나 다른 객체의 필드에서 참조
  • 참조하는 변수나 field가 없으면 Garbage Collector를 실행시켜 쓰레기 객체를 힙 영역에서 자동으로 제거

 

JVM 스택 영역 (-> Frame -> 로컬 변수 스택)

  • 각 스레드마다 하나씩 존재. 스레드가 시작될 때 할당
  • 기본적으로 main thread가 존재(JVM 스택도 하나)
  • Frame: JVM stack의 element
    - method를 호출할 때 마다 Frame을 추가(push)하고 method 종료되면 해당 Frame 을 제거(pop)하는 동작 수행
    - 예외 발생시 printStackTrack() method
  • 로컬 변수 스택: Frame 내부에 존재
    - 기본 타입 변수와 참조 타입 변수가 추가(push)되거나 제거(pop)됨.
    - 변수가 이 영역에 생성되는 시점은 초기화될 때, 즉 최초로 변수에 값이 저장될 때.

메모리 사용 영역

 

Ref. 이것이 자바다 - 신용권의 Java 프로그래밍 정복

+ Recent posts