빌드 툴인 gradle을 이용하여 의존성을 등록할 수 있다. build.gradle repositories { mavenCentral() } dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' } 'org.junit.jupiter:junit-jupiter-api:5.6.0'와 'org.junit.jupiter:junit-jupiter-engine' 라이브러리가 의존성 설치가 되도록 build.gradle에 등록되어 있다. 이 의존성 등록은 mavenCentral이라는 리포지토리에서 위 두 라이브러리에 대한 자료를 찾아..
NPE (Null Pointer Exception)은 가장 많이 발생하는 에러중 하나이다. 자바에서는 거의 모든것이 참조형이므로, 이는 다른말로 거의 모든것이 null이 될 수잇다. 그래서 항상 null을 확인할 필요가 있다. 이렇게 되면 굉장히 피곤해지게 되는데, 이거를 보완하기위해 이제 null을 쓰지 않기로 서로 약속하기로 한다. 근데 문법적으로 null을 없앨 수는 없고 (요즘은 null을 사용하면 error를 사용하기도 함) 그래서 notnull이나 nullable같은 애노테이션을 사용해서 null인지 아닌지 알아내서 문제를 막기도 한다. 어쨋든 개발자들끼리 null을 사용하지 않겠다고 서로 약속하고 프로그래밍을 하게 되는데, (계약 기반 프로그래밍) null을 쓰지 않는 방법으로 여러가지가 있..
자바에서는 collection 객체들에 대해서 stream으로 사용하는 방법을 제공해 준다. (이 stream은 자바 8 이상부터 사용 가능) 물론 System.in 과 System.out도 스트림이고, 우리가 계속 사용해왔던 거지만 자바 8에서 말하는 stream과는 다르다. 자바 8에서의 stream의 데이터의 스트림을 의미한다. 즉, Collections.stream()을 제공해 준다. 이 stream을 이용해서 collection의 데이터를 연속된 흐름으로써 취급할 수 있게 된다. stream에서는 filter, map, forEach 같은 고차함수(함수를 인자로 받는 함수)가 제공 됨 public class Main { public static void main(String[] args) { A..
자바에서 Collection 프레임워크를 제공하는데, 여기서 Collection의 뜻은 데이터의 묶음 이다. Collection 은 인터페이스(추상체)이다. 컬렉션의 구상체로 List가 있고, List의 구상체로 LinkedList, ArrayList, Vector, Stack이 있다. 마찬가지로 컬렉션의 구상체로 Set이 있고 Set의 구상체로 HashSet이 있다. LinkedList list1 = new LinkedList(); // LinkedList는 List 추상체를 구현한 것이므로 List 인터페이스로 표현할 수 있다. (다형성) List list2 = new LinkedList(); // ArrayList는 List 추상체를 구현한 것이므로 List 인터페이스로 표현할 수 있다. (다형성)..
자바 8에서 함수라는 단위가 계속 언급되고 있다. 거기서 함수형 인터페이스 라는 키워드가 등장하게 된다. 우선 이 함수형 인터페이스가 무엇인지 살펴보자. // 특별히 함수형 인터페이스라는 걸 알려주기 위한 애노테이션을 달아주기도 함 @FunctionalInterface public interface MyRunnable { void run(); // 추상 메소드가 하나밖에 없는 메소드 == 함수형 인터페이스 } // 얘는 추상 메소드가 2개이므로 함수형 인터페이스가 될 수 없다. interface MyRunnable2 { void run1(); void run2(); } // 얘도 함수형 인터페이스다. 왜냐면 '추상' 메소드는 하나이기 때문이다. // default, static method가 있는 것은 ..
현재 인터페이스는 굉장히 많은 형태로 사용되고 있다. 그러다보니 인터페이스의 단점들이 드러나기 시작하였고 그것을 해결하기위해 나온것이 디폴트 메서드(default method) 이다. 우선 default method의 역할을 살펴보자. 디폴트 메소드를 사용하면 인터페이스가 구현체(메소드의 구현부)를 가질 수 있게 된다. interface MyInterface { // 추상 메소드로만 이뤄진 클래스 == 인터페이스 void method1(); // 구현이 없다 : 추상 메소드 default void sayHello() { // 구현이 있다 (자바 8 부터 이런 구현 메소드를 인터페이스가 가질 수 있다) 대신 default 키워드를 써줘야 함 System.out.println("Hello World"); }..
Object 클래스는 모든 클래스의 최고 조상이므로 모든 클래스는 Object클래스 메소드를 사용할 수 있다. 그중에서 가장 많이쓰이는 메소드인 equals, hashCode, toString를 정리해 보았다. 1. equals 아래 코드는 Object 클래스에 정의 되어 있는 equals 메서드의 실제 내용이다. public boolean equals(Object obj) { return (this == obj) // 주소 비교 } 즉, 객체 자신(this)과 주어진 객체(obj)의 주소값을 비교한다. public class Main { public static void main(String[] args) { Value v1 = new Value(10); Value v2 = new Value(10); ..
자바에서 인터페이스는 추상클래스처럼 추상 메서드를 갖는다. 추상 클래스와 차이점은 멤버 변수를 구성원으로 가질 수 없고 메서드는 구현되어 있지 않아야 한다. 보통 인터페이스를 밑그림만 그려진 '기본 설계도' 라고 한다. 그럼 도대체 이러한 특성을 가지는 인터페이스를 왜 사용하는 걸까? 1. 구현을 강제 시킨다. interface Login { void login(); } public class KakaoLogin implements Login{ @Override public void login() { System.out.println("카카오로 로그인 합니다."); } } 위 코드와 같이 Login을 implements하게 될 경우 Login의 메서드인 login을 반드시 KakaoLogin에서 구현해 ..
StringBuffer와 StringBuilder의 차이를 보기전에 먼저 String 객체의 특성과 StringBuffer객체의 특성의 차이점을 먼저 살펴보아야 한다. 자바에서는 문자열을 String 객체로 많이 처리 한다. 특히, 문자열 리터럴의 경우 프로그램 실행시 자동으로 생성이 되는데, 이는 Constant Pool(상수 저장소)에 저장된다. 이때, 문자열들을 서로 결합하기위에 += 연산을 하게 되는데, String 객체는 불변(immutable) 하기 때문에 += 연산을 수행할 때마다 constant pool에 새로운 문자열 객체가 생겨나게 된다. 이렇게 되면 복잡한 문자열을 계산할때 쓸때없는 문자열 객체가 계속 쌓이게 되므로 비효율 적이다. 이를 해결하기 위한 것이 StringBuffer 객체..