2021-02-11-TIL
2021-02-11-TIL
class의 List를 반복할 때는 향상된 for문을 사용해도 참조값을 통해 접근하므로, 직접적인 값의 변경이 가능하다.
향상된 for문의 루프 변수에는 리스트 원소의 참조값이 복사되어 들어온다. 그래서 item.setCount(0)처럼 그 참조를 통해 객체의 필드를 바꾸면 리스트 안의 객체가 바뀐다. 반대로 item = new Item()처럼 루프 변수 자체에 다른 객체를 대입하면 지역 변수만 바뀌고 리스트는 그대로다. 원소를 다른 객체로 바꾸거나 Integer, String 같은 불변 객체의 값을 바꾸려면 인덱스 기반 for문과 list.set(i, ...)을 써야 한다.
Convert List to Array in Java
List<String>은 list.toArray(new String[0])로 타입이 있는 배열로 바꾼다. List<Integer>를 int[]로 바꿀 때는 박싱된 Integer를 풀어야 하므로 toArray로는 안 되고, list.stream().mapToInt(Integer::intValue).toArray()를 쓴다.
- https://stackoverflow.com/questions/9572795/convert-list-to-array-in-java
- https://stackoverflow.com/questions/960431/how-to-convert-listinteger-to-int-in-java
Is the Inner class must be static in Java?
static이 아닌 내부 클래스(inner class)의 인스턴스는 바깥 클래스의 인스턴스에 묶여 있고, 바깥 인스턴스에 대한 숨은 참조를 가진다. 그래서 main() 같은 static 문맥에서 new Inner()를 바로 호출하면 바깥 인스턴스가 없어서 컴파일 오류가 난다. 바깥 인스턴스의 필드에 접근할 필요가 없다면 static 중첩 클래스로 선언하는 것이 맞다. 불필요한 바깥 참조가 없어 메모리 누수 위험도 줄어든다.
https://stackoverflow.com/questions/2874074/must-the-inner-class-be-static-in-java#:~:text=For%20a%20non%2Dstatic%20inner,the%20%22owner%22%20object%20instance.&text=So%20the%20inner%20class%20must,within%20a%20non%2Dstatic%20context.
java.lang.ClassNotFound
IntelliJ에서 어떤 프로젝트를 실행해도 빌드 단계에서 같은 오류가 나는 경우다. 링크의 질문은 IntelliJ 빌드 시스템(JPS)의 증분 빌드 캐시가 꼬여서 생긴 문제였고, 답변들은 Build > Rebuild Project로 전체를 다시 빌드하거나 File > Invalidate Caches / Restart로 캐시를 지우는 방법을 제시한다. 코드에는 문제가 없는데 클래스를 못 찾는다면 먼저 IDE의 빌드 산출물과 캐시를 의심해 볼 만하다.
https://stackoverflow.com/questions/64336525/how-do-i-fix-an-error-in-intellij-that-prevents-me-from-running-my-projects
PrioriyQueue
PriorityQueue에 직접 만든 객체를 넣으려면 그 클래스가 Comparable을 구현하거나 생성자에 Comparator를 넘겨야 한다. 둘 다 없으면 원소를 추가하는 시점에 ClassCastException이 난다. 또 이 클래스는 스레드 안전하지 않아서, 여러 스레드가 함께 쓰면 PriorityBlockingQueue를 써야 한다.
https://www.callicoder.com/java-priority-queue/
Assert in Java
assert 조건 : 메시지;는 조건이 거짓이면 AssertionError를 던진다. 다만 assertion은 기본적으로 꺼져 있어서 JVM을 -ea 옵션으로 실행해야 동작한다. 그래서 사용자 입력 검증 같은 실제 로직에 쓰면 안 되고, “여기서는 절대 이럴 리 없다”는 내부 가정을 개발 중에 확인하는 용도로 쓴다.
https://www.baeldung.com/java-assert
Git branch 옮기기
기능 A 브랜치에 기능 B의 커밋이 섞여 버린 상황을 정리하는 글이다. B 커밋을 시작할 지점에서 새 브랜치를 만들고 git cherry-pick으로 해당 커밋들을 복사한 뒤, 원래 브랜치에서는 git reset --hard로 섞인 커밋을 걷어 낸다. 이미 원격에 푸시한 브랜치에서 reset --hard를 하면 이력이 바뀌어 강제 푸시가 필요하므로, 다른 사람과 공유한 브랜치라면 먼저 합의해야 한다.
https://reese-dev.netlify.app/git/seperate_branch/
JUnit5
JUnit 5는 JUnit Platform(테스트 실행 기반), JUnit Jupiter(새 프로그래밍 모델), JUnit Vintage(JUnit 3/4 테스트 실행)로 나뉜다. @Test, @BeforeEach, @DisplayName, @ParameterizedTest, assertThrows() 같은 기능을 쓰고, JetBrains 글은 IntelliJ에서 JUnit 5 테스트를 만들고 실행하는 흐름을 보여 준다.
https://blog.jetbrains.com/idea/2020/09/writing-tests-with-junit-5/
자바 리플렉션
리플렉션은 런타임에 클래스의 정보(생성자, 메서드, 필드, 애너테이션)를 조회하고 호출하는 기능이다. Class.forName("...")이나 obj.getClass()로 Class 객체를 얻고, getDeclaredMethods(), getDeclaredField()로 멤버를 꺼내 invoke(), set()을 호출한다. 컴파일 시점에 타입을 모르는 객체를 다뤄야 하는 프레임워크(Spring의 DI, JPA, JUnit)가 이 기능 위에서 동작한다. 대신 컴파일러의 타입 검사를 받지 못하고, 일반 호출보다 느리며, setAccessible(true)로 캡슐화를 깰 수 있다는 단점이 있다.
https://brunch.co.kr/@kd4/8
EOF를 붙이는 이유
여기서 EOF는 파일 끝에 개행 문자를 붙이는 것을 말한다. POSIX는 줄(line)을 0개 이상의 개행이 아닌 문자와 그 뒤의 종료 개행 문자로 정의한다. 이 정의를 따르면 마지막에 개행이 없는 줄은 완전한 줄이 아니어서, cat으로 여러 파일을 이어 붙이거나 wc -l로 줄 수를 셀 때 결과가 어긋나고, Git diff에도 “No newline at end of file” 표시가 생긴다. IntelliJ에서는 Editor > General의 “Ensure every saved file ends with a line break” 옵션으로 저장할 때 자동으로 붙일 수 있다.
https://stackoverflow.com/questions/16761227/how-to-make-intellij-idea-insert-a-new-line-at-every-end-of-file
https://blog.coderifleman.com/2015/04/04/text-files-end-with-a-newline/
댓글
아직 댓글이 없습니다