Fundamental

μžλ£Œν˜•

Java 의 μžλ£Œν˜•μ€ κΈ°λ³Έ (μ›μ‹œ) νƒ€μž…κ³Ό μ°Έμ‘° νƒ€μž…μœΌλ‘œ 크게 λ‚˜λ‰œλ‹€.

κΈ°λ³Έ νƒ€μž…μ€ μ•„λž˜μ™€ κ°™λ‹€.

λ°μ΄ν„°ν˜• μ˜ˆμ•½μ–΄ λΉ„νŠΈμˆ˜(λ°”μ΄νŠΈμˆ˜) λ²”μœ„
λ…Όλ¦¬ν˜• boolean 8 Bit (1 Byte) true or false
λ¬Έμžν˜• char 16 Bit
μœ λ‹ˆμ½”λ“œ (2 Byte)
μˆ˜μΉ˜λ‘œλŠ” 0 ~ 65535('\u0000'~'\uFFFF')
μœ λ‹ˆμ½”λ“œ:μ˜μ–΄,숫자-1λ°”μ΄νŠΈ, κ·Έμ™Έ λ‹€κ΅­μ–΄-2λ°”μ΄νŠΈ
μˆ˜μΉ˜ν˜•(μ •μˆ˜) byte 8 Bit (1 Byte) -128 ~ 127(-2의7제곱~2의7제곱-1)
2^8
μˆ˜μΉ˜ν˜•(μ •μˆ˜) short 16 Bit (2 Byte) -32,768 ~ 32,767(-2의15제곱~2의15제곱-1)
2^16
μˆ˜μΉ˜ν˜•(μ •μˆ˜) int 32 Bit (4 Byte) -2,147,483,648 ~ 2,147,483,647(-2의31제곱~2의31제곱-1)
2^32
μˆ˜μΉ˜ν˜•(μ •μˆ˜) long 64 Bit (8 Byte) -9,223,372,036,854,775,808~9,223,372,036,854,775,807
(-2^63 ~ 2^63-1)
2^64
μˆ˜μΉ˜ν˜•(μ‹€μˆ˜) float 32 Bit (4 Byte) Β±3.40282347E+38, Β±1.40239846E-45
IEEE 754-1985ν‘œμ€€
μˆ˜μΉ˜ν˜•(μ‹€μˆ˜) double 64 Bit (8 Byte) -1.79769313486231570E308~+1.79769313486231570E308

κΈ°λ³Ένƒ€μž…μ˜ κ°€μž₯ 큰 νŠΉμ§•μ€ λ³€ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” λΆˆλ³€ (immutable) 속성을 가지고 있으며 κ°’ 자체λ₯Ό 가지고 μžˆλ‹€.

μ°Έμ‘° λ°μ΄ν„°ν˜•μ€ λ°°μ—΄, 클래슀, μΈν„°νŽ˜μ΄μŠ€ λ“±λ“±μœΌλ‘œ κΈ°λ³Ένƒ€μž…μ„ μ œμ™Έν•œ μ΄μ™Έμ˜ 것듀을 κ°€λ₯΄ν‚€λ©° 값이 μ•„λ‹Œ 데이터에 λŒ€ν•œ μ°Έμ‘° μ£Όμ†Œλ₯Ό 가지고 μžˆλ‹€.

참고자료

https://aventure.tistory.com/59

JDK & JRE 차이점

JDK (Java Development Kit)

Java 의 μ‘μš©ν”„λ‘œκ·Έλž¨μ„ κ°œλ°œν•  수 μžˆλŠ” μ†Œν”„νŠΈμ›¨μ–΄ 개발 ν‚€νŠΈμ΄λ‹€.

JRE (Java Runtime Environment)

Java ν”„λ‘œκ·Έλž¨ μ½”λ“œκ°€ μ‹€ν–‰λ˜λŠ” JVM 을 지칭함

static ν‚€μ›Œλ“œμ˜ 의미

