전체 글
이진 숫자 승격 (binary numerical promotion)
정숫값으로 평균을 구하고 실수로 평균을 출력하려고 하는데 소수점자리가 나오지 않는다. 동일 형의 연산 정수를 받아서 합계를 구하면 합계는 정수, 즉 int + int + int = int. 이 상태에서 나누기를 한다면 여전히 .뒤에 소수점이 없는 double이 나오게 된다. 이진 숫자 승격 double / int 아니면 int / double하면 어떻게 될까? System.out.println(25.0 / 3) // 8.333333 System.out.println(25 / 3.0) // 8.333333 나눗셈이 이루어지기 전에 int형은 double형으로 격상된다. 이렇게 암묵적으로 이뤄지는 형 변환을 이진 숫자 승격이라고 한다. 피연산자의 자료형이 서로 다를 때 자료형이 작은(덜 구체적인) 피연산자는..
char
char 타입 작은 따옴표 사이에 하나의 문자만. 문자는 각각 유니코드 값을 갖고 있다. // 쌍따옴표의 유니코드는 u0022 char c = '\u0022'; // " 유니코드로도 char형 변수를 만들 수 있다. char ch = 65; // A ch++; // B 문자에 유니코드값이자 아스키값으로도 char타입을 선언, 정의할 수 있다. 정수처럼 연산도 가능. char ch = 65; // A ch + 5; // 70 정수를 같이 연산하면 정수로 출력된다. int는 4byte, boolean은 2byte. 정수의 크기가 더 크기 때문. char ch = 65; // A ch++; // B int b = (int) ch; // 66
boolean, XOR 연산자, &&와 &의 큰 차이점
boolean 리터럴은 false, true. 대소문자에 민감하기 때문에 소문자로 작성해야 한다. XOR 연산자 ^로 사용하는데 양쪽의 값을 비교해서 같은 값이면 false, 다른 값이면 true로 리턴한다. true ^ false = true; false ^ true = true; true ^ true = false; false ^ false = false; &&와 &의 큰 차이점 &&는 단축 회로 연산자다. int i = 10; int j = 10; j > 15 && i++ > 5; // false System.out.println(i); // 10 System.out.println(j); // 10 // 뒤의 식에는 후위 증감 연산자가 있어서 // 값을 다시 출력해보면 +1인 11이 출력되어야 하는..

