β μ μ
- staticμ ν΄λμ€μ μνλ μ μ λ©€λ²
μΈμ€ν΄μ€ μμ΄ν΄λμ€λͺ .λ©μλλ‘ νΈμΆ κ°λ₯- JVMμ΄ ν΄λμ€ νμΌμ λ©λͺ¨λ¦¬μ μ¬λ¦΄ λ κ³ μ λ μμΉμ λ± ν λ² μμ±λμ΄ λͺ¨λ μΈμ€ν΄μ€κ° 곡μ ν¨.
βοΈ μΈμ€ν΄μ€ vs static
| κ΅¬λΆ | μΈμ€ν΄μ€ λ©€λ² | static λ©€λ² |
|---|---|---|
| μμ | κ°μ²΄(μΈμ€ν΄μ€)μ μν¨ | ν΄λμ€ μ체μ μν¨ |
| μ κ·Ό λ°©λ² | κ°μ²΄μ°Έμ‘°.νλ, λ©μλ() | ν΄λμ€λͺ .νλ, λ©μλ() |
| λ©λͺ¨λ¦¬ μμΉ | Heap μμ | Method Area μμ |
| μμ± μμ | κ°μ²΄ μμ± μ | ν΄λμ€ λ‘λ© μ |
| μ¬μ© λͺ©μ | κ° κ°μ²΄λ§λ€ κ³ μ ν λ°μ΄ν° | κ³΅ν΅ λ°μ΄ν°/κΈ°λ₯ 곡μ λͺ©μ |
-memory-
Class Loader
JVM Memory
Method AreaHeapJVM Language StacksPC RegistersNative Method Stacks
Execution Engine<->Native Method<->Native Method Libraries
class Person {
public static void greet() {
System.out.println("Hello from static method");
}
public void sayHello() {
System.out.println("Hello from instance method");
}
}
public class Main {
public static void main(String[] args) {
Person.greet();
Person p = new Person();
p.sayHello();
}
}
βμ¬μ© μ μ£Όμμ¬ν
π ν΅μ¬ μμ½ μ 리
| ν€μλ | μ€λͺ μμ½ |
|---|---|
| static | ν΄λμ€μ μμλλ κ³ μ λ©€λ² (μΈμ€ν΄μ€ μμ΄ μ κ·Ό κ°λ₯) |
| μ κ·Ό λ°©μ | ν΄λμ€λͺ .λ©μλ() λλ ν΄λμ€λͺ .νλ |
| μ₯μ | λ©λͺ¨λ¦¬ 곡μ , μ κ·Ό μλ λΉ λ¦, κ³΅ν΅ κΈ°λ₯ μ²λ¦¬μ μ ν© |
| μ£Όμμ¬ν | μΈμ€ν΄μ€ λ³μμ μ κ·Όν μ μμΌλ©°, λ¨μ© μ λ©λͺ¨λ¦¬ λΆλ΄ |
β μ μ
βΉοΈ outer class μμ κ΄κ³
π€ Why Inner Class?
class Car {
String brand;
public Car(String brand) {
this.brand = brand;
}
class Engine {
public void start() {
System.out.println("The engine of " + brand + " is starting...");
}
}
public void startEngine() {
Engine engine = new Engine();
engine.start();
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car("BMW");
car.startEngine();
}
}
β engine μ¬νμ© κ°λ₯ λ²μ
class Car {
String brand;
Engine engine;
public Car(String brand) {
this.brand = brand;
this.engine = new Engine();
}
class Engine {
public void start() {
System.out.println("The engine of " + brand + " is starting...");
}
}
public void startEngine() {
engine.start();
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car("BMW");
car.startEngine();
}
}
β inner class new ν€μλλ‘ μμ±
// 1. Outer instance μμ±
Main main = new Main();
// 2. Inner instance μμ± (outer.new μ¬μ©)
Main.Inner inner = main.new Inner();
// 3. Inner ν΄λμ€ λ©μλ νΈμΆ
inner.showMessage();
β κ°ν κ²°ν© μμ΄ ν΄λμ€ κ° νλ ₯
class Button {
interface OnClickListener {
void onClick();
}
private OnClickListener listener;
public void setOnclickListener(OnClickListener listener) {
this.listener = listener;
}
public void click() {
if (listener != null) {
listener.onClick();
}
}
// OnclickListenerλ₯Ό ꡬνν ClickHandler Innerclass
private class ClickHandler implements OnClickListener {
public void onClick() {
System.out.println("Button is Clicked");
}
}
public void simulateClick() {
setOnclickListener(new ClickHandler());
click();
}
}
public class Main {
public static void main(String[] args) {
Button button = new Button();
button.simulateClick();
}
}
β μ΄λ ν΄λμ€μ λ©λͺ¨λ¦¬
public class Outer {
private String data = "Outer data";
class Inner {
void printData() {
System.out.println(data);
}
}
public Inner createInner() {
return new Inner();
}
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.createInner();
inner.printData();
outer = null; // outer μΈμ€ν΄μ€κ° null μ΄ λμ΄λ Inner μΈμ€ν΄μ€λ₯Ό μ°Έμ‘°νκ³ μλ inner λ μ¬λΌμ§μ§ μλλ€.
inner.printData();
inner = null;
System.gc();
}
}
class Outer {
static class StaticInner {
void hello() {
System.out.println("Hi!");
}
}
}
public class Main {
public static void main(String[] args) {
Outer.StaticInner inner = new Outer.StaticInner();
inner.hello();
}
}
Inner vs Static Nested Class
| κ΅¬λΆ | Inner Class | Static Nested Class |
|---|---|---|
| Outer μΈμ€ν΄μ€ νμ | O | X |
| μ κ·Ό κ°λ₯ λ©€λ² | Outerμ λͺ¨λ λ©€λ² | static λ©€λ²λ§ |
| μ¬μ© μμ | λ©€λ² λμ°λ―Έ ν΄λμ€ | μ νΈλ¦¬ν°, ꡬ쑰 λΆλ¦¬ |
| λ©λͺ¨λ¦¬ κ΄λ¦¬ | Outer κ°μ²΄μ ν¨κ» | λ 립 κ°μ²΄λ‘ κ΄λ¦¬ |
β μ μ
- μ΄λ¦μ΄ μλ μΌνμ± ν΄λμ€
- μ£Όλ‘ μΈν°νμ΄μ€λ μΆμ ν΄λμ€λ₯Ό μ¦μ ꡬνν λ μ¬μ©
- μ¬μ¬μ©μ μ΄λ ΅μ§λ§ κ°λ¨ν ꡬνμ μ μ©
β interface Greeting μμ±
- μ΅λͺ ν΄λμ€λ κΈ°λ°μ΄ λλ μΈν°νμ΄μ€κ° νμ
- void greet() λ©μλλ§ μ μΈ
β μ΅λͺ ν΄λμ€ μμ± λ°©λ²
- new μΈν°νμ΄μ€λͺ () { ꡬν } ννλ‘ μ μ
- μ€κ΄νΈ λ΄μμ λ©μλλ₯Ό μ¦μ μ€λ²λΌμ΄λ©
interface Greeting {
void greet();
}
class GClass implements Greeting {
public void greet() {}
}
public class Main {
public static void main(String[] args) {
// GClass λ₯Ό κ±°μΉμ§ μκ³ λ°λ‘ μ μΈκ³Ό ꡬνμ λμμ νλ anonymoust class Greeting
Greeting greeting = new Greeting() {
public void greet() {
System.out.println("Hello World");
}
};
greeting.greet();
}
}
interface Calculator {
int compute(int a, int b);
}
class CalculatorMachine implements Calculator {
@Override
public int compute(int a, int b) {
return a * b;
}
}
public class Main {
public static void main(String[] args) {
// 1. κ°λ¨νκ² κΈ°λ₯μ ꡬνν΄μ λ°λ‘ ν
μ€νΈ νλ €λ©΄ anonymous classλ₯Ό μ¬μ©νλ©΄ λλ€.
Calculator multiply = new Calculator() {
public int compute(int a, int b) {
return a * b;
}
};
Calculator add = new Calculator() {
public int compute(int a, int b) {
return a + b;
}
};
// μ«μλ₯Ό λ¬Έμλ‘ λ°μ ν©μΉ λ€ λ€μ μ«μλ‘ λ°ννλ connectNum κΈ°λ₯
Calculator connectNum = new Calculator() {
public int compute(int a, int b) {
return Integer.parseInt("" + a + b);
}
};
System.out.println(multiply.compute(3, 4)); //12
System.out.println(add.compute(3, 4)); //7
System.out.println(connectNum.compute(3, 4)); //34
// 2. λ§μ½ κΈ°λ₯μ μ¬λ¬ λ² μ¬μ©νκ³ μΆμΌλ©΄ classμ implement ν΄μ κ·Έ instance λ₯Ό κ°μ§κ³ μ€νμν€λ κ²μ΄ λ«λ€.
CalculatorMachine machine = new CalculatorMachine();
System.out.println(machine.compute(1, 2)); //2
System.out.println(machine.compute(10, 20)); //200
}
}
λλ€μκ³Ό λΉκ΅
μ΅λͺ ν΄λμ€ vs λλ€μ
| νλͺ© | μ΅λͺ ν΄λμ€ | λλ€μ |
|---|---|---|
| μ΄λ¦ | μμ | μμ |
| ꡬν λμ | μΈν°νμ΄μ€/μΆμ ν΄λμ€ | ν¨μν μΈν°νμ΄μ€ |
| μ½λ κΈΈμ΄ | λΉκ΅μ κΈΈλ€ | κ°κ²°νλ€ |
| μν 보μ | κ°λ₯ | μ νμ |
class CPU {
public int register = 0; // register μ₯μΉ
public int[] memory = {4, 5, 6}; // memory
int pc = 0;
private static final int LOAD = 1;
private static final int SAVE = 2;
private static final int ADD = 3;
private static final int SUB = 4;
private static final int HALT = 5;
// assembly
private int[][] program = { // { operator , memory location }
{ LOAD, 0 }, // register = memory[0]
{ ADD, 1 }, // register = register + memory[1]
{ SAVE, 2 }, // memory[2] = register
{ HALT, 0 } // stop program execution
};
public void executeProgram() {
while(true) {
int opcode = program[pc][0]; // {LOAD, ADD, SAVE, HALT}
int operand = program[pc][1]; // {0, 1, 2, 0}
switch (opcode) {
case LOAD:
register = memory[operand];
System.out.println("MOV: Loading memory[" + operand + "] (" + memory[operand] + ") to Register.");
System.out.println("Register : " + register);
break;
case SAVE:
memory[operand] = register;
System.out.println("MOV: Saving memory[" + operand + "] (" + memory[operand] + ") to Register.");
System.out.println("Register : " + register);
break;
case ADD:
register += memory[operand];
System.out.println("MOV: Adding memory[" + operand + "] (" + memory[operand] + ") to Register.");
System.out.println("Register : " + register);
break;
case SUB:
register -= memory[operand];
System.out.println("MOV: Subtracting memory[" + operand + "] (" + memory[operand] + ") from Register.");
System.out.println("Register : " + register);
break;
case HALT:
System.out.println("MOV: Stopping program.");
return;
default:
System.out.println("Unknown instruction. Halting... opcode : " + opcode);
return;
}
pc++;
}
}
}
public class Main {
public static void main(String[] args) {
CPU cpu = new CPU();
cpu.executeProgram();
System.out.println("Final memory state: memory[" + (cpu.pc-1) + "] = " + cpu.memory[cpu.pc-1]);
}
}