지금까지 배운 내용들로

다양한 클래스들을 이해해보겠다.

자바에는 다양한 클래스들을 지원해주는데
오늘 알아볼 클래스는
 Wrapper, BIgInteger, BigDecimal, 난수 생성 함수, 문자열 토큰 이다.

1. Wrapper 클래스

Wrapper 클래스는 기본 자료형의 데이터를 인스턴스화 시키는 클래스이다.
Wrapper란 말 그대로 감싸고 있다는 것이다.

데이터 클래스를 의미한다.

이런걸 Boxing 이라고 하고 반대는 Unboxing이라고한다.
자바5.0부터는

Auto Boxing, Auto Unboxing이 지원 되서
클래스 생성선언 없이도 바로 생성되어 지원된다.

ex)


Integer iValue = 10; // auto boxing
Double dValue = 3.14;
int num1 = iValue; // auto unboxing
double num2 = dValue;


문제 20-1
static 메소드를 이용하여  Boxing 해보아라.

(valueOf(); 메소드 사용)





(실행 화면)



이러한 Wrapper 클래스안에 valueOf 의 메소드가 있다. 이 값을 이용하면 Wrapper 클래스의 인스턴스를 생성할 수 있다.

그런데 결과 화면을 보면 동일한 인스턴스라고 나온다.

저장되는 데이터는 문자열과 같이 수정이 불가능하다. 그렇기 때문에 메모리 효율 상 같은 인스턴스를 여러개 만들 필요가 없는것이다.
값을 변경하려면 새로운 인스턴스를 만들어 참조값을 변경해주면 된다.

현재 iValue1 과 iValue2는 같은 인스턴스를 참조하고 있다.


2. BigInteger, BigDecimal 클래스
매우 큰 수( BigInteger)
가장 표현범위가 넓은 long형으로도 표현이 불가능한 수를 표현할때 사용한다.
ex)

BigInteger bigValue1 = new BigInteger("10000000000000000000000000000");


왜 입력을 문자열로 넣을까?
그 이유는 정수로 넣게되면 그 정수를 옯겨줄 매개변수가 필요한데
가장큰 long형으로도 커버가 안되기 때문에
문자열로 입력해야하는 것이다.

BigDecimal
-> 정확한 소수점 표현

처음 자료형을 배울때 float나 double의 소수점 표현에
오차가 있다고 말했다.
하지만 오차가 없게 표현하려면
BigDecimal 함수를 사용하면 된다.
BigInteger와 같이 문자열로 입력된다.

문제 20-2
두 개의 실수를 입력받아 두 실수의 차를 절대값으로 계산하시오.




(BigDeciaml 이용 코드)




(실행화면)



결과를 보면 오차없이 계산된 것을 확인 할 수 있다.

3. 난수 생성

JAVA에는 java.util 패키지로 Random 클래스를 제공한다.
- boolean nextBoolean()   : boolean형 난수 반환
- int nextInt() : int형 난수 반환
- long nextLong() : long형 난수 반환
- int nextInt(int n) : 0이상 n미만의 범위 내에있는 int형 난수 반환
- float nextFloat() : 0.0 이상 1.0 미만의 float형 난수 반환
- double nextDouble() : 0.0 이상 1.0 미만의 double형 난수 반환

괄호() 안에는 seed 값이 들어간다.
default 값은 System.currentTimeMillis() 이다.
시간에 관련한 seed 값이 들어간다.

4. 문자열 토큰

- 문자열에서 구분자를 이용해 문자열을 구분하는 방법이다.
ex)
14:99 
위 글자에서 ' : ' 를 구분자로 하여 14와 99를 구분할 수 있다.


StringTokenizer st = new StringTokenizer("14:99", ":");

public String nextToken() // 다음 토큰 반환 메서드




(*참조 - 난 정말 JAVA를 공부한 적이 없다구요, 윤성우)





Layer 1 - 물리적인 전송을 담당한다.
            - 전기 신호
 ex) 허브에 스타토폴로지로 host들이 연결되있다.
 한 host에서 전기신호를 보내고 그 전기신호를 수신하여서 데이터를 주고받는다.

Layer 2 - 데이터 링크 계층
 
 - 터널링관련 프로토콜 : PPP, L2TP, ...
 - 라우팅이 필요하지 않는 계층
 - 라우팅없이도 통신이 가능하다.
- 이더넷, 토큰링방식
 토큰링 방식 (토큰을 가진사람만 보낼 수 있고, 그 토큰은 네트워크를 돌아다닌다., 충돌을 예방하는 방법이다.)
  - 단점 : 토큰이 돌아서 내 차례가 될때까지가 오래걸린다.
 이더넷 : Collison Domain (충돌을 이용한다.)
 이더넷 헤더 (고정 : 14바이트)
 -우리는 보통 이더넷을 사용한다.

* 각 계층별 주소
L4 - Port Number
L3 - IP Address
L2 - MAC 주소. (Media Access Control) : 하드웨어 주소
 - 16진수 6자리  (유일한 주소)

 L2까지 합하면 패킷의 구성은
 
   - 이더넷 + IP + TCP/UDP + 데이터

지금까지 IP, TCP/UDP, 데이터까지 보았다.
 
