자바는 정적 타입검사 언어
자바는 강타입언어
하지만 버전이 넘어가면서 여러가지 타입에 대한 기능 제공
primitve Type: int, short, long, byte, float, double boolean, char (+String)
reference type: interface/class/array
-> array 가 있다..!
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_PARAMETER)
public @interface Pizza {
}
In the context of lambda expressions, target typing refers to the ability of the compiler to infer the type of a lambda expression from its target context.
Map<String, Map<String, String>> mapOfMapsInferred = new HashMap<>();
List<Allergens> sortedAllergens = Arrays.stream(Allergens.values())
.sorted(Comparator.comparing(Allergens::getSeason))
.collect(Collectors.toList());
이 예제에서는 람다 식을 Allergens::getSeason lambda 식과 동일한 메서드 참조입니다. allergen -> allergen.getSeason(). 컴파일러는 대상 유형을 사용합니다. Comparator 람다 식의 유형을 추론합니다.
100_000int unsigned 화잠금없이 변수를 Atomic 하게 제어할 때 사용
AtomicInteger 와 같은 Atomic 객체 대신 상용
// Declaration and Initialization Example
class SafePin {
int pin;
}
class ModifySafePin {
// Declare a static final VarHandle for the "pin" field
private static final VarHandle VH_PIN;
static {
try {
// Initialize the VarHandle by finding it for the "pin" field of SafePin class
VH_PIN = MethodHandles.lookup().findVarHandle(SafePin.class, "pin", int.class);
} catch (Exception e) {
// Throw an error if VarHandle initialization fails
throw new Error(e);
}
}
}
// Atomic Update Example
class ModifySafePin {
private static final VarHandle VH_PIN = ModifySafePin.getVarHandle();
private static VarHandle getVarHandle() {
try {
// Find and return the VarHandle for the "pin" field of SafePin class
return MethodHandles.lookup().findVarHandle(SafePin.class, "pin", int.class);
} catch (Exception e) {
// Throw an error if VarHandle initialization fails
throw new Error(e);
}
}
public static void atomicUpdatePin(SafePin safePin, int newValue) {
int prevValue;
do {
prevValue = (int) VH_PIN.getVolatile(safePin);
} while (!VH_PIN.compareAndSet(safePin, prevValue, newValue));
}
}
계속해서 atomic 하게 업데이트
ref: https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/MethodHandles.html
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public String getDayName(Day day) {
return switch (day) {
case MONDAY -> "Monday";
case TUESDAY -> "Tuesday";
case WEDNESDAY, THURSDAY -> {
String s = day == Day.WEDNESDAY ? "Midweek" : "Almost Weekend";
yield s; // yield is used to return a value from a block of code
}
// Other cases …
default -> throw new IllegalArgumentException("Invalid day: " + day);
};
}
yeild 와 -> arrow statement
sealed abstract class Pet permits Mammal, Reptile {}
sealed abstract class Mammal extends Pet permits Cat, Dog, PygmyPossum {
abstract boolean isAdult();
}
final class Cat extends Mammal {
boolean isAdult() {
return true;
}
// Cat-specific properties and methods
}
// Similar implementations for Dog and PygmyPossum
sealed abstract class Reptile extends Pet permits Snake, BeardedDragon {
abstract boolean isHarmless();
}
final class Snake extends Reptile {
boolean isHarmless() {
return true;
}
// Snake-specific properties and methods
}
// Similar implementation for BeardedDragon
sealed abstract class 의 permits 를 미리 지정 (약간 귀찮...?)
kotlin data class 와 같음
public record Pet (String name, int age, String breed) {}
----
List<Pet> pets = List.of(
new Pet("Ruby", 2, "Great Pyrenees and Red Heeler Mix", true),
new Pet("Bash", 1, "Maltese Mix", false),
new Pet("Perl", 10, "Black Lab Mix", true)
);
List<Pet> adultPets = pets.stream()
.filter(Pet::isAdult)
.collect(Collectors.toList());
adultPets.forEach(pet -> System.out.println(pet.name() + " is an adult " + pet.breed()));


