📚 Study/JAVA

[JAVA] Java API (java.lang 패키지)

0_ch4n 2022. 5. 3. 19:42
반응형

✔️ java.lang 패키지

  • 자바 프로그램의 기본적인 클래스를 담고 있는 패키지로 import 없이 사용할 수 있다

 

📌 Object 클래스

 

public boolean equals(Object obj)

  • 참조변수 값을 비교하기 때문에 값을 비교하기 위해선 오버라이딩을 통해 형변환 후 값을 비교하게 해야 한다
public boolean equals(Object obj) {
    return (this == obj); //두 객체의 참조변수 값을 비교
}

@Override
public boolean equals(Object obj) {
    return value == ((Value) obj).value; //두 객체의 값을 비교
}

hashCode()

  • Object 클래스에서 hashCode()는 객체의 주소값으로 해시코드를 만들어 반환
  • String 클래스에서 hashCode()는 문자열의 내용으로 해시코드를 만들어 반환하도록 오버라이딩 (문자열이 같으면 해시코드가 같다)
  • System.identityHashCode(Object x)는 객체에 대해 항상 다른 해시코드값을 반환
HashCode hc1 = new HashCode("abc");
HashCode hc2 = new HashCode("abc");
String str1 = new String("abc");
String str2 = new String("abc");

System.out.println(hc1.equals(hc2)); //false
System.out.println(str1.equals(str2)); //true
System.out.println(hc1.hashCode()); //981506536
System.out.println(hc2.hashCode()); //747464370
System.out.println(str1.hashCode()); //96354
System.out.println(str2.hashCode()); //96354
System.out.println(System.identityHashCode(str1)); //1513712028
System.out.println(System.identityHashCode(str2)); //1018547642

 

toString()

  • Object 클래스에서 toString()은 클래스이름에 16진수의 해시코드를 반환
  • String 클래스에서 toString()은 String 인스턴스가 갖고 있는 문자열 반환하도록 오버라이딩
  • Date 클래스에서 toString()은 Date 인스턴스가 갖고 있는 날짜와 시간을 문자열로 변환하여 반환하도록 오버라이딩
Test t = new Test();
String str = new String("abc");
java.util.Date today = new java.util.Date();

System.out.println(t.toString()); //Test@35bbe5e8
System.out.println(str.toString()); //abc
System.out.println(today.toString()); //Mon May 02 20:23:38 KST 2022

 

clone()

  • Cloneable이 구현한 객체는 복제 가능 (implements Clonable로 꼭 구현해줘야함)
  • clone()을 오버라이딩해야하며 접근 제어자는 protected에서 public으로 변경
  • try-catch문을 이용해 CloneNotSupportedException으로 반드시 예외처리를 해야함
class Personal implements Cloneable {
    public String name = "홍길동";

    Personal() {}

    public String toString() {
        return name;
    }

    public Personal DeepCopy() { //Deep Copy 객체를 생성해서 복사
        Object obj = null;
        try {
            obj = super.clone();
        } catch (CloneNotSupportedException e) {}
        Personal p3 = new Personal();
        p3.name = name;
        return p3;
    }
}

class CloneTest {
    public static void main(String[] args) {
        Personal p1 = new Personal();
        Personal p2 = p1; //Shallow Copy 주소값만 바꿔서 복사
        Personal p3 = p1.DeepCopy();

        System.out.println(p1); //홍길동
        System.out.println(p2); //홍길동
        System.out.println(p3); //홍길동

        p1.name = "아무개";

        System.out.println(p1); //아무개
        System.out.println(p2); //아무개
        System.out.println(p3); //홍길동
    }
}
  • 얇은 복사(shallow copy) : 원본과 복제본이 같은 객체를 공유하므로 원본을 변경하면 복사본도 영향을 받는다
  • 깊은 복사(deep copy) : 원본이 참조하고 있는 객체를 복제하는 것으로 원본의 변경이 복사본에 영향을 미치지 않는다

 

getClass()

  • Class 클래스는 클래스로더를 통해 생성된 클래스의 모든 정보를 담고 있으며 클래스 당 1개만 존재한다
  • 클래스 객체를 메모리 → 클래스 패스(classpath) 순으로 확인하여 없다면 ClassNotFoundException이 발생한다
  • Reflection API를 통해 동적으로 생선한 객체로 메서드를 호출할 수 있게 한다
final class Card {
    String kind = "SPADE";
    int num = 7;
}

class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        //Class 객체를 얻는 방법들
        Class cObj = new Card().getClass();
        Class cObj2 = Card.class;
        Class cObj3 = Class.forName("Card");

        //Class 클래스의 메서드들
        System.out.println(cObj.getName()); //Card
        System.out.println(cObj2.toGenericString()); //final class Card
        System.out.println(cObj3.toString()); //class Card
    }
}

 