Java Class 의 멀버 λ³€μˆ˜ λ˜λŠ” λ©”μ†Œλ“œκ°€ μ†ν•œ 클래슀의 μΈμŠ€ν„΄μŠ€ν™”λ₯Ό μš”κ΅¬ν•˜μ§€ μ•Šκ³  μ•‘μ„ΈμŠ€ ν•  수 μžˆλŠ” μ ‘κ·Όμ œμ–΄μž μž…λ‹ˆλ‹€.
static μ ‘κ·Ό μ œμ–΄μžλ‘œ μ§€μ •λœ λ³€μˆ˜ ν˜Ήμ€ λ©”μ„œλ“œλŠ” Java Runtime μ‹œμ— Compile μ‹œμ— μ •μ μœΌλ‘œ 바인딩 되기 λ•Œλ¬Έμ— μž¬μ •μ˜ (μˆ˜μ •) 이 λΆˆκ°€ ν•©λ‹ˆλ‹€.

μΈν„°νŽ˜μ΄μŠ€ (interface) 와 좔상 클래슀(abstract) 의 곡톡점 & 차이점

μΈν„°νŽ˜μ΄μŠ€ (interface) 와 좔상 클래슀 (abstract) λŠ” 근본적으둜 λ‹€λ₯Έ λͺ©μ μ— μ˜ν•΄ κ΅¬ν˜„λœλ‹€.

interface abstract
λͺ©μ  ν•¨μˆ˜μ˜ κ΅¬ν˜„μ„ κ°•μ œν™” 상속을 ν†΅ν•˜μ—¬ κΈ°λŠ₯을 μ΄μš©ν•˜κ³  ν™•μž₯함
κ΅¬ν˜„ 방식 λ°˜λ“œμ‹œ λͺ¨λ“  λ©”μ†Œλ“œλ₯Ό κ΅¬ν˜„ λͺ¨λ“  λ©”μ†Œλ“œλ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šμ•„λ„ 됨
닀쀑 상속 κ°€λŠ₯ λΆˆκ°€
μ ‘κ·Ό μ œμ–΄μž public private, protected, public
λ³€μˆ˜ 기본적으둜 final 둜써 μ΅œμ’… λ³€μˆ˜μž„ λΉ„ μ΅œμ’… λ³€μˆ˜λ₯Ό 포함할 수 있음

Java 8 μ΄μ „κΉŒμ§€λŠ” Interface μ•ˆμ— static λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•  수 μ—†μ—ˆλ‹€.

μ΄λŠ” static 클래슀인 κ²½μš°μ—λŠ” 클래슀 μžμ²΄κ°€ JVM κΈ°λ™ν•˜λ©΄μ„œ λ°”λ‘œ λ‘œλ”© λœλ‹€.
Interface λ‚˜ Abstract Class 인 경우 ν΄λž˜μŠ€κ°€ μƒμ„±λ˜μ–΄μ§„ 이후에 ν•΄λ‹Ή 객체λ₯Ό Reference ν•˜κ²Œ λœλ‹€.
μƒλŒ€μ μœΌλ‘œ λ‘œλ”©μ‹œκ°„μ΄ μ•žμ„œ μžˆλŠ” static ν΄λž˜μŠ€μ— λŒ€ν•΄μ„œλŠ” interface λ‚˜ Abstract 클래슀의 κ΅¬ν˜„μ΄ λΆˆκ°€ν•˜λ‹€

일반적으둜 μΆ”μƒν΄λž˜μŠ€λ₯Ό μƒμ†λ°›λŠ” κ²½μš°λŠ” 결합도가 κ°•ν•˜κΈ° λ•Œλ¬Έμ— μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„μ„ ν†΅ν•˜μ—¬ κ΅¬ν˜„ν•˜λŠ”κ²ƒμ„ ꢌμž₯ν•œλ‹€.

Call By Value & Reference 의 차이

