자바는 썬 마이크로시스템즈의 제임스 고슬링(James Gosling)과 연구원들이 개발한 객체 지향 프로그래밍 언어로 1995년에 발표되었다. 처음에는 가전제품에 탑재해 동작하는 프로그램을 만들기 위해 탄생했으나 지금은 웹과 모바일 앱 개발에서 가장 많이 사용하는 언어로 성장했다.
JVM은 Java 바이트코드를 실행하는 가상 머신이다. 운영 체제와 무관하게 Java 프로그램이 실행될 수 있도록 하는 핵심 컴포넌트이다.
JRE는 Java 프로그램을 실행하기 위한 환경이다. JVM을 포함하며, Java 애플리케이션이 실행되기 위해 필요한 라이브러리와 구성 요소를 제공한다.
JAVA version | 특징 |
---|---|
6 | - interface에 @Override 추가됨 - JDBC 4.0 - Scripting Language Support - Java Compiler API - pluggable annotation |
8 | - lambda expression - type annotation - stream api 추가 - repeating annotation - static link library - interface default method - unsigned integer 계산 - 날짜와 시간 API(new) -> JodaTime - rhino 대신 nashorn javascript 엔진 탑재 |
11 | - 람다 지역변수 var 키워드 사용 가능 - G1 GC가 기본 GC로 설정 (GC : Garbage Collection) - 컬렉션, 스트림 등에 메소드 추가 |
17 | - recode class 키워드 사용 가능 - 애플 M1 및 이후 프로세서 탑재 제품군에 대한 정식 지원 - 난수 생성 API 추가 - 봉인 클래스(Sealed Class) 정식 추가 - String 여러줄 사용시 텍스트 블록 기능 사용 가능 - NumberFormat,DateTimeFormatter 기능 향상 - Stream.toList() 사용 가능 |
static을 사용하여 JVM이 클래스의 인스턴스를 생성하지 않고 바로 main 메소드를 호출하기 위함
public class MainExample {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b); // false (메모리 주소가 다름)
System.out.println(a.equals(b)); // true (내용이 같음)
String a = "Hello";
String b = "Hello";
System.out.println(a == b); // true (리터럴은 같은 메모리를 참조)
System.out.println(a.equals(b)); // true (내용이 같음)
class Person {
String name;
Person(String name) {
this.name = name;
}
}
Person p1 = new Person("John");
Person p2 = new Person("John");
System.out.println(p1 == p2); // false (메모리 주소가 다름)
System.out.println(p1.equals(p2)); // true (내용이 같음)
특징 | equals() | hashCode() |
---|---|---|
목적 | 객체의 내용(논리적 동등성)을 비교 | 객체를 고유한 정수로 나타내며, 해시 기반 데이터 구조에서 사용 |
비교 기준 | 객체의 속성 값(내용)을 기준으로 비교 | 객체의 해시코드(정수 값)를 반환 |
기본 구현 | Object 클래스에서는 참조 주소 비교 | Object 클래스에서는 메모리 주소를 기반으로 해시 생성 |
재정의 필요성 | 동등성을 정의하려면 반드시 재정의 필요 | equals 재정의 시 반드시 함께 재정의 필요 |
사용 대상 | 모든 데이터 구조에서 객체 동등성 확인 가능 | 주로 해시 기반 컬렉션(HashMap, HashSet 등)에서 사용 |
중요한 규칙 | a.equals(b) == true라면 a.hashCode() == b.hashCode()여야 함 | 같은 hashCode()를 가진 객체라도 equals()는 false일 수 있음 |
example) hashCode() 정의 안한 경우
import java.util.HashSet;
class Person {
private String name;
public Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return name.equals(person.name);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice");
Person p2 = new Person("Alice");
HashSet<Person> set = new HashSet<>();
set.add(p1);
set.add(p2);
System.out.println(set.size()); // 출력: 2
}
}
example) hashCode() 정의 한 경우
import java.util.HashSet;
import java.util.Objects;
class Person {
private String name;
public Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name); // equals()와 일관된 기준으로 hashCode 생성
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice");
Person p2 = new Person("Alice");
HashSet<Person> set = new HashSet<>();
set.add(p1);
set.add(p2);
System.out.println(set.size()); // 출력: 1
}
}
@Override 안한 경우
class Person {
private String name;
public Person(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice");
System.out.println(p1.toString());
// 출력: Person.p1@26f0a63f
}
}
@Override한 경우
class Person {
private String name;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return this.name;
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice");
System.out.println(p1.toString());
// 출력: Alice
}
}
이름 | 정의 | 비고 |
---|---|---|
상수 | 고정된 값으로, 변수처럼 이름이 붙음, 한 번 초기화되면 변경 불가, final 키워드로 선언 | final 키워드는 변수, 메소드, 클래스에 선언 가능 final로 선언시 재할당할려고 하면 컴파일 오류가 발행 |
리터럴 | 코드에 직접적으로 나타나는 값, 변경 불가, 값 그 자체로 사용 | |
변수 | 변수(variable) 하나의 값을 저장하기 위한공간, 변경 가능 |
Call by Value
public class Main {
public static void modifyValue(int x) {
x = 10; // 복사본의 값을 변경
System.out.println("Inside method: x = " + x);
}
public static void main(String[] args) {
int a = 5;
System.out.println("Before method: a = " + a);
modifyValue(a); // a의 값이 복사되어 전달됨
System.out.println("After method: a = " + a); // 원본은 변경되지 않음
}
}
/*
* Before method: a = 5
* Inside method: x = 10
* After method: a = 5
*/
Call by Reference
public class Main {
public static void modifyArray(int[] arr) {
arr[0] = 10; // 참조된 객체의 내용을 변경
System.out.println("Inside method: arr[0] = " + arr[0]);
}
public static void main(String[] args) {
int[] array = {1, 2, 3};
System.out.println("Before method: array[0] = " + array[0]);
modifyArray(array); // 배열의 참조값이 전달됨
System.out.println("After method: array[0] = " + array[0]); // 원본 변경됨
}
}
/*
* Before method: array[0] = 1
* Inside method: arr[0] = 10
* After method: array[0] = 10
*/
특징 | Primitive Type | Reference Type |
---|---|---|
정의 | 기본 타입은 값(value)을 직접 저장하는 데이터 타입 | 참조 타입은 객체(Object) 또는 배열의 참조(주소)를 저장하는 데이터 타입 변수에는 실제 데이터가 아니라 데이터가 저장된 메모리의 주소값이 저장됩니다. |
데이터 저장 방식 | 값 자체를 저장 | 데이터가 저장된 메모리 주소를 저장 |
저장 위치 | 스택(Stack) | 참조 값은 스택, 데이터는 힙(Heap)에 저장 |
초기화 값 | 타입별 기본값 존재 | null |
메모리 효율성 | 고정된 크기, 메모리 효율적 | 객체 크기에 따라 달라짐 |
사용 예 | byte, short, int ,long, float, double, char, boolean | 배열, 클래스, 인터페이스, 열거형 등 |
GC(Garbage Collector) | 해당 없음 | 사용되지 않는 객체를 자동으로 정리 |
성능 | 상대적으로 빠름 | 객체 접근 시 상대적으로 느림 |
값 비교 | 값 자체 비교 (==) | 주소 또는 내용 비교 (== 또는 equals) |
특징 | 설명 |
---|---|
목적 | 행동(메서드 시그니처) 정의 |
상속 관계 | 다중 구현 가능 (다중 상속 지원) |
메서드 | Java 8 이전: 추상 메서드만 Java 8 이후: 디폴트 및 정적 메서드 포함 |
필드 | public static final(상수)만 가능 |
상속 키워드 | implements 사용 |
추가 기능 | Java 9 이후 private 메서드 제공 |
사용성 | 특정 행동을 구현하도록 강제 (다중 행동 계약 가능) |
example)
public interface Animal {
void eat(); // 추상 메서드
void sleep(); // 추상 메서드
}
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog eats food.");
}
@Override
public void sleep() {
System.out.println("Dog sleeps.");
}
}
특징 | 설명 |
---|---|
목적 | 공통 상태와 행동 제공 |
상속 관계 | 단일 상속만 가능 |
메서드 | 추상 메서드와 일반 메서드 모두 포함 가능 |
필드 | 모든 종류의 필드 선언 가능 |
상속 키워드 | extends 사용 |
추가 기능 | 생성자, 필드 초기화, 상태 관리 가능 |
사용성 | 공통 상태 및 기본 동작을 제공 |
example)
public abstract class Animal {
protected String name; // 필드
public Animal(String name) {
this.name = name;
}
public abstract void makeSound(); // 추상 메서드
public void eat() { // 일반 메서드
System.out.println(name + " is eating.");
}
}
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " says Woof!");
}
}
https://wikidocs.net/190
https://i3utterfly.tistory.com/entry/JAVA-버전별-정리
https://www.oracle.com
https://velog.io/@calis_ws/Java-hashCode-란
https://devlog-wjdrbs96.tistory.com/243
https://study-developmnet.tistory.com/6
https://velog.io/@god1hyuk/Javaclass-오버라이딩overriding과-오버로딩overloading
https://velog.io/@gillog/Java-Interface-vs-Abstract-Class-정리