📌 String 클래스

  • 문자열 리터럴은 constant pool에 한 번 저장되며 같은 내용을 참조할 땐 같은 주소값을 가지게 된다
String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");

System.out.println(str1 == str2); //false
System.out.println(str1 == str3); //false
System.out.println(str1.equals(str2)); //true
System.out.println(str1.equals(str3)); //true

str1 = str1 + str2; //abcabc

위 코드를 메모리 영역에서 표현

 

String 클래스의 생성자

 

String 클래스의 메서드

 

java.util.StringJoiner 클래스

StringJoiner sj = new StringJoiner(",", "[", "]");
String[] strArr = { "aaa" , "bbb", "ccc" };

for(String s : strArr) {
    sj.add(s);
}

System.out.println(sj.toString());

 

getBytes(String charsetName)

  • 문자열의 문자 인코딩을 다른 인코딩으로 변경
String str = "가";

byte[] bArr = str.getBytes("UTF-8");

StringJoiner sj = new StringJoiner(":", "[", "]");

for(byte b : bArr) {
    sj.add(String.format("%02X", b));
}

System.out.println(sj.toString()); //[EA:B0:80]

System.out.println(new String(bArr, "UTF-8")); //가

 

String.format()

  • printf()와 같이 형식문자를 사용하여 형식화된 문자열을 만들어낸다
String str = String.format("%d", 3);
System.out.println(str); //3

 

📌 StringBuffer, StringBuilder 클래스

  • 크기를 변경하려면 새로운 StringBuffer를 만들어야 하지만 String 클래스와 달리 내용을 변경할 수 있다
//StringBuffer의 생성
public StringBuffer(int length) {
    value = new char[length]; //char형 배열을 갖는 참조변수 value
    shared = false;
}

public StringBuffer() {
    this(16); //버퍼의 크기는 디폴트가 16이다
}

public StringBuffer(String str) {
    this(str.length() + 16); //지정한 버퍼의 크기 + 16으로 생성해 str을 추가한다
    append(str);
}

//StringBuffer의 크기 변경
char newValue[] = new char[int newlength];
System.arraycopy(value, 0, newValue, 0, oldlength);
value = newValue;

//StringBuffer의 비교
StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
String s = sb.toString();
String s2 = sb2.toString();

System.out.println(sb == sb2); //false
System.out.println(sb.equals(sb2)); //false
System.out.println(s == s2); //false
System.out.println(s.equals(s2)); //true

sb.append("123")의 실행

 

StringBuffer 클래스의 생성자

 

StringBuffer 클래스의 메서드

 

StringBuilder

  • StringBuffer ←→ StringBuilder
  • StringBuffer가 멀티스레드에 안전하도록 동기화되어 성능이 떨어지는 것에 대한 대안으로 쓰인다

 

📌 Math 클래스

  • 생성자는 모두 private로 다른 클래스에서 인스턴스화 할 수 없다 (인스턴스 변수가 없어서 할 필요가 없다)
  • 메서드는 모두 static이고 2개의 상수를 갖고 있다
    • public static final double E = 2.7182818284590452354; //자연로그의 밑
    • public static final double PI = 3.14159265358979323846; //원주율

 

Math 클래스의 메서드

 

예외를 발생시키는 메서드

  • jdk 8부터 추가됐으며 이름에 'Exact'가 포함된 메서드들로 오버플로우(ArithmeticException)를 감지하기 위한 것이다
int addExact(int x, int y) //x + y
int subtractExact(int x, int y) //x - y
int multiplyExact(int x, int y) //x * y
int incrementExact(int a) //a++
int decrementExact(int a) //a--
int negateExact(int a) //-a
int toIntExact(long value) //(int) value

 

StrictMath 클래스

  • Math 클래스가 성능을 위해 OS의 메서드를 호출해 계산하지만 OS마다 오차가 생기는 것에 대안으로 정확한 값을 위해 사용된다

 

java.math.BigInteger 클래스

  • long 타입의 한계인 10진수로 19자리보다 큰 값을 다루기 위해 사용한다 (성능은 long > BigInteger)
  • 2의 보수 형태로 signum엔 부호 mag엔 값이 저장된다
//BigInteger 생성
BigInteger val;
val = new BigInteger("12345678901234567890"); //문자열로 생성
val = new BigInteger("FFFF", 16); //n진수의 문자열로 생성
val = BigInteger.valueOf(1234567890L); //숫자로 생성

