JVM: 자바가 실행되기 위해서 필요: 자바 실행 환경(JRE) -> java 명령어만, 버추얼 머신만 있는 경우
JRE + 개발툴 -> 개발 환경: JDK -> java + javac명령어까지
역사
콘솔 창에
java --version과 javac --version을 터미널에 입력하여 설치 여부/버전을 확인한다.명령어 관하여
javac ClassName.javajava ClassNameError: Could not find or load main class 클래스 경로를 확인하지 못 해서 발생한 문제임;.을 환경 변수 마지막에 넣어주면, 추가적으로 현재 확인하고 있는 경로에서도 클래스 파일을 찾는다.일일히 자바 파일을 컴파일하는 귀찮다. -> 빌드를 자동화하자: 빌드 툴의 등장
자바의 빌드 툴
Gradle 직접 설치해보기
gradle --version을 터미널에 입력하여 설치 여부 확인Gradle 사용해보기
프로젝트 생성: gradle init명령어
프로젝트 구조: tree 명령어 이용해서 보면
├─.gradle
├─app
│ └─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─programmers
│ │ │ └─java
│ │ └─resources
│ └─test
│ ├─java
│ │ └─com
│ │ └─programmers
│ │ └─java
│ └─resources
└─gradle
└─wrapper
build.gradle 빌드 스크립트이다.Task명령어
gradle build, gradle run 등
build.gradle에 tasks.named("test") 형태로 작업이 명시되어 있다.
gradle test를 실행하면 위의 tasks의 test라 명명된 작업이 실행된다.그런데, build. run의 경우는 위와 같은 task 설명이 없다.
자바 프로젝트에서 공통적으로 많이 쓰이는 부분들의 taskset은 이미 규정되어 있다.
-> plugin
gradle tasks명령어로 종류 확인 가능
------------------------------------------------------------
Tasks runnable from root project 'HelloWorld'
------------------------------------------------------------
Application tasks
-----------------
run - Runs this project as a JVM application
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles test classes.
Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.
Distribution tasks
------------------
assembleDist - Assembles the main distributions
distTar - Bundles the project as a distribution.
distZip - Bundles the project as a distribution.
installDist - Installs the project as a distribution as-is.
Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.
Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'HelloWorld'.
dependencies - Displays all dependencies declared in root project 'HelloWorld'.
dependencyInsight - Displays the insight into a specific dependency in root project 'HelloWorld'.
help - Displays a help message.
javaToolchains - Displays the detected java toolchains.
outgoingVariants - Displays the outgoing variants of root project 'HelloWorld'.
projects - Displays the sub-projects of root project 'HelloWorld'.
properties - Displays the properties of root project 'HelloWorld'.
tasks - Displays the tasks runnable from root project 'HelloWorld' (some of the displayed tasks may belong to subprojects).
Verification tasks
------------------
check - Runs all checks.
test - Runs the test suite.
gradle tasks extension 설치하여 간편하게 확인, 실행 가능하다.VS Code(코드편집용)와 gradle, 그리고 extension들을 이용해도 일일히 각각을 실행해 줘야 하는 불편함이 있다.
-> 통합 개발 환경(IDE; Integrated Development Environment)이 필요한 까닭
자바 개발자들이 주로 사용하는 IDE
IDE는 생산성을 증대시켜준다.
단축키를 적절히 사용하면 생산성이 더 증가한다.
자바를 쓴다고 해서 포인터를 몰라서는 안 된다!
alloc/free를 개발자가 신경 쓰지 않아도 될 뿐이다.자바의 primitive value를 제외한 모든 것은 reference value다!
primitive: boolean, byte, int, short, long, float, double, char
int a =100일 때, a를 전달 -> 값을 전달
Integer b = 100일 때, b를 전달 -> b의 레퍼런스를 전달
Call by value / Call by reference
array는 reference처럼 취급한다.
int[], boolean[]문자열을 만드는 방법
String 클래스의 생성자를 사용해서 만드는 방법 String stringByConstructor = new String("Hello, World!")String stringByLiteral = "Hello, World!"생성자를 이용할 경우
new 연산자에 의해 메모리가 할당되기에
항상 새로운 인스턴스가 생성
아래의 코드에서
String stringByConstructor1 = new String("Hello, World!");
String stringByConstructor2 = new String("Hello, World!");
두 변수 stringByConstructor1, stringByConstructor2는 동일한 인자를 받지만
두 String가 참조하는 주소는 서로 다르다. 같은 값("Hello, World!")을 저장한 메모리가 두 군데라는 것이다.
따라서 stringByConstructor1 != stringByConstructor2 이다!
리터럴을 이용할 경우
이미 존재하는 값을 재사용하는 것
문자열 리터럴 값은 클래스가 메모리에 로드될 때 자동적으로 미리 생성된다!
아래의 코드에서
String stringByLiteral1 = "Hello, World!";
String stringByLiteral2 = "Hello, World!";
두 변수 stringByLiteral1, stringByLiteral2은 동일한 주소를 참조한다.
생성자로 String 변수를 생성하는 것과 달리 이 경우 메모리가 낭비되지 않으며,
stringByConstructor1 == stringByConstructor2 이다!
따라서 문자열을 비교할 때는 ==연산자를 사용하지 말고 equals()메서드를 사용하자.
== 연산자의 경우 두 값이 동일한 인스턴스인가를 비교한다. (동등성, identity)
반면 equals()는 동치성(equity)에 대한 비교를 목표하는, 모든 객체에 적용되는(Object) 메서드이다.
String은 인코딩 방식이 같으며, 문자열 내용의 값이 동일한 경우 true를 리턴하는 식으로 equals()를 오버라이드 했다.
모든 문자열 리터럴 값은 컴파일 시에 클래스 파일에 저장된다.
동일 내용의 문자열 리터럴은 한 번만 저장된다.
문자열 리터럴도 String의 인스턴스이고, 불변이기에 같은 값이면 - 하나의 인스턴스를 공유하면 되기 때문이다.
소스파일에 포함된 모든 리터럴의 목록을 담은 클래스 파일이 있다.
이 파일이 클래스 로더에 의해 메모리에 올라갈 때, 리터럴들은 JVM 내의 상수 저장소(Constant pool)에 저장된다.
자바가 String 클래스를 특수하게 관리하는 수단
String s = "";
for (int i = 0; i < 10; i++) {
s += i;
}
System.out.println("s = " + s);
위의 코드가 실행될 경우
Contstant Pool에는 "", "0", "01", "012", ...이 모두 저장된다.
따라서 String에는 += 연산을 사용하는 것이 성능상 좋지 않다.
StringBuffer를 사용하라.
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 10; i++) {
sb.append(i);
}
System.out.println("sb = " + sb);
길이가 0인 배열이 존재할 수 있듯이,
길이가 0인 char[]를 value로 가지고 있는 String이 있을 수 있다 -> 빈 문자열
String emptyString = ""은 가능하지만,
char emptyChar = ''은 불가능하다.
char 자료형 변수에는 반드시 하나의 문자를 지정해야 한다.초기화
String s = null;
char c = '\u0000';
이런 방식의 초기화도 가능하지만,
String s = "";
char c = ' ';
이런 방식의 초기화가 권장된다.
String관련 유용한 정보String[] split(String regex): 인자로 받은 regex로 구분하여 문자열을 자른다.
자바 8에서는 다음 두 기능이 추가되었다:
join()static String join(CharSequence delimiter, CharSequence... elements)
static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
split()과 반대로 구분자로 문자열을 결합한다.
StringJoinerStringJoiner() 생성 인자로 구분자를 받는다.add(String s):로 합칠 String을 받는다.2byte: 즉 16bit 문자체계다.20bit로 확장하였다: 보충 문자(supplementary characters), (JDK 1.5부터 지원)byte 크기 자료형인 char가 아니라 int로 다뤄야 하는 경우가 생겼다.getBytes(String charsetName)을 이용하여 인코딩 변환한 byte[]를 리턴받을 수 있다.Charset자료형으로도 받을 수 있다(오버라이딩).printf()와 사용법이 동일하다.
기본형 → String: valueOf()를 이용하는 방식
+ ""해주는 방식보다 성능적으로 좋다.Wrapper클래스로 값이 반환되지만, 오토박싱에 의해서 기본 자료형으로 자동 변환된다.String → 다른 자료형(기본형도 포함): toString()
toString() 메서드는 Object의 메서드, 따라서 모든 객체에 존재한다.
새 클래스를 만들 경우 적절히 오버라이드 하라.
StringBuffer와 StringBuilderString 클래스는 Constant Pool에 의해 관리되는 특이한 클래스로, 불변이기에
+연산이 메모리 낭비를 일으킬 수 있다.
→ StringBuffer를 사용하면 해결 가능
StringBufferString과 유사한 구조
char[] value에 값을 저장하는구조버퍼(buffer)
문자열을 저장하고 편집하기 위한 공간
value를 버퍼로 사용한다.
Thread-safe하다!
StringBuffer 인스턴스가 생성될 때, 인자로 버퍼의 크기를 지정 가능하다.
미지정시 16으로 초기화된다.
버퍼의 길이가 부족해질 경우 버퍼의 크기를 늘려주는 작업이 이루어진다.
배열의 복사는 메모리를 잡아먹기 때문에 적절한 양을 할당해주는 것이 필요하다.
append(): 추가 기능, 현재 주소를 반환한다.
append(StringBuilder sb)가 규정되어 있기 때문에
sb.append("a").append("b")형태의 연쇄 호출이 가능하다.`
StringBuffer vs StringBuilderStringBuffer | StringBuilder |
|---|---|
| Thread-safe(동기화) | 동기화 기능을 뺐음 |
| 성능 면에서 손해 있음 | 성능 면에서 더 나음 |
StringBuffer에서 동기화 기능만 뺀 클래스가 StringBuilderStringBuffer 쓰자.모든 객체의 최상위 객체
즉, 모든 객체에는 Object의 메서드를 호출할 수 있음
이 글에서는 간단하게 다루고 추후 이펙티브 자바 요약 정리 링크와 별도의 학습 포스트로 연결할 예정
포함해선 안 될 파일들
*.class, *.jar, build/ 단 라이브러리에 dependency 걸린 것들은 남기거나, 다운 받을 수 있게 해야gradle, gradlew , gradle.bat등 -> gradle wrapper명령어로 생성 가능로컬 환경에 의존적인 절대경로
간단하게 처리하는 방식: gitignore.io
gradle wrapper를 ingore하느냐에 대한 논쟁
포함하지 않아야 한다
포함해야 한다
참고
gradle wrapper를 포함시킨다.개인적인 결론
학습 환경에서는 gradle wrapper를 포함시키지 않는다.
운영하고자 하는 프로젝트의 경우 포함시키는 것을 우선하되,
당연히 팀 컨벤션에 따라간다.
String 부분은 남궁성, <자바의 정석>의 요약 + a임