|
'Back-End'에 해당되는 글 287건
- 2019.04.17 19.04.17 제네릭,와일드카드
- 2019.04.16 19.04.16 멀티 스레드
- 2019.04.15 19.04.15 String클래스 메소드, 정규 표현식, 배열정렬 및 검색, 박싱,언박싱
- 2019.04.14 19.04.14 객체 소멸자, 객체 비교, 동등 비교 등
- 2019.04.12 19.04.12 API, java.lang / java.util 패키지, 해시코드
- 2019.04.10 19.04.10 추상 클래스 / 메소드, 인터페이스
- 2019.04.09 19.04.09 상속, final
- 2019.04.08 19.04.08 어노테이션,Getter / Setter 메소드
Back-End/Java 2019. 4. 17. 17:47
-제네릭의 사용-
제네릭은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법. class Person <T>{ public T info; } Person<String> p1 = new Person<String>();
//<>안에 있는 String이 T자리에 들어간다고 생각하면 된다. 즉 데이터 타입을 외부에서 지정하는 기법을 의미한다.
복수의 제네릭을 사용할 때는 <T,S>처럼 가운데 콤마를 찍고 사용한다. (ex. class Person <T,S>) 그리고 참조 형식은 < >안에 들어갈 수 있고, {기본데이터 타입 = 값 형식}(int,char,float 등)은 java내에서 객체를 가지고 있지 않기 때문에 올 수 없고, 기본 데이터 타입을 포장한 포장(wrapper) 클래스 데이터 타입(integer 등)이 올 수 있다.
-예제 및 출력 결과-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 |
package com.hs.chap13;
public class Box<T, R> {
private T t;
private R r;
public T get0() {
return this.t;
}
public void set0(T t) {
this.t = t;
}
public R get1() {
return this.r;
}
public void set1(R r) {
this.r = r;
}
public static <U> void set2(U u) {
System.out.println("제네릭 메소드가 실행되었습니다.");
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
package com.hs.chap13;
public class BoxExample {
public static void main(String[] args) {
Box<String,Integer> box1 = new Box<String,Integer>(); //멀티 제네릭 타입 사용 T와 R을 각각 String 타입과,Integer 타입으로 지정
box1.set0("안녕하세요.");
box1.set1(3);
System.out.println("제네릭 타입변환 문자 출력 : "+box1.get0());
System.out.println("제네릭 타입변환 숫자 출력 : "+box1.get1());
Box<Integer,String> box2 = new Box<Integer,String>(); //위에와 반대로 멀티 제네릭 타입 사용 T와 R을 각각 Integer 타입과,String 타입으로 지정
box2.set0(78);
box2.set1("반갑습니다.");
System.out.println("제네릭 타입변환 문자 출력 : "+box2.get1());
System.out.println("제네릭 타입변환 숫자 출력 : "+box2.get0());
}
}
|
cs |
-제네릭 메소드-
제네릭 메소드는 매개 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드를 말한다. 제네릭 메소드를 선언하는 방법은 리턴 타입 앞에 <> 기호를 추가하고 타입 파라미터를 기술한 다음, 리턴 타입과 매개 타입으로 타입 파라미터를 사용하면 된다.
-예제 및 출력결과-
|
package com.hs.chap13;
public class Util {
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
boolean keyCompare = p1.getKey().equals(p2.getKey());
boolean valueCompare = p1.getValue().equals(p2.getValue());
return keyCompare && valueCompare;
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 |
package com.hs.chap13;
public class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public void setKey(K key) {
this.key = key;
}
public void setValue(V value) {
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
package com.hs.chap13;
public class CompareMethodExample {
public static void main(String[] args) {
Pair<Integer, String> p1 = new Pair<Integer, String>(1, "사과");
Pair<Integer, String> p2 = new Pair<Integer, String>(1, "사과");
boolean result1 = Util.<Integer, String>compare(p1, p2);
System.out.println(result1);
if (result1) {
System.out.println("p1과 p2는 논리적으로 동등한 객체 입니다.");
} else {
System.out.println("p1과 p2는 논리적으로 동등하지 않는 객체입니다.");
}
Pair<String, String> p3 = new Pair<String, String>("user1", "홍길동");
Pair<String, String> p4 = new Pair<String, String>("user2", "홍길동");
boolean result2 = Util.compare(p3, p4);
System.out.println(result2);
if (result2) {
System.out.println("p3과 p4는 논리적으로 동등한 객체 입니다.");
} else {
System.out.println("p3과 p4는 논리적으로 동등하지 않은 객체 입니다.");
}
}
}
|
cs |
-제네릭 제한-
extends 키워드를 사용하면 제한할 수 있다. < >안에서 extends가 사용되면 상속한다는 뜻이 아니라 부모가 누구인지 표시한다.
EX) class Person <T extends Info>는 T에 데이터 타입을 판단할때 Info클래스에 있는 것들만 쓸 수 있도록 하는 것이다. (제한을 하는 이유 : 아무 값이나 들어오면 오류가 발생될 수 있기 때문에)
-제네릭 메소드-
제네릭 메소드는 매개 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드를 말한다. 제네릭 메소드를 선언하는 방법은 리턴 타입 앞에 <> 기호를 추가하고 타입 파라미터를 기술한 다음, 리턴 타입과 매개 타입으로 타입 파라미터를 사용하면 된다.
abstract class Info{ //Info라는 이름의 추상클래스 생성 public abstract int getLevel(); //getLevel()이라는 메소드 구현
- 와일드 카드 타입 -
코드에서 ?를 일반적으로 와일드카드(wildcard)라고 부른다. 제네릭 타입을 매개값이나 리턴 타입으로 사용할 때 구체적인 타입 대신에 와일드 카드를 사용할 수 있다.
제네릭 타입 <?> : Unbounded Wildcards (제한 없음) 타입 파라미터를 대치하는 구체적인 타입으로 모든 클래스나 인터페이스 타입이 올 수 있다.
제네릭 타입 <? extends 상위타입> : Upper Bounded Wildcards (상위 클래스 제한) 타입 파라미터를 대치하는 구체적인 타입으로 상위 타입이나 하위 타입만 올 수 있다.
제네릭 타입 <? super 하위타입> : Lower Bounded Wildcards (하위 클래스 제한) 타입 파라미터를 대치하는 구체적인 타입으로 하위 타입이나 상위 타입이 올 수 있다.
-제네릭 타입의 상속과 구현-
제네릭 타입도 부모 클래스가 될수 있고, 자식 제네릭 타입은 추가적으로 타입 파라미터를 가질 수 있다.
Back-End/Java 2019. 4. 16. 13:48
-멀티 스레드-
애플리케이션 내부의 멀티 태스킹 즉 프로세스 내부에서 두 가지 작업을 동시에 실행하는것. 멀티 스레드는 하나의 프로세스 내부에 생성되기 때문에 하나의 스레드가 예외를 발생시키면 프로세스 자체가 종료될 수 있어 다른 스레드에게 영향을 미치게 된다.
-스레드의 구현과 실행-
1. Thread 클래스 상속 2. Runable 인터페이스 구현
-멀티 스레드 장,단점-
장점
-자원을 보다 효율적으로 사용할 수 있음 -작업이 분리되어 코드가 간결해 짐
단점
-교착상태가 발생하지 않도록 주의해야 한다.
- 예제 및 출력 결과 -
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
package com.hs.chap12;
public class BeepPrintExample extends Thread {
// 생성자 정의
public BeepPrintExample(String name) {
super(name);
}
// 현재 실행중인 스레드의 이름을 출력한다.
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
BeepPrintExample a0 = new BeepPrintExample("스레드 1");
BeepPrintExample a1 = new BeepPrintExample("스레드 2");
BeepPrintExample a2 = new BeepPrintExample("스레드 3");
a1.setName("스레드 50");
a0.start();
a1.start();
a2.start();
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
package com.hs.chap12;
public class MyThread extends Thread {
//생성자 추가
public MyThread (String name)
{
super(name);
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
//현재 실행중인 스레드의 이름
System.out.println(Thread.currentThread().getName());
}
try {
Thread.sleep(1500); //실행을 멈추는 거기때문에 예외처리가 반드시 필요
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13 |
package com.hs.chap12;
public class ExternThread {
public static void main(String[] args) {
MyThread t1 = new MyThread("스레드1");
MyThread t2 = new MyThread("스레드2");
t1.start();
t2.start();
}
}
|
cs |
-스레드의 이름-
Thread 클래스의 setName()메소드로 스레드의 이름을 변경 Thread 클래스의 getName()메소드로 스레드의 이름을 알수 있다.
-스레드 우선순위-
동시성: 멀티 작업을 위해 하나의 코어에서 멀티 스레드가 번갈아가며 실행하는 성질
병렬성: 멀티 작업을 위해 멀티 코어에서 개별 스레드를 동시에 실행하는 성질
스레드 스케줄링 : 스레드의 개수가 코어의 수보다 많을 경우, 스레드를 어떤 순서에 의해 동시에 실행할 것인가를 결정
(짧은 시간에 번갈아가면서 run() 메소드를 조금씩 실행함)
-동기화 메소드 및 동기화 블록-
임계 영역 = 멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있는 코드 영역, 임계 영역을 지정하기 위해 동기화 메소드와 동기화 블록을 제공한다. 형식 : 메소드선언에 synchronized 키워드를 붙이면 된다.
-스레드 상태-
실행 대기 상태 : 스케줄링이 되지 않아서 실행을 기다리고 있는 상태 실행 상태 : 실행 대기 상태에 있는 스레드 중에서 선택된 스레드가 run() 메소드를 실행한 상태
실행 종료 상태 : 실행 상태에서 run() 메소드가 종료되면 스레드의 실행이 멈추게 되는 상태
-스레드 상태 확인-
getState() 메소드는 스레드 상태에 따라서 Thread.State 열거 상수를 리턴한다.
-Thread 클래스 메소드-
sleep() : 주어진 시간동안 일시 정지 yield() : 다른 스레드에게 실행 양보 join() : 다른 스레드의 종료를 기다림
notify() : 일시 정지 상태에 있는 다른 스레드를 실행 대기 상태로 만듬
-데몬 스레드-
주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드이다. 주의할 점은 start() 메소드가 호출되고 나서 setDaemon(true)를 호출하면 예외가 발생하기 때문에 start() 메소드 호출 전에 setDaemon(true)를 호출해야 한다.
-스레드 그룹-
관련된 스레드를 묶어서 관리하는 것 스레드 그룹을 생성하는 방법은 다음 생성자 중 하나를 이용해서 스레드그룹 객체를 만들면 된다.
ThreadGroup tg = new ThreadGroup(String name); ThreadGroup tg = new ThreadGroup(ThreadGroup parent, String name);
-예제 및 출력 결과-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 |
package synchronization;
public class WorkThread extends Thread {
public WorkThread(ThreadGroup threadGroup, String threadName) {
super(threadGroup, threadName);
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(getName() + "interrupted");
break;
}
}
System.out.println(getName() + "종료됨");
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
package synchronization;
public class ThreadGroupExample {
public static void main(String[] args) {
ThreadGroup myGroup = new ThreadGroup("myGroup");
WorkThread workThreadA = new WorkThread(myGroup, "workThreadA");
WorkThread workThreadB = new WorkThread(myGroup, "workThreadB");
workThreadA.start();
workThreadB.start();
System.out.println("[main 스레드 그룹의 list()메소드 출력 내용]");
ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
mainGroup.list();
System.out.println();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println("[myGroup 스레드 그룹의 interrupt()메소드 호출]");
myGroup.interrupt();
}
}
|
cs |
-스레드풀-
작업 처리에 사용되는 스레드를 제한된 개수만큼 정해 놓고 작업 큐에 들어오는 작업들을 하나씩 스레드가 맡아 처리한다.
java.util.concurrent 패키지에서 ExecutorService 인터페이스와 ExecutorService 구현 객체를 만들 수 있는데, 이것이 바로 스레드풀이다.
-작업 생성-
하나의 작업은 Runnable 또는 Callable 구현 클래스로 표현한다. Runnable과 Callable의 차이점은 작업 처리 완료 후 리턴값의 유무이다. Runnable의 run() 메소드는 리턴값이 없고, Callable의 call() 메소드는 리턴값이 있다.
-작업 처리 요청-
ExecutorService의 작업 큐에 Runnable 또는 Callable 객체를 넣는 행위를 말한다.
-중요 예제-
Back-End/Java 2019. 4. 15. 17:54
-인코딩-
문자를 컴퓨터에 저장하거나 통신할 목적으로 부호화 하는것
-디코딩-
인코딩한 문자를 원래대로 되돌리는 것
-bytes 배열로 변환-
getBytes()메소드는 시스템의 기본 문자셋으로 인코딩된 바이트 배열을 리턴.
getBytes(Charset charset)메소드는 특정 문자셋으로 인코딩된 바이트 배열을 리턴할때 사용. ㄴ잘못된 문자셋을 매개값으로 줄 경우, java.io.UnsupportedEncodingException 예외가 발생하므로 예외 처리가 필요하다.
-문자열 찾기 (indexOf())-
매개값으로 주어진 문자열이 시작되는 인덱스를 리턴.
-문자열 대치 (replace())-
replace()메소드는 첫 번째 매개값인 문자열을 찾아 두번째 매개값인 문자열로 대치한 새로운 문자열을 생성하고 리턴한다.
-문자열 잘라내기(substring())-
주어진 인덱스에서 문자열을 추출한다.
-알파벳 소,대문자 변경(toLowerCase(), toUpperCase())-
toLowerCase()메소드 : 문자열을 모두 소문자로 바꾼 새로운 문자열을 생성한 후 리턴한다.
toUpperCase()메소드 : 문자열을 모두 대문자로 바꾼 새로운 문자열을 생성한 후 리턴한다.
-문자열 앞뒤 공백 잘라내기(trim())-
문자열의 앞뒤 공백을 제거한 새로운 문자열을 생성하고 리턴한다.
-문자열 변환(valueOf())-
기본 타입의 값을 문자열로 변환하는 기능을 가지고 있다.
-라인 피트(/n)-
줄바꿈 문자
-캐리지 리턴(/r)-
행 앞으로 되돌아가는 데 사용되는 기능 키. 현재는 대부분 개행/복귀를 하도록 되어 있다.
-예제 및 출력 결과-
(여러가지 문자열 변환 메소드 사용)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 |
package com.hs.chap11;
public class StringIndexOfExample {
public static void main(String[] args) {
String name0 = "가나다라마바사아";
String name1 = "아저씨";
int indext = name0.indexOf("라마바");
int indexf = name1.indexOf("이한섭");
System.out.println("해당되는 문자열의 인덱스의 값 : " + indext);
System.out.println("해당되는 문자열이 없을때 인덱스의 값 : " + indexf);
String java = "자바 프로그래밍";
String java2 = java.replace("자바", "java");
System.out.println("원래 문자열 : " + java);
System.out.println("replace메소드 사용 변경된 문자열 : " + java2);
String ssn = "880815-1234567";
String firstNum = ssn.substring(0, 6); // 0번 인덱스부터 5번인덱스 까지 출력 (6개)
String secondNum = ssn.substring(5); // (0번~5번 까지는 출력안함) 6번 인덱스부터 마지막 인덱스 까지 출력
System.out.println(firstNum);
System.out.println(secondNum);
String name = "APPLE";
String ename = name.toLowerCase();
String hname = ename.toUpperCase();
System.out.println("원래 문자열 :" + name);
System.out.println("toLowerCase()메소드 사용 바뀐 소문자 문자열 :" + ename);
System.out.println("toUpperCase()메소드 사용 바뀐 대문자 문자열 :" + hname);
if (name.equals(ename)) {
System.out.println("두 문자열은 같습니다.");
} else {
System.out.println("두 문자열은 다릅니다.");
}
}
}
|
cs |
-정규 표현식-
문자 또는 숫자 기호와 반복 기호가 결합된 문자열이다.
문자열이 정해져 있는 형식으로 구성되어 있는지 검증할때 사용한다.
(ex 로그인할때 비밀번호 맞는지 확인, 등등등)
-예제 및 출력결과-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
package com.hs.chap11;
import java.util.regex.Pattern;
public class PatternExample {
public static void main(String[] args) {
String regExp = "(02|010)-(02|123)-(02|4567)";// (02또는010)-(02또는123)-(02또는4567)
String data = "010-123-4567";
boolean result = Pattern.matches(regExp, data); // 패턴 클래스의 매치메소드를 사용해서 regExp와 data를 비교
System.out.println(result);
if (result) {
System.out.println("전화번호가 같습니다.");
} else {
System.out.println("전화번호가 다릅니다.");
}
}
}
|
cs |
-배열 항목 정렬 및 검색-
Arrays.sort() 메소드 = 배열을 오름차순으로 정렬시킴
Arrays.binarySearch() 메소드 = 배열 항목 검색
-예제 및 출력 결과-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
package com.hs.chap11;
import java.util.Arrays;
public class Member {
public static void main(String[] args) {
String[] name = { "홍길동", "김길동", "임꺽정" };
for (int i = 0; i < name.length; i++) {
System.out.println("원래 배열의 원소 name[" + i + "]:" + name[i]);
}
Arrays.sort(name);
for (int i = 0; i < name.length; i++) {
System.out.println("재정렬된 배열의 원소 name[" + i + "]:" + name[i]); // 가나다 순서대로 김길동, 임꺽정, 홍길동 출력됨
}
int index0 = Arrays.binarySearch(name, "김길동");
int index1 = Arrays.binarySearch(name, "임꺽정");
int index2 = Arrays.binarySearch(name, "홍길동");// 임꺽정이라는 단어가 들어있는 인덱스 번호를 출력
System.out.println("인덱스 출력값 : " + index0);
System.out.println("인덱스 출력값 : " + index1);
System.out.println("인덱스 출력값 : " + index2);
}
}
|
cs |
-박싱(Boxing)-
기본 타입의 값을 포장 객체로 만드는 과정
-언박싱(Unboxing)-
포장 객체에서 본 타입의 값을 얻어내는 과정
-예제 및 출력결과-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 |
package com.hs.chap11;
public class BoxingUnboxing {
public static void main(String[] args) {
Integer obj1 = new Integer(100); // Integer은 포장 클래스, 타입을 내부에 두고 포장함
int value1 = obj1.intValue(); // 언박싱
System.out.println("integer형 박싱한 값 : " + obj1);
System.out.println("integer형 언박싱한 값 : " + value1);
Character obj2 = new Character('가'); // Character은 포장 클래스, 타입을 내부에 두고 포장함
char value2 = obj2.charValue(); // 언박싱
System.out.println("Character형 박싱한 값 : " + obj2);
System.out.println("Character형 언박싱한 값 : " + value2);
Integer obj = 100; // 자동 박싱은 포장 클래스 타입에 기본값이 대입될 경우에 발생
int value4 = obj; // 자동 언박싱은 기본 타입에 포장 객체가 대입될 경우에 발생
System.out.println("integer형 자동 박싱한 값 : " + obj);
System.out.println("integer형 자동 언박싱한 값 : " + value4);
System.out.println("equals()결과 : " + obj.equals(value4));
Character obj5 = '나';
char value5 = obj5;
System.out.println("Character형 자동 박싱한 값 : " + obj5);
System.out.println("Character형 자동 언박싱한 값 : " + value5);
System.out.println("equals()결과 : " + obj5.equals(value5));
}
}
|
cs |
Back-End/Java 2019. 4. 14. 21:26
-객체 소멸자-
참조하지 않는 배열이나 객체는 쓰레기 수집기(Garbage Collector)가 힙 영역에서 자동적으로 소멸시킨다. 쓰레기 수집기는 객체를 소멸시키기 직전에 마지막으로 객체의 소멸자(finalize())를 실행시킨다. 소멸자는 기본적으로 실행 내용이 없다.
-객체 비교-
Objects.compare(T a,T b, Comparator<T>c) 메소드는 두 객체를 비교자(Comparator)로 비교해서 int값을 리턴한다.
-동등 비교-
Objects.equals (Object a, Object b)는 두 객체의 동등을 비교한다. 특이한 점은 a와 b가 모두 null일 경우 true를 리턴한다는 점이다. a와 b가 null이 아닌경우는 a.equals(b)의 결과를 리턴한다.
-쓰레기 수집기 (Garbage Collector)-
메모리가 부족하거나 CPU가 한가할때 사용하지 않는 객체를 자동 제거.
-currentTimeMillis(), nanoTime() 메소드-
currentTimeMillis() : 컴퓨터의 시계로 부터 현재 시간을 읽어서 밀리세컨드(1/1000초) 단위의 long값을 리턴 nanoTime() : 컴퓨터의 시계로 부터 현재 시간을 읽어서 나노세컨드(1/10^9초) 단위의 long값을 리턴
-시스템 프로퍼티-
자바를 실행시켰을때 자동 설정되는 시스템의 속성값을 말한다. (ex 운영체제의 종류, 자바프로그램을 실행시킨 사용자 아이디, 자바 버전, 파일경로 등) 시스템 프로퍼티를 읽어오기 위해서는 System.getProperty() 메소드를 이용하면 된다.
-동적 객체 생성(newlnstance())-
Class 객체를 이용하면 new 연산자를 이용하지 않아도 동적으로 객체를 생성할 수 있다. 이 방법은 코드 작성 시에 클래스 이름을 결정할 수 없고, 런타임 시에 클래스 이름이 결정되는 경우에 사용된다.
-깊은 복제-
깊은 복제란 참조하고 있는 객체도 복제하는 것을 말한다.
-예제 및 출력-
|
package com.hs.chap11;
public class Car {
public String model;
public Car(String model) {
this.model = model;
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 |
package com.hs.chap11;
import java.util.Arrays;
public class Member implements Cloneable {
public String name;
public int age;
public int[] scores;
public Car car;
public Member(String name, int age, int[] scores, Car car) {
this.name = name;
this.age = age;
this.scores = scores;
this.car = car;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// 먼저 얕은 복사를 해서 name, age를 복사한다.
Member cloned = (Member) super.clone();
// scores를 깊은 복제 한다.
cloned.scores = Arrays.copyOf(this.scores, this.scores.length);
// car를 깊은 복제 한다.
cloned.car = new Car(this.car.model);
// 깊은 복제된 Member 객체를 리턴
return cloned;
}
public Member getMember() {
Member cloned = null;
try {
cloned = (Member) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return cloned;
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 |
package com.hs.chap11;
public class MemberExample {
public static void main(String[] args) {
// 원본 객체 생성
Member original = new Member("홍길동", 25, new int[] { 90, 90 }, new Car("소나타"));
// 복제 객체를 얻은 후에 참조 객체의 값을 변경
Member cloned = original.getMember();
cloned.scores[0] = 100;
cloned.car.model = "그랜저";
System.out.println("[복제 객체의 필드값]");
System.out.println("name: " + cloned.name);
System.out.println("age: " + cloned.age);
System.out.println("scores: {");
for (int i = 0; i < cloned.scores.length; i++) {
System.out.print(cloned.scores[i]);
System.out.print((i == (cloned.scores.length - 1)) ? "" : ",");
}
System.out.println("}");
System.out.println("car: " + cloned.car.model);
System.out.println();
System.out.println("[원본 객체의 필드값]");
System.out.println("name: " + original.name);
System.out.println("age: " + original.age);
System.out.println("scores: {");
for (int i = 0; i < original.scores.length; i++) {
System.out.print(original.scores[i]);
System.out.print((i == (original.scores.length - 1)) ? "" : ",");
}
System.out.println("}");
System.out.println("car: " + original.car.model);
}
}
|
cs |
Back-End/Java 2019. 4. 12. 14:46
-API 도큐먼트- 쉽게 API를 찾아 이용할 수 있도록 문서화 한 것
-구성-
좌측 상단 : 패키지 전체 목록 좌측 하단 : 클래스와 인터페이스 목록 중앙 부분 : 좌측 하단에서 선택한 클래스나 인터페이스에 대한 상세 설명 └상단 : 클래스가 포함된 패키지 정보, 상속 정보, 인터페이스 구현 정보 └중앙 : 클래스의 설명과 사용방법을 간략하게 보여준다. └하단 : 필드, 생성자, 메소드의 목록을 보여준다.
-java.lang 패키지-
자바 프로그램의 기본적인 클래스를 담고 있는 패키지 └종류 : Object, System, Class, String 등
-java.util 패키지-
컬렉션 클래스들이 대부분을 차지한다. └종류 : Arrays, Calendar, Date, Objects, StringTokenizer, Random
-Object 클래스-
클래스 선언시 extends 키워드로 다른 클래스를 상속하지 않으면 상속하는 클래스. 따라서 java의 모든 클래스는 Object클래스의 자식이거나 자손 클래스이다.
-객체 해시코드(hashCode())-
객체를 식별할 하나의 정수값. Object의 hashCode()메소드는 객체의 메모리 번지를 이용해서 해시코드를 만들어 리턴하기 때문에 객체마다 다른 값을 가지고 있다.
-해시코드 사용이유-
equals만 가지고는 HashMap, HashSet와 같이 Key,Value의 쌍으로 구성되는 자료구성에서 제대로 작동하지 않기 때문에 equals와 해시코드를 같이 사용해서 객체를 식별한다.
-객체의 동등 비교-
Object의 equals()메소드와 hashCode() 메소드를 같이 재정의해서 동등 객체일 경우 동일한 해시코드가 리턴되도록 해야한다.
-예제 및 출력 결과-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package com.hs.chap11; public class Key { public int number; public Key(int number) { this.number = number; } @Override //해시코드의 리턴값을 number의 필드값으로 했기 때문에 같은 해시코드가 리턴된다. public int hashCode() { return number; } @Override public boolean equals(Object obj) { if(obj instanceof Key) { Key compareKey = (Key) obj; if(this.number == compareKey.number) { return true; } } return false; } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package com.hs.chap11; import java.util.HashMap; public class KeyExample { public static void main(String[] args) { //Key 객체를 식별키로 사용해서 String 값을 저장하는 HashMap 객체 생성 HashMap<Key,String> hashMap = new HashMap<Key, String>(); //식별키 "new Key(1)"로 "홍길동"을 저장함 hashMap.put(new Key(1),"홍길동"); //식별키 "new Key(1)"로 "홍길동"을 읽어옴 String value = hashMap.get(new Key(1)); System.out.println(value); } } | cs |
Back-End/Java 2019. 4. 10. 17:09
-추상 클래스 및 메소드 특징-
자체적으로 객체를 생성할 수 없다. 상속을 통해 자식 클래스에서 인스턴스를 생성해야 한다. 추상클래스는 추상 메소드, 일반 메소드, 필드(멤버변수), 생성자로 구성된다. 추상클래스와 추상메소드는 클래스와 메소드 앞에 abstract 키워드를 추가하면 된다.
-인터페이스-
추상클래스보다 더 추상도가 깊은 개념 필드는 모두 상수로 선언해야 한다. 메서드는 모두 추상메서드로 선언해야 한다. 추상클래스와 다른점은 다중상속이 가능하다는 점이다.
-인터페이스 형식-
public interface 인터페이스_이름
{
필드(타입 상수명 = 값)
메소드( 추상, 디폴트, 정적 )
}
- 예제 및 출력 결과 -
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 |
package com.hs.chap8;
public interface RemoteControl {
// 상수 필드
public int MAX_VOLUME = 10;
public int MIN_VOLUME = 0;
// 추상 메소드
public void turnOn();
public void turnOff(); // 메소드 선언부만 설정
public void setVolume(int volume);
// 디폴트 메소드
default void setMute(boolean mute) {
if (mute) {
System.out.println("무음 처리합니다.");
} else {
System.out.println("무음 해제합니다.");
}
}
// 정적 메소드
static void changeBattery() {
System.out.println("건전지를 교환합니다.");
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 |
package com.hs.chap8;
public class Audio implements RemoteControl {
// 필드
private int volume;
// turnOn() 추상 메소드의 실체 메소드
public void turnOn() {
System.out.println("Audio를 켭니다.");
}
// turnOff() 추상 메소드의 실체 메소드
public void turnOff() {
System.out.println("Audio를 끕니다.");
}
// setVolume() 추상 메소드의 실체 메소드
public void setVolume(int volume) {
if (volume > RemoteControl.MAX_VOLUME) {
this.volume = RemoteControl.MAX_VOLUME;
} else if (volume < RemoteControl.MIN_VOLUME) {
this.volume = RemoteControl.MIN_VOLUME;
} else {
this.volume = volume;
}
System.out.println("현재 Audio 볼륨:" + this.volume);
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 |
package com.hs.chap8;
public class RemoteControlExample {
public static void main(String[] args) {
RemoteControl rc = null;
rc = new Television();
rc.turnOn();
rc.turnOff();
rc = new Audio();
rc.turnOn();
rc.turnOff();
}
}
|
cs |
|
package com.hs.chap8;
public interface Searchable {
void search(String url);
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 |
package com.hs.chap8;
public class SmartTelevision implements RemoteControl, Searchable {
private int volume;
public void turnOn() {
System.out.println("TV를 켭니다.");
}
public void turnOff() {
System.out.println("TV를 끕니다.");
}
public void setVolume(int volume) {
if (volume > RemoteControl.MAX_VOLUME) {
this.volume = RemoteControl.MAX_VOLUME;
} else if (volume < RemoteControl.MIN_VOLUME) {
this.volume = RemoteControl.MIN_VOLUME;
} else {
this.volume = volume;
}
System.out.println("현재 TV 볼륨: " + this.volume);
}
public void search(String url) {
System.out.println(url + " 을 검색합니다.");
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 |
package com.hs.chap8;
public class Television implements RemoteControl {
// 필드
private int volume;
// turnOn() 추상 메소드의 실체 메소드
public void turnOn() {
System.out.println("TV를 켭니다.");
}
// turnOff() 추상 메소드의 실체 메소드
public void turnOff() {
System.out.println("TV를 끕니다.");
}
// setVolume() 추상 메소드의 실체 메소드
public void setVolume(int volume) {
if (volume > RemoteControl.MAX_VOLUME) {
this.volume = RemoteControl.MAX_VOLUME;
} else if (volume < RemoteControl.MIN_VOLUME) {
this.volume = RemoteControl.MIN_VOLUME;
} else {
this.volume = volume;
}
System.out.println("현재 TV 볼륨: " + this.volume);
}
}
|
cs |
-출처-
-동영상 강의- https://www.youtube.com/watch?v=XkSWgIQ2zkk
Back-End/Java 2019. 4. 9. 17:39
-상속-
부모가 자식에게 물려주는 행위로 자식은 상속을 통해서 부모가 물려준것을 자연스럽게 이용할 수 있다.
부모클래스의 생성자 호출 -자식 클래스의 생성자 최상단에서 "super(매개값);" 명령어를 사용해서 부모클래스의 생성자를 호출 한다.
상속하는 법 - public class "자식클래스 이름" extends "부모클래스 이름"
-예제 및 출력결과- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package chap07Inheritance; public class chap07Inheritancefather { String model; String color; public chap07Inheritancefather() { System.out.println("부모 클래스의 생성자가 호출되었습니다."); } String name(String n) { System.out.println("부모"+n+"메서드가 호출 되었습니다. "); return n; } public void print() { System.out.println("super명령어 사용 메서드 호출"); } public static void main(String[] args) { } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package chap07Inheritance; public class chap07Inheritance extends chap07Inheritancefather{ //자식인 chap07Inheritance클래스가 부모인 chap07Inheritancefather클래스를 선택해서 호출함 int channel; chap07Inheritance (String model, String color, int channel) { super(); //부모클래스의 생성자 호출 this.model = model; //부모클래스 필드 호출 this.color = color; //부모클래스 필드 호출 this.channel = channel; } String name(String n) //name 메소드를 부모 클래스에서 받고 내용을 수정한다. { System.out.println("오버라이딩 된 자식"+n+"메소드가 호출 되었습니다. "); return n; } public void print() //상속받은 부모클래스의 메소드를 호출 { super.print(); } void turnOnDmb() { System.out.println("모델이름은"+model+"입니다."); System.out.println("색깔은"+color+"입니다."); System.out.println("채널은"+channel+"입니다."); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package chap07Inheritance; public class chap07InheritanceTest { public static void main(String[] args) { String n = "클래스"; chap07Inheritance chap07Inheritance = new chap07Inheritance("모델이름 1","갈색",3); chap07Inheritance.turnOnDmb(); chap07Inheritance.name(n); //오버라이딩으로 재정의된 자식 클래스의 메소드를 호출한다. chap07Inheritance.print(); //super 명령어를 사용해서 상속받은 부모클래스의 메소드를 호출 } } | cs |
-final- final이 지정되면 초기값 설정 후, 더 이상 값을 변경할 수 없다. 또한 final 클래스는 부모 클래스가 될수 없어 자식 클래스를 만들 수 없다. 메소드도 마찬가지 이다.
-final 클래스호출시 오류-
-final 메소드 호출-
Back-End/Java 2019. 4. 8. 17:39
- 어노테이션이란? -
컴파일 과정과 실행과정에서 코드를 어떻게 컴파일하고 처리할 것인지를 알려주는 정보
@Override 선언한 메서드가 오버라이드 되었다는 것을 나타냅니다. 만약 상위(부모) 클래스(또는 인터페이스)에서 해당 메서드를 찾을 수 없다면 컴파일 에러를 발생 시킵니다.
@Deprecated 해당 메서드가 더 이상 사용되지 않음을 표시합니다. 만약 사용할 경우 컴파일 경고를 발생 시킵니다.
@SuppressWarnings 선언한 곳의 컴파일 경고를 무시하도록 합니다.
@SafeVarargs Java7 부터 지원하며, 제너릭 같은 가변인자의 매개변수를 사용할 때의 경고를 무시합니다.
@FunctionalInterface Java8 부터 지원하며, 함수형 인터페이스를 지정하는 어노테이션입니다. 만약 메서드가 존재하지 않거나, 1개 이상의 메서드(default 메서드 제외)가 존재할 경우 컴파일 오류를 발생 시킵니다.
-출처- https://elfinlas.github.io/2017/12/14/java-annotation/
-Getter 메소드- 필드값을 가공한 후 외부로 전달하는 메소드
-Setter 메소드- 매개값을 검증해서 유효한 값만 데이터로 저장하는 메소드
-예제 및 출력값-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package chap06_Getter_Setter; public class GetterSetter { private int speed; // 필드선언 private boolean stop; //필드선언 public int getSpeed() { return speed; //speed를 리턴 } public void setSpeed(int speed) //speed를 매개변수로 받음 { if(speed < 0) //speed가 0보다 작을 시(음수가 나올시에)에는 0를 리턴하고 아닐시에는 그 속도를 그대로 쓴다. { this.speed = 0; return; } else { this.speed = speed; } } public boolean isStop() //boolean은 논리타입 (참,거짓 판별) { return stop; //stop를 리턴 } public void setStop(boolean stop) { this.stop = stop; this.speed = 0; } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package chap06_Getter_Setter; public class GetterSetterCar { public static void main(String[] args) { GetterSetter myCar = new GetterSetter(); //잘못된 속도 변경 myCar.setSpeed(-50); System.out.println("현재 속도: "+myCar.getSpeed()); //올바른 속도 변경 myCar.setSpeed(60); //멈춤 if(!myCar.isStop()) { myCar.setStop(true); } System.out.println("현재 속도: "+myCar.getSpeed()); } } | cs |
|