기존에 만들었던건 윈도우즈 소켓을 이용해 패킷을 덤프했던 것이다.
이 윈도우즈소켓으로는 L3까지밖에 확인이 안된다.
그래서
L2까지 보기위해 다른 방법을 사용해보겠다.

새로 만든 모듈을 이용했다.



(모듈로 설정한 get_device)





(실행화면)



어떤 장치로 들어오고 나가는 내용을 화면에 출력할지를 정해야한다.
화면에서 Microsoft 라고 나온것이 무선어댑터 지금 사용하는 것이다.

 실행하면 인터페이스를 선택하라고 나온다.
이 때 여기서 나오는 인터페이스란

제어판에서 네트워크 정보에갔을 때 나오는 목록이다.
이 목록은 컴퓨터의 네트워크 장치이다.
이제 이 장치로부터 패킷을 가져와 열어보겠다는 것이다.





(두개의 어댑터)



이 화면은 집마다 다르다.

여기서 전에 소켓통신했던것과 유사하게
핸들러(장치를 다룰) 를 선언했다. 소켓과 비슷한 역할이다.

그 후 전에 덤프 프로그램과 비슷하게 작성해준다.



(패킷을 덤프받아 출력하는 코드)



이렇게 하면 전에 사용했던 프로그램과 비슷한 모양의 코드가 된다.



(실행 화면)



출력을 해보면 데이터가 출력된다.
캡쳐된 내용을 보면 앞에 14바이트 빼고는 지금까지 봤던 정보들이다.

앞에 14바이트는 이더넷프레임이다.


['0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0x90', '0x9f', '0x33', '0xeb', '0x34', '0xa1', '0x8', '0x0']

분석해보면
1. 도착지 맥주소(6바이트) :  0xff', '0xff', '0xff', '0xff', '0xff', '0xff
2. 출발지 맥주소(6바이트) : '0x90', '0x9f', '0x33', '0xeb', '0x34', '0xa1'
3. 프로토콜 타입(2바이트) : '0x8', '0x0'
                                          - 0x0800 -> IPv4  , IP 프로토콜
                                            0x8600 -> IPv6
                                            0x0806 -> ARP 프로토콜

통신을 하려면 MAC주소를 알아야한다. 하지만 우리는 IP주소만 알고있다.
그렇기 때문에
ARP 가 필요하다.
ARP : Address Resolution Protocol

이제 전에 작성했던 프로그램에서 L2까지 나오는프로그램으로 확장시켜본다.



(확장 코드)




(출력 화면)


출력 화면을 보면 이제 L2의 프레임 단위로 패킷을 확인할 수 있는것을 볼 수 있다.

이제 내일부터
이 내용을 가지고 네트워크를 살펴보겠다.





그렇다면 스택영역과 힙역역을 왜 구지 나누었을까?
-> 그 이유는 인스턴스 소멸시기와 지역변수 소멸시기가 다르기 때문이다.

* Object 클래스

- finalize 메소드
모든 Object 클래스에는 finalize 메소드가 있다. 이 finalize메소드는 함수가 소멸되기 전에 반드시 실행되어야하는 코드다.
인스턴스를 지칭하는 참조변수가 사라진다고해서
바로 사라지는 것은 아니다. 너무 빈번하게 일어나면 프로그램 성능에 문제가 될 수 있기 때문이다.

그래서 finalize를 인스턴스가 사라질때 반드시 실행시키고 싶다면,
System.gc();
System.runFinalization(); 
이 코드를 적어주면 된다.

- equals 메소드
== 연산자는 참조변수의 참조 값을 비교한다.
문제 19-1
equals 메소드를 삽입해 참조 내용을 비교해보자.



(equal 오버라이딩)





(equal 오버라이딩)




(비교 코드)




(실행 화면)



* 인스턴스 복사 clone

인스턴스를 복사하기 위한 메소드가 정해져있다.
protected Object clone() throws CloneNotSupportedException

이란 메소드로 정해져있다.

이 메소드를 쓰기위해서는 Cloneable 인터페이스를 구현해야한다.

왜냐하면 프로그래밍을 하다보면 복사에 민감한, 인스턴스들도 있다. 그런것과 복사해도 되는 것을 구별하기 위해서 표현하기 위해서
Cloneable 인터페이스를 구현하는지를 확인한다.

여기서 중요한건 clone으로 복사되는데
그 안의 변수들도 복사가 된다.
하지만 그 인스턴스 내부의 인스턴스는 복사되지 않으니 같은 참조값으로써 복삭가 된다.

결론적으로 말하면
인스턴스를 완전히 복사하기 위해서는
내부 인스턴스들 또한 같이 복사해줘야한다.

문제 19-2를 보면 이해가 될것이다.


(Business 클래스 복사)




(PersonalInfo를 복사하고 그 내부의 Business 클래스 복사)




이렇게 내부도 복사해주어야

중간에 값을 변경해도 다른 복사본에 영향을 주지 않는다.



(복사 후 내부 문자열을 바꾸는 내용)



(실행화면)



내부 문자열을 변경했어도 복사본에 영향이 없음을 확인 할 수 있다.

(*참조 - 난 정말 JAVA를 공부한 적이 없다구요, 윤성우)



+ Recent posts