//다른 타입으로 변환
val.toString(); //문자열로 변환
val.toString(16); //n진법의 문자열로 변환
val.toByteArray(); //byte 배열로 변환

//연산 (새로운 인스턴스 생성)
val.add(val); //덧셈
val.subtract(val); //뺄셈
val.multiply(val); //곱셈
val.divide(val); //나눗셈
val.remainder(val); //나머지

//비트 연산
val.bitCount(); //2진수로 표현했을 때 1의 개수(음수는 0)
val.bitLength(); //2진수로 표현했을 때 bit 수
val.testBit(n); //우측에서 n+1번째 비트가 1이면 true, 0이면 false
val.setBit(n); //우측에서 n+1번째 비트를 1로 변경
val.clearBit(n); //우측에서 n+1번째 비트를 0으로 변경
val.flipBit(n); //우측에서 n+1번째 비트를 전환 (0 -> 1, 1 -> 0)

 

java.math.BigDecimal 클래스

  • double 타입이 한계인 소수점 13자리보다 더 정밀한 값을 다루기 위해 사용한다
  • 실수를 정수와 10의 제곱으로 표현한다
//BigDecimal 형태
private final BigInteger intVal; //정수
private final int scale; //지수
private transient int precision; //정밀도(정수의 자릿수)

BigDecimal val = new BigDecimal("123.45"); //12345x10^-2
System.out.println(val.unscaledValue()); //12345
System.out.println(val.scale()); //2
System.out.println(val.precision()); //5

//BigDecimal 생성
BigDecimal val;
val = new BigDecimal("123.4567890"); //문자열
val = new BigDecimal(123.456); //double 타입 (오차주의)
val = new BigDecimal(123456); //int, long 타입
val = BigDecimal.valueOf(123.456); //valueOf(double)
val = BigDecimal.valueOf(123456); //valueOf(int)

//BigDecimal 변환
BigDecimal val = new BigDecimal(1.0e-22);
//숫자로만 표현
System.out.println(val.toPlainString()); //0.00000000000000000000010...
//지수형태로 표현
System.out.println(val.toString()); //1.000000000000000048...5E-22

//BigDecimal -> 기본형
val.intValue();
val.longValue();
val.floatValue();
val.doubleValue();

//BigDecimal 연산
val.add(val); //덧셈
val.subtract(val); //뺄셈
val.multiply(val); //곱셈
val.divide(val); //나눗셈
val.remainder(val); //나머지

//반올림 모드
BigDecimal val = new BigDecimal("123.456");
BigDecimal divisor = new BigDecimal("1.0");
val.divide(divisor, 2, RoundingMode.HALF_UP); //123.46
val.setScale(2, RoundingMode.HALF_UP); //123.46
  • 반올림모드
    1. CEILING : 올림
    2. FLOOR : 내림
    3. UP : 양수일 때는 올림, 음수일 때는 내림
    4. DOWN : 양수일 때는 내림, 음수일 때는 올림
    5. HALF_UP : 반올림(5 이상 올림, 5 미만 버림)
    6. HALF_EVEN : 반올림(반올림 자리의 값이 짝수면 HALF_DOWN, 홀수면 HALF_UP)
    7. HALF_DOWN : 반올림(6 이상 올림, 6 미만 버림)
    8. UNNECESSARY : 나눗셈의 결과가 딱 떨어지는 수가 아니면 ArithmeticException 발생

 

java.math.MathContext 클래스

  • 반올림 모드와 정밀도를 하나로 묶어 놓은 것으로 정밀도가 정수와 소수점 이하를 모두 포함한 자리수를 의미한다
BigDecimal bd = new BigDecimal("123.456");
BigDecimal bd2 = new BigDecimal("1.0");

System.out.println(bd.divide(bd2, 2, RoundingMode.HALF_UP)); //123.46
System.out.println(bd.divide(bd2, new MathContext(2, RoundingMode.HALF_UP))); //1.2E+2

 

📌 래퍼(Wrapper) 클래스

  • 8개의 기본형을 객체로 다루기 위한 클래스로 Boolean과 Character를 제외한 나머지는 Number 클래스를 상속 받는다

래퍼 클래스 상속계층도

 

래퍼 클래스의 생성자

  • 매개변수의 자료형이 옳지 않으면 NumberFormatException 예외 발생

 

문자열을 숫자로 변환하기

 

오토박싱(autoboxing) & 언박싱(unboxing)

  • 오토박싱 : 기본형 값을 래퍼 클래스의 객체로 자동 변환해주는 것
  • 언박싱 : 래퍼 클래스의 객체를 기본형 값으로 변환해주는 것

 

📄 참고

자바의 정석 3rd Edition

반응형