Java μ—μ„œ Call By Value λ₯Ό ν†΅ν•œ κ°’ 전달 방식은 객체의 볡사본이 μ „λ‹¬λœλ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€.
즉 원본 데이터에 영ν–₯을 주지 μ•ŠλŠ”λ‹€. 객체가 참쑰둜 μ „λ‹¬λ˜λ©΄ μ΄λŠ” μ‹€μ œ 객체가 μ „λ‹¬λ˜μ§€ μ•ŠλŠ” 참쑰객체의 전달 을 μ˜λ―Έν•œλ‹€.

CBV (Call By Value) 와 CBR (Call By Reference) 의 λΉ„κ΅μ˜ˆλ‘œλŠ” ν”νžˆ λ‹€μŒκ³Ό κ°™λ‹€.

equals 와 == 의 차이

λ¬Έμžμ—΄ λΉ„κ΅μ—μ„œ ν”ν•˜κ²Œ μ‚¬μš©ν•˜μ§€λ§Œ λ°˜ν™˜κ°’μ΄ boolean μ΄λΌλŠ” 곡톡점이 μžˆμ§€λ§Œ λ‹€μŒκ³Ό 같은 차이점이 μžˆλ‹€.

  • equals
    • λ©”μ„œλ“œ
    • λŒ€μƒμ˜ λ‚΄μš©μ„ 비ꡐ
  • ==
    • μ—°μ‚°μž
    • λŒ€μƒμ˜ μ£Όμ†Œκ°’μ„ 비ꡐ
String A = "abc";
String B = A;
String C = new String("abc");

System.out.println(A == B); // true
System.out.println(A == C); // false
System.out.println(B == C); // false

System.out.println(A.equals(B));  // true
System.out.println(A.equals(C));  // true
System.out.println(B.equals(C));  // true

equals μ—μ„œ κ°™μŒμ„ μ •μ˜ν•  λ•Œ hashCode 도 같이 μ •μ˜ν•΄μ€˜μ•Ό ν•œλ‹€.

객체λ₯Ό equals λ©”μ„œλ“œλ‘œ λ‚΄μš©μ˜ κ°™μŒμ„ μ •μ˜ν•˜μ˜€μŒμ—λ„ λΆˆκ΅¬ν•˜κ³  μ„œλ‘œ λ‹€λ₯Έ 객체 μ°Έμ‘°μ—μ„œ μ΄λ£¨μ–΄μ‘Œμ„λ•Œμ˜ μ˜ˆμ™Έμ²˜λ¦¬κ°€ ν•„μš”ν•œ κ²½μš°λ„ 있기 λ•Œλ¬Έμ΄λ‹€.

즉 λ‹€λ₯Έ λΆ€μž‘μš©μ΄ 생길 여지가 있기 λ•Œλ¬Έμ΄λ‹€.

Set<Person> set = new HashSet<>();

Person p1 = new Person("JDK", 27);
Person p2 = new Person("JDK", 27);

System.out.println("Person 1 : " + p1.hashCode()); // 2018699554
System.out.println("Person 2 : " + p2.hashCode()); // 1311053135

set.add(p1);
set.add(p2);

System.out.println(set.size());  // 2

μœ„μ—μ„œ 같은 λ‚΄μš©μ„ 가진 Object μž„μ—λ„ λΆˆκ΅¬ν•˜κ³  Set 에 2건이 μ€‘λ³΅μœΌλ‘œ μž…λ ₯λ˜μ—ˆλ‹€.

즉 λ°˜λ“œμ‹œ equals λ‘œλ„ 같은 객체라면 λ°˜λ“œμ‹œ hashCode 도 같은 κ°’ μ΄μ—¬μ•Όλ§Œ ν•œλ‹€.

참고자료

https://jeong-pro.tistory.com/172

hashCode() 에 λŒ€ν•΄

일반적으둜 Hash λ₯Ό μ‚¬μš©ν•œ Collection (HashMap, HashTable, HashSet, LinkedHashSet ... ) μ—μ„œ 객체의 Key λ₯Ό κ²°μ •ν• λ•Œ HashCode λ₯Ό μ‚¬μš©ν•œλ‹€.

