1.1 변수(variable) 란?
하나의 값을 저장할 수 있는 메모리 공간
1.2 변수의 선언과 초기화
변수의 초기화란, 변수를 사용하기 전에 처음으로 값을 저장하는 것
- 변수를 선언하면 메모리의 빈 공간에 알맞은 크기의 저장공간이 확보된다.
- 타입이 같은 경우 여러 변수를 한 줄에 선언할 수 있다.
int a,b;
int x = 0, y = 0;
- 지역변수는 초기화가 필수지만, 클래스변수와 인스턴스 변수는 초기화를 생략할 수 있다.
두 변수의 값 교환하기
- 변수 x에 저장된 값을 변수 tmp에 저장
- 변수 y에 저장된 값을 변수 x에 저장
- 변수 tmp에 저장된 값을 변수 y에 저장
int x = 10, y = 20;
int tmp = 0;
System.out.println("x: " + x + " y: " + y);
tmp = x;
x = y;
y = tmp;
System.out.println("x: " + x + " y: " + y);
1.3 변수의 명명규칙
- 대소문자가 구분되며 길이에 제한이 없다.
- 예약어를 사용해서는 안 된다.
- 숫자로 시작해서는 안 된다.
- 특수문자는 '_'와 '$'만을 허용한다.
또한, 필수적인 것은 아니지만 권장 규칙은 다음과 같다.
- 클래스 이름의 첫 글자는 항상 대문자로 한다.
- 여러 단어로 이루어진 이름은 단어의 첫 글자를 대문자로 한다.
- 상수의 이름은 모두 대문자고 한다. 여러 단어로 이루어진 경우 '_' 로 구분한다.
1.3 변수의 타입
기본형과 참조형
- 기본형 변수는 실제 값(data)을 저장하는 반면, 참조형 변수는 어떤 값이 저장되어 있는 주소(memory address)를 값으로 갖는다.
- 자바는 참조형 변수 간 연산을 할 수 없으므로 실제 연산에 사용되는 것은 모두 기본형 변수이다.
기본형(primitive type)
- 논리형(boolean), 문자형(char), 정수형(byte,short,int,long), 실수형(float,double)
계산을 위한 실제 값을 저장한다. (8개)
참조형(reference type)
- 객체의 주소를 저장한다. 8개의 기본형 제외 나머지 타
- 객체를 생성하는 연산자 new의 결과는 생성된 객체의 주소이다.
2.1 기본형
- 정수형의 경우, 가질 수 있는 값의 범위는 -2^(n-1)~2^(n-1)-1(n은 bit 수)이다.
- 예를 들어 int형의 경우 32 bit이므로 -2^31~2^31-1의 범위를 갖는다.
- int 타입 변수는 대략 10자리 수의 값을 저장할 수 있다.
2.2 상수와 리터럴 (constant & literal)
상수
- 상수는 변수와 달리 한번 값을 저장하면 다른 값으로 변경할 수 없다.
- 상수는 반드시 선언과 동시에 초기화해야 한다. (cf _ JDK1.6부터 사용하기 전에만 초기화하면 되도록 바뀜)
- 상수의 이름은 모두 대문자가 관례이다.
final int MAX_SPEED = 10;
리터럴(literal)
변수(variable): 하나의 값을 저장하기 위한 공간
상수(constant): 값을 한번만 저장할 수 있는 공간
리터럴(literal): 그 자체로 값을 의미하는 것
- 상수는 리터럴에 '의미있는 이름'을 붙여서 코드의 이해와 수정을 쉽게 만든다.
리터럴의 타입과 접미사
- 정수형의 경우, long 타입의 리터럴에 접미사 'l' 또는 'L'을 붙인다.
- 접미사가 없으면 int타입의 리터럴이다.
- 16진수는 '0x' 또는 '0X'를, 8진수의 경우에는 '0'을 붙인다.
int octNum = 010; // 8진수 10, 10진수로 8
int hexNum = 0x10; // 16진수 10, 10진수로 16
int binNum = 0b10; // 2진수 10, 10진수로 2
- 실수형에서는 float타입의 리터럴에 접미사 'f'또는 'F'를 붙인다.
- double타입의 리터럴에 접미사 'd' 또는 'D'를 붙인다.
- 실수형 리터럴에서는 double이 기본 자료형이다.
- 아래는 double 타입 리터럴로 간주되어, 컴파일 시 에러가 발생한다.
float pi = 3.14; // error! float 타입 변수에 double 타입 리터럴 저장 불가
double rate = 1.618; // OK. 접미사 d는 생략 가능
타입의 불일치
- 저장 범위가 넓은 타입에 좁은 타입의 값을 저장하는 것은 허용된다. (반대의 경우 컴파일 에러 발생)
- 값의 크기에 상관없이 double타입의 리터럴을 float타입의 변수에 저장할 수 없다.
문자 리터럴과 문자열 리터럴
- char타입의 변수는 단 하나의 문자만 저장 가능하다. 여러 문자를 저장하기 위해서는 String타입을 사용해야 한다.
- 문자열 리터럴은 "" 안에 아무런 문자도 넣지 않는 것을 허용하며,이를 빈 문자열이라고 한다. 그러나 문자 리터럴은 반드시 ''안에 하나의 문자가 있어야한다.
String str = ""; // OK. 내용 없는 빈 문자열
char ch = ''; // 에러. ''안에 반드시 하나의 문자가 필요
char ch = ' '; // OK, 공백문자(blank)로 변수 ch를 초기화
- 기본형과 참조형의 구별 없이 어떤 타입의 변수도 문자열과 덧셈연산을 수행하면 그 결과가 문자열이 된다.
- 기본형 타입의 값을 문자열로 변환할 때는 아무런 내용도 없는 빈 문자열("")을 더해주면 된다.
2.3 형식화된 출력 - printf()
- println()은 변수의 값을 그대로 출력하므로, 다른 형식으로 출력할 수 없다.
- printf()는 같은 값이라도 다른 형식으로 출력할 수 있다.
- printf()는 줄바꿈을 하지 않는다.따라서 줄바꿈을 하려면 지시자 '%n'을 따로 넣어줘야 한다.
- 출력될 값이 차지할 공간을 아래와 같이 숫자로 지정할 수 있다.
int finger = 10;
System.out.printf("[%5d]\n", finger); // [ 10]
System.out.printf("[%-5d]\n", finger); // [10 ]
System.out.printf("[%05d]\n", finger); // [00010]
- 10진수를 2진수로 출력하는 지시자는 없기 때문에 정수를 2진 문자열로 변환해주는 함수를 사용해야한다.
- Integer.toBinaryString(int i) 메서드는 정수를 2진수로 변환해서 문자열로 반환한다.
int binNum = 0b10; // 2진수 10, 10진수로는 2
System.out.printf("binNum = %s\n", Integer.toBinaryString(binNum));
- .을 붙이면 문자열의 일부만 출력할 수 있다.
String s = "안녕하세요 자바 공부중이에요";
System.out.printf("[%.8s]\n",s); // 왼쪽에서 8글자만 출력.결과: [안녕하세요 자바]
화면에서 입력받기 - Scanner
Scanner 클래스를 사용하기 위해 아래 문장을 추가한다.
import java.util.*;
그 다음, Scanner 클래스의 객체를 생성한다.
Scanner scanner = new Scanner(System.in); // Scanner 클래스 객체 생성
그 다음 nextLine() 메서드를 호출하면 엔터키를 누를때 입력한 내용이 문자열이 반환된다.
String input = scanner.nextLine(); // 입력받은 내용을 input에 저장
int num = Integer.parseInt(input); // 입력받은 내용을 int 타입의 값으로 변환
nextInt()나 nextFloat()와 같은 메서드들을 사용하면 변환하는 수고는 하지 않아도 된다.
int num = scanner.nextInt(); // 정수를 입력받아서 변수 num에 저장
예제 2.6
import java.util.*;
Scanner scanner = new Scanner(System.in);
System.out.print("두자리 정수를 하나 입력해주세요.>");
String input = scanner.nextLine();
int num = Integer.parseInt(input); // 입력받은 문자열을 숫자로 변환
System.out.println("입력내용 : "+input);
System.out.printf("num=%d\n", num);
// output:
//두자리 정수를 하나 입력해주세요.>입력내용 : 33
//num=33
4.1 논리형 - boolean
true와 false 중 하나를 정할 수 있으며 기본값(default)은 false 이다.
boolean power = true;
4.2 문자형 - char
단 하나의 문자를 저장한다. 변수에 '문자'가 저장되는 것 같지만, 사실은 문자가 아닌 '문자의 유니코드(정수)'가 저장된다.
ex) 문자 'A'의 유니코드는 65이므로 'A' 저장시 65가 저장된다.
4.2 문자형 - char
단 하나의 문자를 저장한다. 변수에 '문자'가 저장되는 것 같지만, 사실은 문자가 아닌 '문자의 유니코드(정수)'가 저장된다.
ex) 문자 'A'의 유니코드는 65이므로 'A' 저장시 65가 저장된다.
// 아래 두 결과는 동일
char ch = 'A';
char ch = 65;
문자의 유니 코드를 알고 싶으면 char형 변수에 저장된 값을 정수형으로 변환하면 된다.
int code = (int) ch; //ch에 저장된 값을 int타입으로 변환하여 저장
특수 문자 다루기
public class SpecialCharEx {
public static void main(String[] args) {
System.out.println('\''); // '''처럼 할 수 없다.
System.out.println("abc\t123\b456"); // \b에 의해 3이 지워진다
System.out.println('\n'); // 개행(new line) 문자를 출력하고 개행
System.out.println("\"Hello\""); // 큰따옴표를 출력하려면 이렇게 한다
System.out.println("c:\\");
}
}
실행결과
'
abc 12456
"Hello"
c:\
char타입은 정수형과 달리 음수를 나타낼 필요가 없으므로 표현할 수 있는 값의 범위가 다르다.
16비트로 표현할 수 있는 정수의 개수 : 2^16개 (65536개)
short 타입의 표현범위 : -2^15 ~ 2^15-1 (~32768~32767)
char 타입의 표현범위 : 0 ~ 2^16-1 (0~65535)
다음과 같이 변수 ch와 s에 각각 'A'와 65를 저장하면 둘 다 2진수로 같은 값이 저장된다.
char ch = 'A'; // char ch = 65;
short s = 65;
하지만 두 변수를 출력해보면 아래와 같이 다른 값이 출력된다. println()은 변수의 타입에 따라 저장된 값을 해석하여 출력하므로 정수형 변수는 숫자를, 문자형 변수는 문자를 출력하기 때문이다. (이는 '1231'이 생일로 해석할지,시간으로해석할지,날짜로 해석할지를 알 수 없는 것과 같음)
System.out.println(ch); // A가 출력됨
System.out.println(s); // 65가 출력됨
인코딩과 디코딩
문자 인코딩(encoding) : 문자를 코드로 변환하는 것 'A'->65
문자 디코딩(decoding) : 코드를 문자로 변환하는 것 65->'A'
웹서핑을 하다가 페이지 전체가 알 수 없는 이상한 글자들로 가득찬 경험이 있을텐데, 그 이유는 해당 html문서의 인코딩에 사용된 코드표와 웹브라우저의 설정이 맞지 않아서이다.
◼ 유니코드 : 전 세계의 문자를 하나의 통일된 문자집합으로 표현
- UTF-8 : 하나의 문자를 1~4byte의 가변크기로 표현
- UTF-16 : 모든 문자를 2byte의 고정크기로 표현
4.3 정수형 - byte, short, int, long
- 정수형 변수를 선언할 때는 int타입으로 하고, int의범위(+-20억)를 넘어서는 수를 다뤄야할 때는 long을 사용한다.
- 오버플로우(overflow) : 해당 타입이 표현할 수 있는 값의 범위를 넘어서는 것.
- 부호없는 정수는 2진수로 0000이 될 때, 부호있는 정수는 부호비트가 0에서 1이 될때 오버플로우가 발생한다.
4.4 실수형 - float, double
연산속도의 향상이나 메모리를 절약하려면 float를 선택하고, 더 큰 값의 범위나 더 높은 정밀도를 필요로 한다면 double을 선택한다.
5.1 형변환 이란?
형변환이란, 변수 또는 상수의 타입을 다른 타입으로 변환하는 것
5.2 형변환 방법
(타입) 피연산자 : 형변환 방법은 형 변환하고자 하는 변수나 리터럴의 앞에 변환하고자 하는 타입을 괄호와 함께 붙여주기만 하면 된다.
double d = 85.4;
int score = (int) d; // double타입의 변수 d를 int타입으로 형 변환
- 형변환 연사자는 피연산자의 값을 읽어서 지정된 타입으로 형변환 후 결과 반환한다. 위에서 피연사자인 변수 d의 값은 형변환 후에도 아무런 변화가 없다.
- 기본형에서 boolean을 제외한 나머지 타입들은 서로 형변환이 가능하다.
- 기본형과 참조형간의 형변환은 불가능하다.
5.5 정수형과 실수형 간의 형변환
10진수로 8자리 이상의 값을 실수형으로 변환할때는 float이 아닌 double로 형변환해야 오차가 발생하지 않는다.
(float는 정밀도가 약 7자리이므로 8자리 정수를 저장할 때 오차가 발생한다.)
5.6 자동 형변환
컴파일러가 생략된 형변환을 자동적으로 추가한다. 그러나 더 큰 값을 저장하려는 경우에 형변환을 생략하면 에러가 발생한다. 이는 값 손실이 발생할 수 있기때문이다.
byte b = 1000; // 에러.byte범위(-128~127)를 넘는 값을 저장
하지만 다음과 같이 명시적으로 형변환 해줬을 경우, 컴파일러는 형변환이 의도적인 것으로 간주하고 에러를 발생시키지 않는다.
char ch = (char) 1000; // 명시적 형변환.에러가 발생하지않는다.
💡 자동 형변환 규칙
기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환한다.
형변환 정리
- boolean을 제외한 나머지 7개의 기본형은 서로 형변환이 가능하다.
- 기본형과 참조형은 서로 형변환할 수 없다.
- 서로 다른 타입의 변수간의 연산은 형변환을 하는 것이 원칙이지만, 값의 범위가 작은 타입에서 큰 타입으로의 형변환은 생략할 수 있다.
👀 추가 보충 내용
Scanner클래스 next(), nextLine() 차이
next()
- 공백을 기준으로 한 단어 또는 한문자씩 입력받는다.
- 공백 전까지의 단어를 읽는다.
- 개행문자를 가져오지 않는다.
nextLine()
- 문자 또는 엔터를 치기 전까지의 문장 전체를 입력받는다.
- 버퍼에 입력된 문자열을 개행문자까지 다 가져온다.
'Java' 카테고리의 다른 글
[Java의 정석] chapter05 배열 array - 요약정리 (0) | 2024.04.08 |
---|---|
[Java] 김영한의 실전 자바 - 기본편 섹션1~2 클래스와 데이터, 기본형과 참조형 (0) | 2024.04.08 |
[Java] 김영한의 자바 입문 - 섹션2~3 변수, 연산자 (0) | 2024.03.31 |
[Java] 김영한의 자바 입문 - 섹션1 Hello World 자바란? (0) | 2024.03.30 |
[Java의 정석] chapter01 자바를 시작하기 전에 - 요약정리 (0) | 2023.09.12 |