00188 20151208 자바 GoF 디자인패턴 수업 2일차 - AngryQA/blog GitHub Wiki
자바 GoF 디자인패턴 수업 2일차
AngryQA | 2015-12-08 화요일 오전 9:29 | IT/개발전반 | 원본
1. 캐릭터 타입에 대해 자바에서 연산자 오버로딩 + 는 문자열인 경우만 합쳐줌 "a" 문자열 'a' 문자 "a" + "b"와 'a' + 'b'는 차이가잇음
문자(캐릭터타입)를연결하는방법 스트링빌더 , 연산맨앞에 "" 프린트 에프
(int)(char)(byte)-1 결과가 65535가 나옴 캐릭터엔 부호가없다능
조건연산자 두번째 세번째 자료형일치시켜야함
2. Object에 대해
메모리자원은 GC가 관리하지만 비메모리 자원인 경우도 있으니까.. 반환해주는 코드가 필요함
파일도 열수있는게 제한되어 있으니까
그런데 하지만
finalize를 이용해 비메모리 자원을 반환하면 안된다.
그래서 명시적인 Close같은 명시적 종료 메소드를 만들어 제공해주어야한다(메소드제작자)
finalize의 용법은 사용자가 close를 호출하지 않은경우를 위해 코딩해 둔다.
부모의 finalize를 명시적 호출도 해야함.
mCloseGuard를 이용하면 명시적 close 관련함수를 모두 끄거나 킬수있다(메모리절약일까..)
안드로이드에서 많이 사용한것으로 보임
Finalizer Guardion pattern
하위클래스가 부모클래스의 finalizer를 호출하는것을 잊은경우를 방지하는 방법
Try with Resource
1. 명시적인 종료메소드로 인한 코드의 가독성 해결, (파이널리등 여러가지고려해야할사항때문에 코딩이 늘어남)
2. 블록이 끝났을대, 명시적 종료메소드를 자동적으로 호출해준다
3. AutoCloseable 인터페이스를 구현해야함
try(리소스가져오는코드)
[#M_Try with Resource Code|접기|
import javax.imageio.ImageIO; import java.awt.*; import java.io.BufferedOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.URL;
// http://d.pr/n/19BcI public class Example8 {
// Try with Resource - Java 1.7 // : C# using block // 1. 명시적인 종료 메소드로 인한 코드의 가독성이 어지럽혀지는 것을 방지해준다. // 2. 블록이 끝났을 때, 명시적인 종료 메소드를 자동적으로 호출해준다. // 3. AutoCloseable 인터페이스를 구현해야 한다. static void goo() { try (Photo photo = new Photo("http://d.pr/i/Jv0e+"); FileOutputStream fos = new FileOutputStream("a.dat"); BufferedOutputStream bos = new BufferedOutputStream(fos);) { //... } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
static void foo() { Photo photo = null; FileOutputStream fos = null; BufferedOutputStream bos = null; try { photo = new Photo("http://d.pr/i/Jv0e+"); fos = new FileOutputStream("a.dat"); bos = new BufferedOutputStream(fos);
//...
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (photo != null)
photo.close();
if (fos != null)
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
if (bos != null)
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception { foo(); } }
class Photo implements AutoCloseable { Image image;
public Photo(String imageUrl) { URL url; try { url = new URL(imageUrl); image = ImageIO.read(url); } catch (IOException e) { e.printStackTrace(); } }
@Override public void close() { System.out.println("Image 자원 해지"); if (image != null) { image.flush(); image = null; } }
@Override protected void finalize() throws Throwable { try { if (image != null) { System.err.println("Explicit Termination Method" + " 'close' is not called"); close(); } } finally { super.finalize(); } }
}
_M#]
Object.equals를 재정의하지않은경우 레퍼런스만 비교함
객체동일성(레퍼런스)이 아닌 논리 동일성이 필요한경우 equals를 재정의할 필요가 있다.
[#M_equals를 재정의|접기|
public class Example9 { public static void main(String[] args) { Point p1 = new Point(10, 20); Point p2 = new Point(10, 20);
if (p1.equals(p2)) {
System.out.println("Same");
} else {
System.out.println("Not Same");
}
} }
// 1. Object.equals() 를 재정의하지 않는 경우 // 모든 객체는 오직 자기 자신과 동일하다. // 2. 객체 동일성이 아닌 논리적 동일성의 개념을 제공하기 위해서는 // Object.equals() 재정의 해야 한다. // class Point { private final int x; private final int y;
public Point(int x, int y) { this.x = x; this.y = y; }
// 3. equals를 재정의했다면 반드시 hashCode도 제공해야 한다. @Override public int hashCode() { final int prime = 31; int result = 1; result += prime * result + x; result += prime * result + y; return result; }
@Override public boolean equals(Object obj) { // 1. 자기 자신인지 검사 if (this == obj) return true;
// 2\. obj == null인지 체크
// (모든 객체는 null과 동치 관계가 성립되지 않는다.)
if (obj == null) return false;
// 3\. 인자의 자료형이 정확한지 검사
// if (obj.getClass() != Point.class) // 1
if (!(obj instanceof Point)) // 2
return false;
// 4\. 자료형 변환
Point p = (Point)obj;
// 5\. 중요 필드 점검
return x == p.x && y == p.y;
}
@Override public String toString() { return "Point{" + "x=" + x + ", y=" + y + '}'; }
}
_M#]
Guava 라이브러리를 이용하면 내부인스턴스를 모두 널체크및을 다 해주는것이 있다
반복작업이나 귀찮은 작업을 해주는듯... hash, Object등..
이것이 자바에 1.7부터 적용됨 그러므로 즉
Objects(1.7).equals를 사용하면 적은코드로 비교가능하다.
[#M_Guava, Equals, hash, Objects|접기|
import javax.imageio.ImageIO; import java.awt.*; import java.io.BufferedOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.URL;
// http://d.pr/n/19BcI public class Example8 {
// Try with Resource - Java 1.7 // : C# using block // 1. 명시적인 종료 메소드로 인한 코드의 가독성이 어지럽혀지는 것을 방지해준다. // 2. 블록이 끝났을 때, 명시적인 종료 메소드를 자동적으로 호출해준다. // 3. AutoCloseable 인터페이스를 구현해야 한다. static void goo() { try (Photo photo = new Photo("http://d.pr/i/Jv0e+"); FileOutputStream fos = new FileOutputStream("a.dat"); BufferedOutputStream bos = new BufferedOutputStream(fos);) { //... } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
static void foo() { Photo photo = null; FileOutputStream fos = null; BufferedOutputStream bos = null; try { photo = new Photo("http://d.pr/i/Jv0e+"); fos = new FileOutputStream("a.dat"); bos = new BufferedOutputStream(fos);
//...
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (photo != null)
photo.close();
if (fos != null)
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
if (bos != null)
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception { foo(); } }
class Photo implements AutoCloseable { Image image;
public Photo(String imageUrl) { URL url; try { url = new URL(imageUrl); image = ImageIO.read(url); } catch (IOException e) { e.printStackTrace(); } }
@Override public void close() { System.out.println("Image 자원 해지"); if (image != null) { image.flush(); image = null; } }
@Override protected void finalize() throws Throwable { try { if (image != null) { System.err.println("Explicit Termination Method" + " 'close' is not called"); close(); } } finally { super.finalize(); } }
}
_M#]
다양한 동등성(equal)체크시 고려할 사항
[#M_double, 배열의경우|접기|
import java.lang.reflect.Array; import java.math.BigDecimal; import java.util.Arrays; import java.util.Objects;
// 1. float, double == 으로 비교하면 안된다. // 2. BigDecimal public class Example10 { public static void main(String[] args) { BigDecimal v1 = new BigDecimal(2.0) .subtract(new BigDecimal(1.1));
// 3\. BigDecimal(String) 생성자를 이용해야 한다.
// C# : decimal
BigDecimal v2 = new BigDecimal("2.0")
.subtract(new BigDecimal("1.1"));
System.out.println(v1);
System.out.println(v2);
double value1 = 2.0 - 1.1;
double value2 = 0.9;
System.out.println(value2);
if (Math.abs(value1 - value2) < 0.0000001) {
System.out.println("Same");
}
int[] arr1 = new int[20];
int[] arr2 = new int[20];
System.out.println(arr1 == arr2);
System.out.println(arr1.equals(arr2));
// 4\. 배열 내용을 비교하기 위해서는 Object.eqauls()
// Arrays.equals() 사용해야 한다.
System.out.println(Arrays.equals(arr1, arr2));
System.out.println(Objects.equals(arr1, arr2));
} }
_M#]
클론어블.. 클론 메소드.. 잘 모르게따..
기본적으로 클론은 오브젝트 속성
앝은 복사? 깊은 복사...
불편객체 설계.. 내일 예정..
예제소스
[#M_더보기|접기|
public class Example12 { public static void main(String[] args) throws Exception { Person p1 = new Person("Tom", 42); Person p2 = p1.clone();
System.out.println(p1);
System.out.println(p2);
} }
// 1. clone() 메소드 재정의 // 2. Cloneable 인터페이스 구현(mark-up) class Person implements Cloneable { private String name; private int age;
public Person(String name, int age) { this.name = name; this.age = age; }
// protected -> public // 공변 반환형 : 재정의 메소드의 리턴 타입은 재정의 되는 메소드의 // 리턴 타입의 하위 클래스가 될 수 있다.(1.5) @Override public Person clone() throws CloneNotSupportedException { return (Person) super.clone(); }
@Override public String toString() { return "Person{" + "name='" + name + ''' + ", age=" + age + '}'; }
}
_M#]
오픈소스에는 GoF디자인패턴과 Idioms(관용구)=사람들이 다 비슷하게 쓰는 코드
가 많이 씀
자바는 그래도 대충보이는데 C++은 안보니까
공부해두면 소스 해석이 가능하다.
JAVAIdioms, c++ Idioms