1) 변수와 타입
1.1 변수란?
- 하나의 값을 저장 할 수 있는 메모리 공간
- 변수의 선언 : 타입 변수이름, int age; double value;
- 변수 이름 명명 규칙 : 첫 글자는 문자, 소문자여야한다! 다른 단어를 이어붙여쓸 경우 첫자를 대문자로 한다.
1.2 데이터 타입
- 기본 타입(자료형) : 정수형, 실수형, 논리형으로 3종류의 8가지 타입이 있으며 값이 저장된다.
- 참조 타입(자료형) : 배열, 열거, 클래스, 인터페이스, 참조 자료형은 주소 값을 가진다.
1.3 타입 변환
- 데이터의 자료형을 다른 자료형으로 변환하는 행위
- 변환 종류 : 묵시적(Promotion), 명시적(Casting) - Casting 시에는 데이터 오버플로우를 주의해야한다.
- 데이터 연산 시에 타입이 다를 경우 피연산자중 큰 타입으로 자동변환하여 연산된다.
└ int + double > int형이 double형으로 변환되어 연산한다.
└ int형으로 연산을 원할 경우 double형을 int형으로 Casting 해줘야 한다.
1.4 참조 자료형 instance
- 참조 자료형 변수를 비교 연산자(==, !=)로 비교 할 경우 주소 값을 비교한다.
- 묵시적 객체 생성시 대입하는 상수 값이 같으면 같은 주소를 가진다.
- String 클래스는 불변적 특징으로 인해 String 클래스에 문자열을 이어붙일 경우 힙 영역에
└ 잉여 객체가 생성되며 가비지 컬렉터가 이를 자주 소거하게 하여 자원을 낭비하게 된다.
- 주의해야 할 사항 > 안드로이드, 미들웨어 환경에서는 메모리 효율이 매우 중요하다!
1.5 JVM이 사용하는 메모리 영역
- 메모리 영역 : 메소드 영역(클래스, 바이트코드 등), 힙 영역(객체, 배열 등), JVM스택(지역변수, 지역메서드)
- 위 내용은 매우 간략히 간소화 시킨 내용이며 좀 더 깊은 내용은 이후에 다루게 된다.
1.6 import
- 외부에 있는 패키지 및 클래스를 불러오는 명령어
- Scanner : 인풋 스트림을 통해 문자 데이터를 전달받는다.
- System.in : 키보드 장치로부터 입력받는다.
소스 코드
package ex1;
public class Ex1_Demotion {
public static void main(String[] args) {
byte num1 = 10;
byte num2 = 20;
byte num3 = (byte) (num1 + num2);
System.out.println(num3);
System.out.println("------------------------------------");
// 연습) short sh1, sh2에 값을 각각 100, 200을 대입
// short sh3에 sh1 + sh2 연산값을 저장한 후 출력 해봅시다
short sh1 = 100;
short sh2 = 200;
short sh3 = (short) (sh1+sh2);
int sh = sh1 + sh2;
System.out.println(sh1 + " + " + sh2 + " = " + sh3);
System.out.println("------------------------------------");
// -------------------------------***
char ch1 = 'A'; // A는 유니코드로 65
System.out.println("ch1 : " + ch1);
short ch2 = 1;
System.out.println("정수형과 연산 : " + (ch1 + ch2));
// int형으로 승격
char ch3 = (char) (ch1 + ch2); // 연산시에는 캐스팅을 통해 디모션해준다.
// char형은 문자로 변환한다.
System.out.println(ch3); // 66은 유니코드로 B이므로,
// -------------------------------***
char ch4 ='가';
System.out.println(ch4);
char ch5 = 44032; // 10진수로 표기한 유니코드 '가'
System.out.println(ch5);
char ch_def = '\u0000'; // 초기화
System.out.println("char의 초기값 : " + ch_def);
char ch6 = '\uac00'; // 16진수로 표기한 유니코드 '가'
System.out.println(ch6);
// 유니코드 문자열을 한 문자씩 char에 저장해서 출력할때도 사용 가능
}
}
package ex1;
public class Ex1_Variable1 {
public static void main(String[] args) {
// pojo 타입에서 다른 외부 프레임워크에서
// 현재의 변수 Val을 인식 못하는 경우가 발생한다.
// 변수는 반드시 소문자로 작성해야 한다.
int Val = 10;
System.out.println("Val : " + Val);
// 변수 이름의 권장 사례 (pdf 2장 참고)
int ifCase = 0;
}
}
package ex1;
public class Ex1_VariableDataType {
// Alt + shift + f : 자동 정렬 코드
public static void main(String[] args) {
int a = 3; // 선언과 초기값을 대입
int b; // 선언
b = 3; // 대입
// + 연산자 : 덧셈, 문자열 연결 연산자.
System.out.println("a의 값 :" + a);
System.out.println("b의 값 :" + b);
// PDF 2장 2절 데이터 타입 참조해서 설명
// 4바이트 이하의 자료형은 저장할 수 있으나 JVM의 연산시
// int형이 되기 때문에 잘 사용하지 않음
byte d = 100;
short c = 50;
System.out.println("d의 값 :" + d);
System.out.println("c의 값 :" + c);
// 리터러 상수값 : \n (개행)
System.out.println(
"변수 a의 값 :" + a + "\n"
+ "변수 b의 값 :" + b + "\n"
+ "변수 c의 값 :" + c + "\n"
+ "변수 d의 값 :" + d);
// 시스템의 현재 시간을 밀리세컨드 => 1/1000 출력
System.out.println(System.currentTimeMillis());
// long형 8byte -> int 4byte
// int형의 자료형의 범위를 넘어서는 값이라면
// 오버플로우가 발생해서 정확한 값이 나오지 않는다.
// 큰 자료형의 데이터를 작은 자료형으로 바꿀때 사용 - 캐스팅, 디모션
// long형 데이터를 반환해주는 currentTimeMillis()에 (int)를 캐스팅하여
// 데이터가 오버플로우 되어 데이터 손실이 발생합니다.
// 그리고 나서 long형 time2에 대입해주며 프로모션이 작용하지만
// 이미 데이터는 손실이 발생하여 int형이 담을수 있는 값만 대입되게 됩니다.
long times2 = (int) System.currentTimeMillis();
System.out.println("long형 time2에 int형으로 캐스팅한 값을 대입할 경우 : " + times2);
// 자료형 변환 예제
// currentTimeMillis() 함수는 long형 데이터를 반환하므로
// int형 times 변수에 대입해줄때 (int)를 통해 캐스팅(디모션) 해준다.
int times = (int) System.currentTimeMillis();
System.out.println("int형 time 변수의 값 : " + times);
// long형 time1 변수는 캐스팅 없이 바로 대입이 가능하다. (같은 데이터 자료형)
long times1 = System.currentTimeMillis();
System.out.println("long형 time1 변수의 값 : " + times1);
// long 자료형 변수 e에 접미사 L을 붙이지 않을 경우 컴파일 오류 발생.
long e = 1000000000000000000L; // L, l 리터럴 접미사
// 오류 발생의 이유는 상수의 경우 접미사가 없을 경우
// 기본적인 자료형이 int로 정의 되는데 e = 1000000000000000000; 코드는
// int형이 담을 수 있는 데이터를 초과하여 오버플로우가 발생하기 때문.
System.out.println("변수 e의 값은 : " + e);
// 상수 => 프로그램 영역안에서 한번 선언 후 유지하기 위해 사용.
// [final] [자료형 [변수] = 값;
// local 영역에 선언한 상수, 대문자료 표기하는 것이 원칙이나
// 인터페이스 등에서는 변수와 같은 소문자로 표기 할 수 있다.
final int SIZE;
SIZE = 5;
System.out.println("상수값 : " + SIZE);
//SIZE = 15; (불가능)
//**************************************************************
float g = 3.14f; // double -> 3.14이고 -> F,f의 리터럴 접미사 필요
double h = 3.14; // double, 3.14d도 가능, d,D 리터럴 접미사
boolean i = true;
// 자바에서는 한 문자를 유니코드로 인식(2byte)
char j = 'A'; // 문자는 ' '를 사용한다. " "는 참조자료형이다.
int k = (int) 100L; // 디모션, 캐스팅(강제적) (큰 => 작은)
long l = k; // 프로모션(묵시적) (작은 => 큰)
System.out.println("float : " + g + "\ndouble : " + h
+ "\nboolean : " + i + "\nchar : " + j + "\nint : " + k
+ "\nlong : " + l);
}
}
package ex1;
public class Ex3_ReferenceDataType {
// 1) jvm -> main 메서드가 호출
public static void main(String[] args) {
// String 타입의 참조 자료형 변수 str을 선언
// null도 주소값이다 (값이 없는 상태의 주소값이다)
// heap 영역의 주소값을 의미한다.
// 2) 지역 변수 선언, 힙에 생성 된 null의 주소를 저장
String str = null;
// 3) System 클래스 안에 PrintStream이 힙에 생성이 되고
// println() 함수를 호출 , 스택에서 제거(pop)
System.out.println("result1 : " + str);
// 4) 새로운 형태로 System 클래스 안에 PrintStream이 힙에 생성이 되고
// println() 함수를 호출 , 스택에서 제거(pop)
System.out.println("result2 : " + str);
// 5) main 메서드가 종료 되면서 스택에서 빠져 나가기 때문에
// 이 안에 선언 된 모든 지역 변수도 함께 사라진다.
int num1 = 100;
System.out.println(num1); // 정수형 변수는 println() 할 경우 문자열로 변환
// String 문자열 참조 자료형 변수를 선언
String str1;
// 글자의 갯수와는 상관이 없다.
str1 = "aaaaaabbbbbbcccccc";
System.out.println(str1);
// 문자열의 길이를 확인하기 위한 String 클래스의 메서드를 호출
System.out.println(str1.length());
str1 = " h1"; // 공백도 문자열로 인식됨
System.out.println(str1);
System.out.println(str1.length());
str1 = null; // 다시 초기화
str1 = "hi" + "one"; // 문자열 + 문자열 : 연결의미
System.out.println(str1); // *** 문자열은 객체, 불변적 특징이 있다
str1 = "hi" + 10; // 문자열 + 비문자열 : 연결의미
System.out.println(str1);
str1 = false + "hi";
System.out.println(str1);
}
}
package ex1;
public class Ex3_ReferenceDataType1 {
// 핵심 포인트 : 참조 자료형일 ? == , != 연산자는 값을 비교하는 것이
// 아니라 주소 값을 비교한다.
public static void main(String[] args) {
// == 비교 연산자 (<,>,|=, <=, >=) : boolean
// +, -, /, *, % => 산술 연산자
int num1 = 10;
int num2 = 20;
// 일반 자료형일 경우 값 비교
System.out.println("num1 == num2 => " + (num1 == num2));
System.out.println("num1 != num2 => " + (num1 != num2));
// 참조 자료형일 경우 ***** : 주소 값을 비교한다.
// 명시적 객체 생성시에는
String str1 = new String("Test"); // 0x100
String str2 = new String("Test"); // 0x200
System.out.println("str1 == str2 => " + (str1 == str2));
// 내용을 비교하고 싶을 때는 String 클래스에서 제공하는 메서드를 활용
System.out.println(str1.equals(str2));
// 내용을 비교할 때 대소문자 구분없이 비교해서 제공하는 메서드
System.out.println(str1.equalsIgnoreCase(str2));
System.out.println("----------------------------------");
// 묵시적 객체 생성 방법
// 상수 값이 같을 경우에는 주소 값이 같다 *****
// 설명)
// step1) s1에서 객체가 100번지로 힙에서 생성이 된다. [상수풀] Test
// step2) s2에서는 선언 한 후에 상수풀에 이미 등록 된 Test가 존재 하기 때문에
// 힙에서 더 이상 생성하지 않고 이미 힙에서 생성 된 100번지를 s2가 함께 참조하는 개념
String s1 = "Test";
String s2 = "Test";
System.out.println("s1 == s2 " + (s1 == s2)); // true
// String 클래스의 불변적 특징.
// 때문에 힙 영역에 잉여 객체를 가비지 객체가 소거하는 자원을 낭비하게 된다.
// 주의해야 할 사항 -> 안드로이드, 미들웨어 환경에서는 메모리 효율이 매우 중요함.
String msg = "AB";
msg = msg + "CD";
msg = msg + "EF";
System.out.println(msg); // ABCDEF
String msg2 = "AB";
msg2 += "CD";
msg2 += "EF";
System.out.println(msg2); // ABCDEF
System.out.println("----------------------------------");
// 개선책 += -> StringBuffer와 같은 버퍼 클래스를 생성해서 사용 권장!!
// 스레드 동기화 여부에 따른 차이가 있다.
// 객체를 생성
StringBuilder sb = new StringBuilder();
// 생성 된 객체의 주소 값을 저장한 sb를 가지고 "."(참조연산자) 가지고
// 해당 객체를 찾아가서 가지고 있는 메서드를 호출해서 사용하는 방법
// 주소가 버퍼에 유지 되기 때문에 가비지 컬렉션이 불필요하게 객체를 삭제
// 하는데 자원을 소비하지 않는다 -> 효율적이다.
sb.append("ABABAB");
sb.append("CDCDCD");
sb.append("EFEFEFEF");
System.out.println(sb);
int cap = sb.capacity();
System.out.println("용량 : " + cap);
System.out.println("길이 : " + sb.length());
sb.delete(0, 14);
System.out.println(sb);
sb.trimToSize(); // 문자열 데이터 사이즈 최소화
cap = sb.capacity();
System.out.println("용량2 : " + cap);
System.out.println("길이2 : " + sb.length());
}
}
package ex1;
import java.util.Scanner;
// 클래스를 객체로 생성 해보기
// jdk 5부터 제공해주는 Scanner 클래스를 생성해보자
// 외부 패키지에 있는 클래스를 불러오는 방법
// import 패키지명.클래스명 -> 올바른 표현 방법
// import 패키지명.*; -> 나쁜 표현 방법
// import java.util.Scanner;
public class Ex4_Scanner {
public static void main(String[] args) {
// String str; 클래스 변수 선언
// Scanner sc;
// 단축키 ctrl + space (클래스 내부 함수 보기, 클래스 자동 import)
// System.in : 키보드 장치로 입력
// sc = new Scanner(System.in);
// 실전
System.out.print("메세지 입력하세요 : ");
Scanner sc = new Scanner(System.in);
// . 연산자를 사용해서 힙에 접근해서 Scanner가 가지고 있는
// 자원을 접근해서 사용한다.
// sc.nextLine() 호출하면 반환 값이 String 이다.
// 그래서 메서드가 수행한 후의 그 값을 변수에 저장해서
// 다시 가공해서 사용하는 것이 일반적이다.
String msg;
msg = sc.nextLine(); // 대기하는 메서드 (blocking 메서드)
System.out.println("Msg : " + msg);
}
}
'JAVA > Study' 카테고리의 다른 글
| [세미 프로젝트] 4. GUI 제작 및 테이블, DTO 설계, 추상메서드 (0) | 2021.03.15 |
|---|---|
| [0201] 5. 제어문 (if,for,forfor), static 멤버 변수 (0) | 2021.03.01 |
| [0129] 4. 연산자, 조건문(if else) (0) | 2021.03.01 |
| [0128] 3. Wrapper 클래스, static 메서드, 메서드 문법 (0) | 2021.03.01 |
| [0126] 1. 프로그래밍 이론 및 자바 기본 실습 (개발환경구축) (0) | 2021.03.01 |