// 2번
public class Question {
public static void main(String args[]) {
// 다음 문장들의 출력 결과를 확인해보세요.
System.out.println("10" + "04");
// 숫자로 합쳐지는 것이 아닌 문자열로 합쳐져 1004
System.out.println("" + false);
// 문자열 + 논리형타입 = 문자열로 치환 -> false
System.out.println('a' + 100);
// char타입 + 정수형타입 = 10진수로 변환된 char타입으로 계산 -> 197
}
}
// 3번
public class Question {
public static void main(String args[]) {
// 에러가 발생하는 부분을 고쳐보세요. 값을 수정하던지 타입을 변경하던지
byte a = 999;
// int a = 999; / byte a = 127;
char b = 'abc';
// String b = "abc"; 문자열 타입은 기본 타입이 아니라 참조형 타입, 문자열 타입엔 무조건 쌍 따옴표 사용 / char b = 'a';
float c = 1.23d;
// double c = 1.23; / float c = 1.23F;
}
}
// 5번
2byte , 0~65535 , 16bit , 2의 16승
// 6번
2. char b = ' ';
3. String c = "Hello"; / char c = 'H';
4. int d = 12345; / (byte -128 ~ 127)
// 9번
// 하나의 변수를 만들어서 값을 넣어두고 나머지 값들을 할당해준다음 마지막 값에 변수값을 넣어준다.
// 변수를 만들지 않고 값을 넣어주면 값 하나가 사라진다.
데이터 타입을 다른 데이터 타입으로 변환하는 것을 말함.
두 가지 종류가 있는데 자동 변환 타입(묵시적 타입 변환), 강제 타입 변환(명시적 타입 변환)이 있다.
이때 강제 타입 변환에선 데이터 손실이 있을 수 있다.
작은 크기의 타입을 큰 크기의 타입으로 자동 타입 변환 하는 것
public static void main(String[] args) {
byte byteValue = 10;
int intValue = byteValue; // 타입 변환 (byte -> int)
System.out.println(intValue);
char charValue = '가';
intValue = charValue;
System.out.println("'가'의 유니코드= " + intValue);
intValue = 500;
long longValue = intValue; // 타입 변환 (int -> long)
System.out.println(longValue);
intValue = 200;
double doubleValue = intValue; // 타입 변환 (int -> double)
System.out.println(doubleValue);
}
전세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 표준
인코딩 포맷 - utf-8(한글까지 지원해서 사용), ISO 등등
큰 크기의 타입을 작은 크기의 타입으로 강제적으로 변환.
큰 그릇을 쪼개어 작은 그릇에 넣는다 > 캐스팅 해준다
long longValue = 300;
int intValue = (int) longValue; // intValue는 300이 그대로 저장
표현식이 다른 두 가지 타입을 연산할 때 범위가 더 큰 값을 따라서 연산해줌.
int intValue = 10;
double doubleValue = 5.5;
double result = intValue + doubleValue; // result에 15.5가 저장
//이때 소숫점 없이 버림으로 저장하고 싶다면 캐스팅 해주면 됨.
int result = intValue + (int)doubleValue; // result에 15가 저장
byte byteValue = 10;
char charValue = 'A';
(1) int intValue = byteValue;
(2) int intValue = charValue; // charValue가 유니코드로 변환됨.
(3) short shortValue = charValue; // short - 2byte, 표현되는 크기는 같지만 변환은 불가능함
(4) double doubleValue = byteValue;
int intValue = 10;
char charValue = 'A';
double doubleValue = 5.7;
String stringValue = "A";
(1) double var = (double) intValue; // 묵시적으로도 가능, 자동 타입 변환 가능하지만 명시적으로 넣어줘도 되긴 함.
(2) byte var = (byte) intValue;
(3) int var = (int) doubleValue;
(4) char var = (char) stringValue; // 문자열 값은 char 값으로 변환을 할 수가 없다. String에서 제공해주는 메서드를 이용하면 가능하지만 아니면 할 수 없다. → charAt(index) 라는 메서드를 사용해야 함.
컴파일 오류가 나면 코드를 수정 해줘야 한다.
프로그램이 실행될 수 없는 상태 → 클래스 파일이 생성되지도 않은 상태.
저장 영역 : stack
기본 타입 변수
- 리터럴 값을 실제로 저장. stack에 직접 저장
참조 변수
- 직접 저장되지 않고 객체에서 참조하여 사용. 실제값을 가지고 있지 않고 주소값을 가지고 있는데 해당 주소값이 heap영역을 가르키고 있어서 그 값을 찾아서 값을 가져오는 것.
참조 변수의 객체 메모리 영역 : heap
참조 변수의 메모리 공간 차지가 더 크다.
// 기본 타입 변수의 초기화 예시
int age = 10;
// 참조 변수의 초기화 예시
Calculator calculator = new Calculator();
문자열을 다루는 String
알아두기 : 초기화 해줄 때 null값은 넣지 말고 ""을 넣되 실제 값을 넣어 주는 걸 더 권장.
// String , 참조 자료형 : new 예약어를 사용해서 변수를 초기화.
// 실제값(리터럴값)을 그대로 선언해서 사용할 수 있음. 예외!
// String str = "" // 초기화
String str = "실제값";
String str2 = new String("실제값");
// String str = null; // null을 선언할 수 있지만 잘 하지않음. 주소값이 없는 상태를 뜻함
// str.length(); // NullpointerException. 해당 오류는 run을 돌려야 확인할 수 있어서 치명적일 수 있다.
// String , 참조 자료형 : new 예약어를 사용해서 변수를 초기화.
// 실제값(리터럴값)을 그대로 선언해서 사용할 수 있음. 예외!
// String str = "" // 초기화
String str = "실제값";
String str2 = new String("실제값");
String str3 = new String("실제값");
String str4 = new String("실제값");
String str5 = "실제값";
// false
System.out.println(str == str2);
System.out.println("str2 == str3 결과 : " + (str2 == str3));
System.out.println("str2 == str4 결과 : " + (str2 == str4));
System.out.println("str3 == str4 결과 : " + (str3 == str4));
System.out.println("str == str5 결과 : " + str == str5); //"str == str5 결과 : " + str 와 str5가 비교가 되서 false가 나옴. 연산자 우선순위..!
//true
System.out.println("str == str5 결과 : " + (str == str5));
System.out.println(str.equals(str2));
// String str = null; // null을 선언할 수 있지만 잘 하지않음. 주소값이 없는 상태를 뜻함
// str.length(); // NullpointerException. 해당 오류는 run을 돌려야 확인할 수 있어서 치명적일 수 있다.
값은 똑같은데 결과는 false
== 은 주소값 비교. 리터럴 값과 참조 주소값이 달라서 false가 나옴. String한정!
int a = 10;
int b = 10;
System.out.println(a == b); // tryue
기본형 타입을 특정 래퍼 클래스 타입으로 변환.
이때 래퍼 클래스는 참조형 타입이다.
해당 박싱을 하는 이유는 래퍼 클래스에서 사용할 수 있는 메서드가 많아서이다.
참고 ) 해당 체크 박스 클릭 안하고 검색하면 내가 만든 파일에서 검색, 체크 하고 검색하면 전체 파일 검색
오토 박싱이 되는 경우도 있고 개발자가 메서드를 줘서 박싱이 되는 경우가 있다.
//박싱 (int -> Integer)
int a = 10;
Integer a2 = Integer.valueOf(a); // 대부분의 클래스에 valueOf() 메서드가 있음
//오토 박싱 (int -> Integer)
Integer a3 = a;
// 둘다 값은 같음
오토 박싱은 제네릭 컬렉션에 값을 추가하는 경우 유용
제내릭은 <> 안에 넣어주는데 기본 타입은 들어갈 수 없음.
public class AutoBoxingExample {
public static void main(String args[]) {
ArrayList<Integer> arrayList = new ArrayList<>();
/* 오토 박싱 */
arrayList.add(10); // 여기서 만약에 int값이 아닌 다른 값이 들어가면 컴파일로 오류를 내줌
// arrayList.add(10); // int -> Integer, 만약 오토 박싱이 안된다면 해당
arrayList.add(20);
arrayList.add(30);
System.out.println("ArrayList: " + arrayList);
}
}
// 결과
ArrayList: [10, 20, 30]
래퍼 클래스를 기본형 타입으로 변환되는 것
int index = 20;
Integer intObject = index; // 오토박싱
int index = intObject; // 언박싱 Integer -> int
편의성을 위해 오토박싱과 언박싱이 제공되지만, 내부적으로 추가 연산 작업을 거치게 됨.
그렇기 때문에, 오토박싱과 언박싱이 일어나지 않도록 동일한 타입 연산이 이루어지도록 구현함.
// 오토박싱 연산
public class AutoBoxingPerformanceExample {
public static void main(String[] args) {
long startTimeMs = System.currentTimeMillis(); // 시간 체크용 메서드
Integer sum = 0;
for (int i = 0; i < 1000000; i++) {
// 반복문이 실행될때마다 박싱이 실행됨, int -> Integer
sum = sum + 1;
}
System.out.println("실행 시간: " + (System.currentTimeMillis() - startTimeMs) + "ms");
}
}
// 실행 시간: 37ms
//primitive 연산
public static void main(String[] args) {
long startTimeMs = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < 1000000; i++) {
// 반복문이 실행되더라도 박싱 x
sum = sum + 1;
}
System.out.println("실행 시간: " + (System.currentTimeMillis() - startTimeMs) + "ms");
}
// 실행 시간: 5ms (1s(초)는 1000ms)
// 실 테스트 코드
package chap02;
public class PrimitiveTypePerformanceExample {
public static void main(String[] args) {
// 성능 측정 (오토 박싱 vs 오토 박싱 x)
// 실행 시점 시간
long currentTimeMillis = System.currentTimeMillis();
Integer sum = 0; // 오토 박싱
for (int i = 0; i < 2000000; i++) {
sum = sum + i;
}
long term = System.currentTimeMillis() - currentTimeMillis; // 현재 시간 - 실행 시점 시간
System.out.println("오토박싱 소요시간: " + term);
long currentTimeMillis2 = System.currentTimeMillis();
int sum2 = 0; // 기본 타입, 즉 오토 박싱 x
for (int i = 0; i < 2000000; i++) {
sum2 = sum2 + i;
}
long term2 = System.currentTimeMillis() - currentTimeMillis2;
System.out.println("primitive type 연산 소요시간:" + term2);
}
}
둘 다 ms로 상당히 빠른 속도로 계산 되지만 해당 계산이 쌓이면 쌓일수록 큰 차이가 나 성능 차이가 커질 수 있음. 따라서 기본 타입 연산이 이루어지도록 구현 해야함
문자열에서 숫자 primitive type으로의 변환은 Xxx.parseXxx(문자열) 메소드를 사용하여 변환하고,
문자열에서 숫자 Wrapper class로의 변환은 valueOf() 메소드를 사용하여 변환
public class StringConverter {
public static void main(String[] args) {
// String -> 숫자 변환 , 이때 변환을 시키려면 정확하게 숫자만 있어야함. 그렇지 않으면 에러가남.
String str = "12345"; // int/Integer
int primitiveStr = Integer.parseInt(str);
// int sum = primitiveStr + 1; // 이때 변환을 하지 않고 연산을 한다면 "123451"
Integer wrapperStr = Integer.valueOf(str);
// String -> Long/long
long primitiveLong = Long.parseLong(str);
Long wrapperLong = Long.valueOf(str);
String value = "10000.345";
// String -> float/Float
// float primitiveFloat = Float.parseFloat(str);
// Float wrapperFloat = Float.valueOf(str);
float primitiveFloat = Float.parseFloat(value);
Float wrapperFloat = Float.valueOf(value);
System.out.println("primitiveFloat: " + primitiveFloat);
System.out.println("wrapperFloat: " + wrapperFloat);
// String -> double/Double
double primitiveDouble = Double.parseDouble(value);
Double wrapperDouble = Double.valueOf(value);
System.out.println("primitiveDouble: " + primitiveDouble);
System.out.println("wrapperDouble: " + wrapperDouble);
// String str = "12345L" 이런 거는 변환이 안 되고 "12345.5F" 같은 경우는 되던데
// 검색해봤는데 잘 이해가 안 되서 그냥 자바에서는 그렇게 처리한다고 알고 있으면 될까요?? 그렇다.
// 오류 남
// String str5 = "454875839545436L";
// long primitveLong2 = Long.parseLong(str5);
String str6 = "12345.5F";
float floatString = Float.parseFloat(str6);
}
}
int intValue = 10;
String StrValue;
StrValue = String.valueOf(intValue);
StrValue = Integer.toString(intValue);
StrValue = "" + intValue; // 정수값에 빈 문자열을 더해 문자열 합치기 연산으로 작동되게 한다
//실습
int intValue = 10;
String s1 = intValue + "";
String s2 = Integer.toString(intValue);
String s3 = String.valueOf(intValue);
System.out.println(intValue + 10);
System.out.println("s1: " + s1);
System.out.println("s2: " + s2);
System.out.println("s3: " + s3);
// 결과값
20
10 // 만약 해당 괄호 안에 + 10을 넣어서 확인하면 1010. 즉 문자열로 잘 변환 되었음.
10
10
퀴즈
타입에 들어갈 단어는~? double
타입에 들어갈 단어는 ~? float
wrapper타입 변수로 받으려면 어떤 메소드를 사용하면 될까~? valueOf(문자열)
타입에 들어갈 단어는 ~? String, String
int인 a2에 double 타입을 초기화할 수 없기 때문에 강제 형 변환을 통해 int타입으로 바꾸어야 합니다.
int a2 = d; → int a2 = (int) d
int-> double 자동형변환
30
3
Hello world
데일리 퀴즈
100 + 10.5
100 / 5
10.0 / 5
int example7Value1 = 100;
float example7Value2 = 10.5F;
float example7Value3 = 10.0F;
int example7Value4 = 5;
System.out.println(example7Value1 + example7Value2)
System.out.println(example7Value1 / example7Value4)
System.out.println(example7Value3 / example7Value4)
// 결과값
110.5
20
2.0
char charValue = '가';
intValue = charValue;
System.out.println("'가'의 유니코드= " + intValue);
public class Question {
public static void main(String args[]) {
int number1 = 10;
double number2 = 2.0;
// 사칙연산 코드 추가
System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
System.out.println(result4);
}
}
// 정답!
double result1 = number1 + number2; // 덧셈
double result2 = number1 - number2; // 뺄셈
double result3 = number1 * number2; // 곱셈
double result4 = number1 / number2; // 나눗셈
public class Question {
public static void main(String args[]) {
// 아래 코드의 출력값은 무엇일까요?
System.out.println(10 / 2 + 3 * 4);
}
}
// 17
public class Question {
public static void main(String args[]) {
// 아래 코드의 실행 결과가 true가 되도록 수정해보세요.
String str1 = new String("Hello world!");
String str2 = new String("Hello world!");
System.out.println(str1 == str2);
}
}
// 정답!
System.out.println(str1.equals(str2));