μ΄λŠ” μ„œλ‘œ λ‹€λ₯Έ 객체의 비ꡐλ₯Ό μœ„ν•΄μ„œλ„ μ‚¬μš©λ˜λŠ”λ° == κ°€ λŒ€ν‘œμ μ΄λ©° Hash 값을 κ°•μ œμ μœΌλ‘œ μ£Όμž…μ‹œμΌœ 객체λ₯Ό κ°™κ²Œλ” μ„€μ •ν• μˆ˜λ„ μžˆλ‹€.

μ•„λž˜λŠ” λŒ€ν‘œμ μΈ HashCode 의 μƒμ„±λ‘œμ§μ΄λ‹€.


Β 








public int hashCode() {
  final int prime = 31;
  int hashCode = 1;

  hashCode = prime * hashCode + ((name == null) ? 0 : name.hashCode());
  hashCode = prime * hashCode + age;

  return hashCode;
}

31 을 승수둜 μ‚¬μš©ν•˜λŠ” 이유 ?

31 값은 μ†Œμˆ˜μ΄λ©° μ–΄λ–€μˆ˜μ— 31 을 κ³±ν•˜λŠ”κ²ƒ λ˜ν•œ λΉ λ₯΄κ²Œ μ—°μ‚° κ°€λŠ₯ν•˜λ‹€.
νŠΉμ • 값에 31N = 32N - N 인데 νŠΉμ • 값에 32을 κ³±ν•œκ°’μ€ shift μ—°μ‚°μœΌλ‘œ μ‰½κ²Œ κ΅¬ν˜„ κ°€λŠ₯ν•˜λ‹€.
λ”°λΌμ„œ νŠΉμ •κ°’ N 은 N << 5 - N κ³Ό κ°™μœΌλ―€λ‘œ 31을 κ³±ν•œ 연산은 μ΅œμ ν™”λœ λ¨Έμ‹  μ½”λ“œλ‘œ 생성 κ°€λŠ₯ν•˜λ‹€.

λ”°λΌμ„œ String ν΄λž˜μŠ€μ—μ„œ ν•΄μ‹œκ°’μ„ 계산할 λ•Œμ—λŠ” 31을 승수둜 μ‚¬μš©ν•œλ‹€.

HashCode 의 결정은 hashCode() λ©”μ„œλ“œμ—μ„œ native call 을 ν•˜μ—¬ Memory μ—μ„œ 가진 Hash Address 값을 좜λ ₯ν•œλ‹€.
νŠΉλ³„ν•˜κ²Œ 섀정이 μ—†λŠ” κ²½μš°μ—λŠ” κΈ°λ³Έκ°’μœΌλ‘œ System.identityHashCode() 와 λ™μΌν•œ 값을 λ‚˜νƒ€λ‚Έλ‹€.

String 의 클래슀의 hashCode() λ©”μ„œλ“œλŠ” Object 클래슀의 hashCode() 와 달리 @Override λ˜μ–΄ μžˆλŠ” μƒνƒœμ΄λ‹€.

String a = "a";
String _a = new String("a");

// a
System.out.println(a);
// a
System.out.println(_a);

// false
System.out.println(a == _a);
// true
System.out.println(a.equals(_a));

// true
System.out.println(a == _a.intern());

// 97
System.out.println(a.hashCode());
// 97
System.out.println(_a.hashCode());
// 97
System.out.println(_a.intern().hashCode());

// 708049632
System.out.println(System.identityHashCode(a));
// 1887400018
System.out.println(System.identityHashCode(_a));
// 708049632
System.out.println(System.identityHashCode(_a.intern()));

λ•Œλ¬Έμ— μ‹€μ œ ν…ŒμŠ€νŠΈ κ²°κ³Ό String ν΄λž˜μŠ€μ™€ Object 클래슀의 hashCode() λ©”μ„œλ“œμ˜ κ²°κ³Όκ°€ μƒμ΄ν•˜λ‹€.

Object a = new Object();
Object _a = new Object();