부동 소수점 리터럴의 default, 부동 소수점 데이터 타입은 부정확하다?, 정확하게 BigDecimal()
부동 소수점 리터럴의 default 값은 double float 리터럴을 만들 때 값의 뒤에 부동 소수점 접미어인 F를 붙여주지 않으면 에러가 발생한다. 8byte인 double 타입을 4byte인 float 타입에 담으려고 했기 때문. float f = 12.3456; // 값을 default인 double로 인식, 에러 float f = 12.3456F; // 부동 소수점 접미어 F를 붙인 값 부동 소수점 데이터 타입은 정확하지 않다? 34.56789876 + 34.2234 의 값은 68.791229876이지만 java로 확인해보면 0.000000001이 부족한 68.79129875999999이 출력되는 것을 확인할 수 있다. 자바는 IEEE 754 부동 소수점 방식을 사용한다. 그래서 정확한 실수를..
중첩 반복문 안에서 break로 원하는 반복문 탈출하기(레이블 지정문) (+ continue)
첫번째레이블명: for () { 두번째레이블명: for () { 세번째레이블명: for () { break 첫번째레이블명; // 첫번째레이블명을 가진 반복문 종료, 탈출. } } } // break 첫번째레이블명; 사용 후 나오게 되는 위치.
8진수, 16진수, long 타입과 명시적 형변환 / 묵시적 형변환, 기본형의 확대 변환 (widening primitive conversion), 기본형의 축소 변환 (narrowing primitive conversion)
8진수 (0 ~ 7) 0으로 시작하여 숫자를 입력하면 8진수가 된다. int i = 010; // 8; 16진수 (0 ~ 9, A(10) ~ F(15)) 0x로 시작하여 숫자를 입력하면 16진수가 된다. int i = 0xF; // 15 long의 정수 접미어 모든 정수 유형의 리터럴들은 default로 int 유형을 가지기 때문에 long 리터럴을 만들 때 값의 뒤에 정수 접미어인 L을 붙여주지 않으면 에러가 발생한다. 소문자 l은 1과 혼동하기 쉽기 때문에 대문자 L을 사용하는 것이 좋다. long l = 9223372036854775807; // 값을 default인 int로 인식, 에러 발생 long l = 9223372036854775807L; // 정수 접미어 L을 붙인 값 명시적 형변환 (E..

split()의 separator가 연속될 때 생기는 공백
String a = "boo:and:foo"; String[] arr = a.split("o"); System.out.println(Arrays.toString(arr)); 이대로 실행하면 공백이 나오는 것이다. 내 예상으로 boo:and:foo는 b, :and:f라고 생각했었는데 뜬금포로 공백이 나오니 너무 궁금해서 왜 나오는지 한참 찾아봤는데 split() 메서드는 separator를 기준으로 좌우로 갈라진다. separator끼리 좌우로 갈라지면 사이에는 공백이 생기게 된다. 또 파라미터가 0인 경우에는 후행 빈 문자열은 삭제가 된다.foo는 [f, , ]의 공백들은 후행 빈 문자열로 삭제되기 때문에 결과가 이렇게 출력된다.
캡슐화
캡슐화는 한 개체를 다른 개체로부터 보호하는 것. 클래스는 특정 클래스의 데이터를 직접적으로 바꿀 수 없다. 상태 = 데이터를 바꾸고 싶다면 해당 클래스에서 수행하는 동작 = 메서드를 통해야 한다. 캡슐화의 기본 원칙 중 하나. getter와 setter를 사용하는 이유도 된다. getter와 setter를 사용하는 이유 데이터를 직접적으로 바꾸지 않고 메서드를 이용해서 변경하게 되면 말도 안되는 값을 데이터에 넣지 못하도록 논리를 정할 수 있게 되고 잘못 된 값으로 데이터가 변경되는 일을 막을 수 있다. 특정 데이터를 걸러 내주는 역할도 캡슐화의 역할 중 하나. 다양한 연산 값을 그냥 변경하는 것이 아닌 연산을 수행해서 값을 넣어야 할 때, 이런 비즈니스 로직도 클래스 안에 캡슐화 할 수 있다. 비즈니..
String과 StringBuffer / StringBuilder 차이점
String String은 StringBuffer와 StringBuilder와의 큰 차이점은 한번 값이 할당되면 그 할당된 공간의 크기가 변하지 않는 불변(immutable)의 속성을 갖고 있다. hello로 선언한 String이 hello world로 값을 변경하게 되면 기존 주소에 있던 hello는 GC에 의해 제거되고 새로운 인스턴스인 hello world 주소를 가리키게 된다. 변하지 않는 문자열을 읽어 들일 때 String을 사용하면 좋다. StringBuffer/StringBuilder의 공통점 반면 StringBuffer와 StringBuilder는 가변(mutable) 성을 가진다. 문자열 연산 등으로 기존 객체의 공간이 부족할 경우 버퍼 크기를 늘리면서 유연하게 동작한다. 클래스가 제공하..
JRE와 JDK
JRE (Java Runtime Environment) JRE = JVM + Lbraries + Other components 말 그대로 자바를 실행할 수 있는 환경. 어떤 자바 프로그램이든 기본적으로 내장되어야 하는 클래스가 있다.예를 들면 System.out.println(). S.o.p는 Libraries에 들어있다. JDK (Java Development Kit) JDK = JRE + Compilers + Debuggers JDK는 자바 프로그램을 개발하고, 컴파일하고, 실행까지 필요한 것들이 모아진 것이다. 프로그램을 실행만 하는 사용자라면 JRE가 필요하고 프로그램을 개발하는 개발자라면 JDK가 필요하다.
Java의 플랫폼 독립성
컴퓨터가 알아듣는 0과 1은 기본 명령이라고 한다. 어떤 다른 프로그램을 돌려도 결국 일어나야 할 일은 각 운영체제를 위해 기본 명령으로 바뀌게 되기 때문에 윈도우의 명령은 리눅스와 유닉스 등 다른 운영체제의 명령과 다르다. 자바가 다양한 운영체제에서 작동되는 것을 플랫폼 독립성이라고 한다. 자바는 왜 플랫폼 독립성을 갖게 되었을까? 자바는 모든 운영체제에서 사용할 수 있는 표현을 만들어 뒀는데 그것을 바이트 코드라고 한다. 바이트 코드는 운영체제 상관 없이 공통적인 포맷을 취하는데 정작 운영체제들은 기본 적인 명령을 제외한 바이트 코드를 이해하지 못한다. 이 때 JVM이 바이트 코드를 각 운영 체제의 특정한 명령으로 실행할 수 있도록 바꿔준다. 바이트 코드는 어디에서 오는 걸까? 자바 프로그램을 짜고 ..
float 타입 정의 시 값 뒤에 f를 붙이는 이유?
float f = 2.5f; 숫자 뒤에 f를 붙이는 이유는? 컴퓨터에게 float 타입이라는 것을 알리려고 붙인다. f를 붙이지 않으면 더 큰 실수타입인 double로 인식을 하게 되고 float에는 더 큰 타입의 값을 넣지 못해 에러를 띄울 수 있다.
변수를 저장하면 메모리에서는?
Memory Location Value Name 4575 30 c 4353 10 a 4564 2345 5475 20 b 3454 int a = 10를 선언하면 메모리의 어딘가에 name과 value가 저장된다. int b = 20도 마찬가지. int c = a + b를 선언하면 a + b는 30. 30이 c에 저장된다. 사실 변수를 생성, 수정하는 것은 실제로 메모리의 값이 바뀌는 것이기 때문에 이름은 특정 메모리의 위치를 저장해두는, 즉 참조하기 위해 주는 것이다.

github Binary file not shown.
java 문제를 풀고 github에 올리던 도중 이상현상이 발생했다. 1. 문제1.java를 push까지 마친 상태에서 2. 문제2.java를 commit까지 한 상태에서 3. staging area를 확인했는데 문제1.java에 수정사항이 생겼다고 4. 문제1, 문제2 둘다 commit하라는 것. 분명 문제1.java는 push 후 수정하지 않았는데 .. push를 하고 github를 확인해보면 Binary file not shown.이라는 내용으로 push가 되어있다. push는 잘돼서 문제는 없었지만 문제1.java push 완료 후 새 자바파일인 문제2.java 파일을 push할때 계속 이전 파일인 문제1.java에 수정사항이 생겼다고 같이 커밋하라고 떠서 log가 뒤죽박죽이 될까 싶어 고치기로 ..