1. StringBuilder / StringBuffer 사용하기
그냥 String에 concat이나 +를 사용하여 문자열을 추가하게 되면 Heap에 추가할때마다 새로운 String 객체가 생성되어 참조되지 않는 Garbage가 많아지기 때문에,
이런 문제를 해결하기 위해서 StringBuilder 또는 StringBuffer를 사용한다.
public static void main(String[] args) {
// +로 String 연결
String str = "";
long startTime = System.currentTimeMillis(); //시작시간 체크
for (int i = 0; i < 50000; i++) {
str += "Cat";
}
System.out.println(str);
long endTime = System.currentTimeMillis(); //끝나는 시간 체크
long 걸린시간 = endTime - startTime;
StringBuilder sb = new StringBuilder(str);
long startTime2 = System.currentTimeMillis();
for (int i = 0; i < 50000; i++) {
sb.append("Cat");
}
System.out.println(sb.toString());
long endTime2 = System.currentTimeMillis();
long 걸린시간2 = endTime2 - startTime2;
System.out.println("String += 사용 : " + 걸린시간 + "ms\nStringBuilder.append 사용 : " + 걸린시간2 + "ms");
}
// String += 사용 : 490ms
// StringBuilder.append 사용 : 3ms
2. Java Class 클래스
- 클래스의 구성요소 : 필드(객체의 데이터가 저장되는 곳), 생성자(객체 생성시 초기화 역할), 메소드(객체의 동작에 해당하는 실행 블록) 으로 구성
- Class 클래스 : 클래스 정보 얻어오는 클래스
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Customer customer = new Customer("민철");
Class clazz = customer.getClass(); //customer 클래스 가져오기-> 객체.getClass()
//Class clazz1 = Customer.class; //class 가져오기2 -> 클래스이름.class
Constructor[] constructors = clazz.getConstructors(); //클래스의 생성자 가져오기
for (Constructor constructor : constructors) {
System.out.println(constructor); //Customer 클래스의 생성자 출력
}
Method[] methods = clazz.getMethods(); //클래스의 메소드 가져오기
for (Method method : methods) {
System.out.println(method); //Customer 클래스의 메소드 출력
}
Field[] fields = clazz.getFields(); //클래스의 필드 가져오기, public 만 가져올 수 있음
for (Field field : fields) {
System.out.println(field);
}
Field[] declaredFields = clazz.getDeclaredFields(); //public 아닌 필드도 가져올수 있음
for (Field field : declaredFields) {
System.out.println(field);
}
Customer customer1 = (Customer) clazz.getConstructor(String.class).newInstance("민철");
//clazz를 통해 인스턴스 생성 Object 타입 -> 다운캐스팅 필요
customer1.printMyInfo(); //Customer의 메소드 사용 가능
}
- Class 클래스가 필요한이유 : Java Reflection 기술과 같이 쓰임. Spring AOP 에서 사용. 추후 배울 예정.
3. Java System 클래스 (유틸리티 클래스)
- 운영체제 시스템 관련 기능 수행(ex. 입출력관리, 시간측정, 환경변수 접근, GC 호출 등)
4. Java Math 클래스 (유틸리티 클래스)
- 기본 수식 연산자 외 여러 수학 계산 관련 메소드 제공(ex. abs절대값, ceil올림, max, min, sqrt제곱근, round반올림, random 등)
☑️ Wrapper, Generic
1. Wrapper 클래스
- 자바 기본타입(int, float, byte, char 등) 과 매핑된 클래스
- 박싱 : 기본타입 -> Wrapper 클래스 // 언박싱 : Wrapper 클래스 -> 기본타입
Integer num = new Integer(10); //박싱
int n = num.intValue(); //언박싱
Integer num2 = 10; //오토박싱 -> 박싱 기능 자동으로 수행
int n2 = num2; //오토언박싱 -> 언박싱 기능 자동으로 수행
Character ch1 = new Character('X'); //박싱
char c1 = ch1.charValue(); //언박싱
Character ch2 = 'X'; //오토박싱 -> 박싱 기능 자동으로 수행
char c2 = ch2; //오토언박싱 -> 언박싱 기능 자동으로 수행
Integer result1 = num + num2; // 20
Integer result2 = n + n2; //20
int result3 = num * n2; // 100
Integer integer1 = null; //가능
int int1 = null; //불가능
- Wrapper 클래스가 존재하는 이유?
- 객체지향적 프로그래밍 실현 & 자료구조 일관성 유지, Java 라이브러리 사용 지원, Generic 프로그래밍 지원
2. Generic 살펴보기
- 안전하게 같은 코드를 여러 참조형에서 사용하여 코드 재사용성을 올리는 프로그래밍 기법
public class 클래스<T> {...}
public interface 인터페이스<T> {...}
// NON GENERIC
public class GeneralPrint {
private Object material;
public void printMyInfo() {
System.out.println(material + "를 출력합니다");
}
public Object getMaterial() {
return material;
}
public void setMaterial(Object material) {
this.material = material;
}
}
...
public class PrintSituation {
public static void main(String[] args) {
//GeneralPrint를 Object로 선언, 다운캐스팅 필요
GeneralPrint print = new GeneralPrint();
print.setMaterial("설계도");
String meterial = (String) print.getMaterial();
print.printMyInfo();
GeneralPrint print2 = new GeneralPrint();
print2.setMaterial(1235);
Integer intMaterial = (Integer) print2.getMaterial();
print2.printMyInfo();
GeneralPrint print3 = new GeneralPrint();
print3.setMaterial(true);
Boolean booleanMaterial = (Boolean) print3.getMaterial();
print3.printMyInfo();
}
}
//GENERIC
public class GeneralPrint<T> {
private T material;
public void printMyInfo() {
System.out.println(material + "를 출력합니다");
}
public T getMaterial() {
return material;
}
public void setMaterial(T material) {
this.material = material;
}
}
...
public class PrintSituation {
public static void main(String[] args) {
//<> 여기에는 Wrapper 클래스만 가능, int, float, double 등등 기본형 불가
GeneralPrint<String> print = new GeneralPrint();
print.setMaterial("설계도");
String meterial = print.getMaterial();
print.printMyInfo();
GeneralPrint<Integer> print2 = new GeneralPrint();
print2.setMaterial(1235);
Integer intMaterial = print2.getMaterial();
print2.printMyInfo();
GeneralPrint<Boolean> print3 = new GeneralPrint();
print3.setMaterial(true);
Boolean booleanMaterial = print3.getMaterial();
print3.printMyInfo();
//<> 안붙이면 Object 타입으로 캐스팅
GeneralPrint print4 = new GeneralPrint();
print.setMaterial("설계도1");
//다운캐스팅 필요
String meterial1 = (String) print4.getMaterial();
print.printMyInfo();
}
}
3. Generic 심화
- Static은 Generic 적용할 수 없음. 왜냐? Static은 클래스 로드 시 생성되는데 Generic은 인스턴스 생성 시 생성
- 두 개 이상도 가능
- 자료형 제한하기 : extends로 범위를 좁히기
public class Point<T extends Number, V extends Number> { //범위를 Number의 하위 클래스들로 한정시키기
private T x;
private V y;
public Point(T x, V y) {
this.x = x;
this.y = y;
}
public T getX() {
return x;
}
public V getY() {
return y;
}
public Double calculateDistance() {
Double num1 = (this.x).doubleValue();
Double num2 = (this.y).doubleValue();
return Math.sqrt(Math.pow(num1, 2) + Math.pow(num2, 2));
}
}
...
public class PointSituation {
public static void main(String[] args) {
Point<Integer, Integer> point = new Point<>(1, 5);
Point<Integer, Double> point1 = new Point<>(1, 4.5);
Point<Double, Double> point2 = new Point<>(1.5, 5.5);
System.out.println(point.calculateDistance());
System.out.println(point1.calculateDistance());
System.out.println(point2.calculateDistance());
Point<String, Integer> point3 = new Point<>("A", 1); //에러 발생
System.out.println(point3.calculateDistance());
}
}
#슈퍼코딩, #1:1관리형부트캠프, #백엔드, #backend, #백엔드공부, #개발공부, #백엔드개발자 #취준일기, #취준기록, #취뽀, #빡공, #HTML/CSS, #javascript, #react , #java, #spring