// false
System.out.println(a == _a);
// false
System.out.println(a.equals(_a));

// 708049632
System.out.println(a.hashCode());
// 1887400018
System.out.println(_a.hashCode());

// 708049632
System.out.println(System.identityHashCode(a));
// 1887400018
System.out.println(System.identityHashCode(_a));

객체 μž¬μ‚¬μš©

λŒ€ν‘œμ μœΌλ‘œ Singleton λ””μžμΈ νŒ¨ν„΄κ³Ό 같이 미리 사전에 μƒμ„±λœ Instance λ₯Ό μž¬μ‚¬μš©ν•˜λŠ” λ°©μ‹μœΌλ‘œ 일반적으둜 ThreadPool μ΄λ‚˜ Connection Pool λ“±μ˜ λ°©μ‹μœΌλ‘œ 주둜 μ‚¬μš©ν•œλ‹€.

μ΄ˆκΈ°ν™” λΈ”λŸ­ (Initialization Block)

클래슀 μ΄ˆκΈ°ν™” λΈ”λŸ­κ³Ό μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λΈ”λŸ­μ΄ μžˆλ‹€.

public class TEST {
  static int a;
  int b;

  static {
    System.out.println("Static initialization"); // 1
  }

  {
    System.out.println("Instance initialization"); // 2 // 4
  }

  public TEST() {
    System.out.println("Constructor"); // 3 // 5
  }

  public static void main(String[] args) {
    new TEST();
    new TEST();
  }
}
Static initialization
Instance initialization
Constructor
Instance initialization
Constructor

Reflection

λ¦¬ν”Œλ ‰μ…˜μ΄λž€ 객체의 ν΄λž˜μ„œ 정보λ₯Ό 뢄석해 λ‚΄λŠ” ν”„λ‘œκ·Έλž¨ 기법을 λ§ν•œλ‹€.

reflection 의 사전적인 의미투영 및 λ°˜μ‚¬μž…λ‹ˆλ‹€.

μ΄λŠ” 싀행쀑인 μžλ°” ν”„λ‘œκ·Έλž¨μ˜ λ‚΄λΆ€λ₯Ό κ²€μ‚¬ν•˜κ³  κ·Έ 속성을 μˆ˜μ •ν•  수 μžˆλ„λ‘ ν•œλ‹€.

μ‰½κ²Œ 말해 객체λ₯Ό ν†΅ν•˜μ—¬ 클래슀의 정보λ₯Ό μ—­μœΌλ‘œ λΆ„μ„ν•΄λ‚΄λŠ” ν”„λ‘œκ·Έλž˜λ° 기법 을 λ§ν•œλ‹€.

Class aClass = Test.class;

Class myObjClass = Class.forName(className);
Package pkgOfAClass = aClass.getPackage();

μ‚¬μš©

λ™μ μœΌλ‘œ λ‘œλ”©ν•˜κ³  λ™μ μœΌλ‘œ μ‹€ν–‰ν•˜κ³  μ‹Άμ„λ•Œ 주둜 μ‚¬μš©λœλ‹€.

μž¬μ‚¬μš©μ„±, ν™•μž₯μ„±, 생산성, μœ μ—°μ„± 등이 κ·ΉλŒ€ν™”λ  수 μžˆλŠ” 곳이여야 νš¨κ³Όμ μ΄λ‹€.

이슈

Runtime μ‹œμ— λ™μ μœΌλ‘œ μ›ν•˜λŠ” 라이브러리λ₯Ό λ‘œλ”©ν•  수 μž‡λŠ” μž₯점이 μžˆμ§€λ§Œ
μ»΄νŒŒμΌμ‹œμ— 탐색 (Detection) 이 μ•ˆλ˜μ–΄ Runtime Exception 이 μƒκΈΈμˆ˜ μžˆλŠ” 단점이 쑴재 ν•œλ‹€.

보톡은 λ™μ λ‘œλ”©μ΄ λŠλ¦¬λ‹€κ³  전해진닀 (ν™•μΈλΆˆκ°€)