###Java Object Layout(JOL)을 이용한 Object Memory Layout 분석
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;
import static java.lang.System.out;
public class ArrayLayout {
public static void main(String[] args) throws Exception {
out.println(VM.current().details());
byte[] ba = new byte[8];
out.println(ClassLayout.parseInstance(ba).toPrintable());
}
}
# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# WARNING | Compressed references base/shifts are guessed by the experiment!
# WARNING | Therefore, computed addresses are just guesses, and ARE NOT RELIABLE.
# WARNING | Make sure to attach Serviceability Agent to get the reliable addresses.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
[B object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 …) (1)
4 4 (object header) 00 00 00 00 (00000000 …) (0)
8 4 (object header) 48 68 00 00 (01001000 …) (26696)
12 4 (object header) 08 00 00 00 (00001000 …) (8)
16 8 byte [B.<elements> N/A
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.

[B object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 …) (1)
4 4 (object header) 00 00 00 00 (00000000 …) (0)
8 4 (object header) 48 68 00 00 (01001000 …) (26696)
12 4 (object header) 08 00 00 00 (00001000 …) (8)
16 8 byte [B.<elements> N/A
public class MorningPeopleArray {
public static void main(String[] args) throws Exception {
out.println(VM.current().details());
// Create an array of MorningPeople objects
MorningPeople[] mornpplarray = new MorningPeople[8];
// Print the layout of the MorningPeople class
out.println(ClassLayout.parseClass(MorningPeople.class).toPrintable());
// Print the layout of the mornpplarray instance
out.println(ClassLayout.parseInstance(mornpplarray).toPrintable());
}
}
class MorningPeople {
String name;
Boolean type;
public MorningPeople(String name, Boolean type) {
this.name = name;
this.type = type;
}
}
# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# WARNING | Compressed references base/shifts are guessed by the experiment!
# WARNING | Therefore, computed addresses are just guesses, and ARE NOT RELIABLE.
# WARNING | Make sure to attach Serviceability Agent to get the reliable addresses.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
MorningPeople object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 12 (object header) N/A
12 4 java.lang.String MorningPeople.name N/A
16 4 java.lang.Boolean MorningPeople.type N/A
20 4 (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
[LMorningPeople; object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) (1)
4 4 (object header) (0)
8 4 (object header) (13389376)
12 4 (object header) (8)
16 32 MorningPeople MorningPeople;.<elements> N/A
Instance size: 48 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
불변객체
// An immutable class by declaring it final
final class MorningPeople {
private final String name;
private final Boolean type;
public MorningPeople(String name, Boolean type) {
this.name = name;
this.type = type;
}
// Getter methods for name and type
public String getName() {
return name;
}
public Boolean getType() {
return type;
}
}
MorningPeople 메모리 독립객체, 그리고 불변객체헤더를 제거, primitive type 과 유사한 인라인 스토리지
원시유형도 제네릭 지원에 포함
public class FreshmenAdmissions<K, any V> {
K key;
V boolornumvalue;
public void admissionInformation(K name, V value) {
key = name;
boolornumvalue = value;
}
}
any V 는 primitive type 도 지원하는 generic 이 됨
java 에 value class, primitive class, generic 향상
== 을 사용하는 경우 ID 가 아닌 콘텐츠 동일성 확인 (값 클래스는 id 가 없음)이제 primitive type 을 다른유형하고 다르게 취급할 필요없기 때문에 type 시스템이 우아해짐
Project Valhalla는 가치 클래스와 프리미티브 클래스를 메모리에 직접 저장할 수 있도록 하고 제네릭을 개선하여 이러한 유형과 더 잘 작동하도록 함으로써 메모리 사용량을 줄이고 Java 애플리케이션의 성능을 향상시키는 것을 목표
JEP 401: Value Class and Objects 는 얼리 억세스로 릴리즈됨 (EA)