import java.util.StringTokenizer;
public class Aaaa {
public static void main(String[] args) {
String abc = "SrtingTokenizer/result/is/token";
StringTokenizer bcd = new StringTokenizer(abc, "/");
while (bcd.hasMoreTokens()) {
String cde = bcd.nextToken();
System.out.print(" "+cde);
}
}
}
result
SrtingTokenizer result is token
더 검색할 문자열이 있는지 확인하는 hasMoreTokens 메서드와 다음 문자열을 가져오는 nextToken 메서드를 사용한다
2. StringTokenizer 메서드
int countTokens()
전체 token의 개수가 아닌 현재 남아있는 token 개수를 반환한다
boolean hasMoreElements() boolean hasMoreTokens()
둘다 동일한 값을 반환한다 현재 위치 뒤에 있는 문자열에서 하나 이상의 토큰을 사용할 수 있는 경우 True를 반환하고 그렇지 않으면 false를 반환한다
Object nextElement() String nextToken()
두 개의 메서드는 같은 객체를 반환하지만 반환형은 다르다 nextElement는 Object를 반환한다 nextToken은 String을 반환한다
public class Example { //Example class 선언
int a = 10; //필드
if a(){ }; //메서드
void printX() {...} //메서드
Example exe = new Exanple() //생성자
class Example2 {...} //이너 클래스
}
2) 클래스 추가 정의
클래스 == 데이터 + 함수 의 결합으로 사용할 수 있다 - 클래스 : 데이터와 함수의 결합 (구조체 + 함수) - 데이터는 변수와 같다 - 함수는 메서드와 같으며, 명령문의 집합체이다 - 함수의 작업은 데이터를 재료로 계산을 한다 - 데이터와 함수는 상호 관련성이 있으므로 결합하여 사용하는 것이 용이하다
데이터 저장의 변화는 다음과 같다 - 변 수 : 하나의 데이터를 저장할 수 있는 공간 - 배 열 : 같은 종류의 여러 데이터를 하나로 저장할 수 있는 공간 - 구조체 : 서로 다른 종류의 데이터라도 관련성이 있다면 하나로 저장할 수 있는 공간 - 클래스 : 데이터와 함수의 결합 (구조체 + 함수)
클래스는 사용자 정의 타입이다 - 원하는 타입을 사용자가 직접 만들 수 있다 - ex) 사용자 정의 변수를 통하여 코그의 단순화한 경우
2. 객체
실제로 존재하는 사물이나 개념, 논리 등을 말한다
객체가 가지는 기능과 속성에 따라 사용되는 용도가 다르다
실제 존재물 HW을 컴퓨터가 실행할 수 있는 SW 로 만들는 과정에서 사용된다
모든 인스턴스를 대표하는 일반적 용어이다
클래스를 객체로 생성하기 위해서 메모리로 할당하는 과정을 인스턴스화 한다고 말한다
1) 구성요소
객체 = 속성(변수) + 기능(메서드) 로 구성된다
객체를 사용하기 위해서는 속성과 기능을 부여해 줘야 한다
HW를 분석하여 SW화 하는 방법이다
2) 객체의 생성
클래스명 ; //클래스를 선언한다
클래스명 변수명 ; //클래스의 객체를 참조하기 위한 변수(참조변수)를 선언한다
변수명 = new 클래스명( ) ; //클래스 인스턴스를 생성하여 참조변수에 주소를 저장한다. 메모리에 참조변수 영역을 확보한 객체가 생성된다
2와 3은 다음과 같이 줄여서 사용할 수 있다 -> Audio audio = new Audio( );
ex) 1 class Audio; class Audio;
2 Audio audio; -> Audio audio = new Audio( );
3 audio = new Audio( );
3) 객체의 사용
클래스 작성 -> 객체 생성 -> 객체 사용 의 순서로 작성한다 - 클래스는 객체를 만들기 위한 설계도 역활이며, 객체는 객체를 사용하기 위하여 생성된다.
객체의 사용은 변수와 메서드를 사용한다는 의미이다
객체 사용 시에는 참조변수를 필히 호출하여 사용한다 - 참조변수.멤버변수 = 값 ;//참조변수 객체의 멤버변수에 값을 저장하는 경우에 사용한다 ex) audio.volume = 50 ; //오디오 객체의 볼륨변수의 값을 50으로 저장한다
- 참조변수.메서드변수( ) ;-> 참조변수 객체의 메서드변수를 호출하여 실행하는 경우에 사용한다 ex) audio.volumeup( ) ; //오디오 객체의 볼륨변수에 있는 기능을 실행시킨다 (volume++)
변수가 생성되면 기본값으로 초기화된다
ex1)
ex2)
ex3)
class Audio {
public static void main(String arg[]){
Audio audio = new Audio( );
audio.model;//변수 사용
audio.power = power; //전원 true
audio.volume = 50; //현재 볼륨 입력
audio.volumeup( ); //메서드 사용, 볼륨 +1 상승 = 50+1 = 51
System.out.println("현재의 볼륨은" + audio.volume + "입니다");
}
}
class audio {
String model;
Int volume;
boolean power = power;
audio.model( ) {“white”;}
audio.power( ) {power = !power;}
audio.volumeup( ) {volume++;}
audio.volumedown( ) {volume--;}
}
result
"현재의 볼륨은 51입니다
import java.util.Scanner; //Scanner 유틸 호출
//간이계산기 프로그램
public class Calculator {
public static void main(String[] args) { //maun 메서드 선언
Scanner scan = new Scanner(System.in); //Scanner 객체 생성 : 외부입력
System.out.println("첫 번째 숫자를 입력하세요."); //콘솔출력
String no1 = scan.nextLine(); //첫 번째 숫자 입력
System.out.println("사칙연산자를 입력하세요.");
String op = scan.nextLine(); //사칙연산자 입력
System.out.println("두 번째 숫자를 입력하세요.");
String no2 = scan.nextLine(); //두 번째 숫자 입력
int num1 = Integer.parseInt(no1); //입력받은 첫 번째 문자를 숫자형으로 변환
int num2 = Integer.parseInt(no2); //입력받은 두 번째 문자를 숫자형으로 변환
int result;
if(op.equals("+")) { //덧셈 연산
result = num1 + num2;
}
else if(op.equals("-")) { //뺄셈 연산
result = num1 - num2;
}
else if(op.equals("/")) { //나누기 연산
result = num1 / num2;
}
else{
result = num1 * num2; //곱하기 연산
}
System.out.println(no1 + " " + op + " " + no2 + " = " + result); // 결과값 출력
}
}
3. 소스파일과 클래스의 관계
하나의 소스 파일에는 하나의 public class만 존재해야 한다
또한, 하나의 소스 파일에는 하나의 클래스만 존재하는 것을 권장한다
소스파일의 이름은 main 메서드가 있는 클래스의 이름과 일치해야 한다
하나의 소스 파일에 여러 개의 클래스가 존재할 경우 소스파일의 이름은 아래와 같이 사용한다
소스파일
클래스
내용
Hello1.java
public class Hello1 { } class Hello2 { }
public class가 있는 경우 소스파일의 이름은 반드시 public class 이름과 일치해야 한다
class Hello1 { } class Hello2 { }
public class가 없는 경우 소스파일의 이름은 Hello1, Hello2 어떤 것을 사용해도 상관없다
아래와 같은 경우는 오류가 발생한다
소스파일
클래스
내용
Hello1.java
public class Hello1 { } public class Hello2 { }
하나의 소스파일에 두 개 이상의 public class가 존재할 수 없다 각 클래스를 별도의 소스파일로 나눠서 저장하거나 class 중 한 개의 public를 삭제해야 한다
Hello2.java
public class Hello1 { } class Hello2 { }
소스파일의 이름과 public class의 이름이 일치하지 않는다 소스파일의 이름을 Hello1.java로 변경해야 한다
hello1.java
public class Hello1 { } class Hello2 { }
소스파일의 이름과 public class의 이름이 일치하지 않는다 소스파일의 이름은 대소문자도 일치해야 한다 소스파일의 이름을 대문자 H로 변경해야 한다
'String 참조변수 ; 참조변수 = "문자열"'의 형태로 선언 : 문자열 리터럴을 대입하는 방식
'String 참조변수 = "문자열"'의 형태로 선언 : 문자열 리터럴을 대입하는 방식
'String 참조변수 = new String("문자열")'의 형태로 선언 : 객체를 생성하고 문자열을 대입하는 방식
public class Grade {
public static void main(String[] args) {
String str;
str = "문자열";
System.out.println(str);
String str1 = "문자열1";
System.out.println(str1);
String str2 = new String("문자열2");
System.out.println(str2);
}
}
result
문자열
문자열1
문자열2
'String 참조변수 = "문자열"'의 형태로 선언
문자열 리터럴을 대입하는 방식의 주소값과 객체를 생성하는 방식의 주소값은 서로 다르다
그러므로, 문자열을 비교할 경우 등호"=" 대신 equals를 사용한다 ("=="은 저장공간의 주소를 비교하므로 문자열에 적합하지 않다)
public class Grade {
public static void main(String[] args) {
String str;
str = "문자열";
String str1 = "문자열";
String str2 = new String("문자열");
System.out.println(str==str1);
System.out.println(str==str2);
}
}
result
true
false
위에 코드에서 str==str1은 true로 같지만, str==str2는 false로 서로 다르다
3. String 특성
String 문자열은 내용을 변경할 수 없다
a = a+ b로 인하여 문자열 결합을 하였을 때 새로운 a의 저장공간이 생성된다
a = a + b의 결과가 "문자열1"이 아닌 "문자열1문자열2"로 출력되며, a라는 새로운 저장공간이 생성된다
a = "문자열1";
b = "문자열2";
a = a + b;
System.out.println(a);
result
문자열1문자열2
수식에 의한 새로운 저장공간의 생성은 데이터의 처리 속도를 지연시킨다
문자열 변환이 필요한 변수에는 StingBuffer 메서드를 사용하는 것이 편리하다
같은 내용의 문자열 리터럴은 하나만 만들어진다
String a = "abc";
String b = "abc";
String c = "abc";
//문자열이 동일하므로 "abc" 저장공간 1개만 생성된다
4. String 관련 대표 method
1) charAt( )
해당 문자열의 특정 인덱스에 해당하는 문자를 반환한다
해당 문자열의 길이보다 큰 인덱스나 음수를 전달하면, 오류가 발생한다
public class Grade {
public static void main(String[] args) {
String str =new String("charAt method");
System.out.println("문자열 : "+ str);// "문자열 : charAt method""
System.out.println(str.charAt(0));// 'c'
System.out.println(str.charAt(4));// 'A'
System.out.println(str.charAt(6));// ' '
System.out.println(str.charAt(12));// 'd'
System.out.println(str.charAt(13));// 'error'
System.out.println("\ncharAt() 메서드 호출 후 문자열 : "+ str);
}
}
result
문자열 : charAt method
c
A
d
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 13
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:47)
at java.base/java.lang.String.charAt(String.java:693)
at Grade.main(Grade.java:9)
//13번째문자열이 인덱스를 벗어났다고 에러 표시
public class Grade {
public static void main(String[] args) {
String str =new String("charAt method");
System.out.println("문자열 : "+ str);// "문자열 : charAt method""
System.out.println(str.charAt(0));// 'c'
System.out.println(str.charAt(4));// 'A'
System.out.println(str.charAt(6));// ' '
System.out.println(str.charAt(12));// 'd'
//System.out.println(str.charAt(13));// 'error'
System.out.println("\ncharAt() 메서드 호출 후 문자열 : "+ str);
}
}
result
문자열 : charAt method
c
A
d
charAt() 메서드 호출 후 문자열 : charAt method
//index 13을 주석 처리 후 정상 출력
2) compareTo( )
해당 문자열을 인수로 전달된 문자열과 사전 편찬 순으로 비교
문자열을 비교할 때 대소문자를 구분하여 비교한다
두 문자열이 같다면 0을 반환
해당 문자열이 인수로 전달된 문자열보다 작으면 음수를, 크면 양수를 반환
- 문자열을 비교할 때 대소문자를 구분하지 않으려면 compareToIgnoreCase() 메서드를 사용
public class Grade {
public static void main(String[] args) {
String str =new String("concat");
System.out.println("문자열 : "+ str);
System.out.println(str.concat(" - method"));
System.out.println(str.concat(""));
System.out.println("concat() 메서드 호출 전 문자열 : "+ str);
}
}
result
문자열 : concat
concat - method
concat
concat() 메서드 호출 전 문자열 : concat
4) indexOf( )
해당 문자열에서 특정 문자나 문자열이 처음으로 등장하는 위치의 인덱스를 반환한다
문자열의 대소문자를 구분한다
만약 해당 문자열에 전달된 문자나 문자열이 포함되어 있지 않으면 -1을 반환한다
public class Grade {
public static void main(String[] args) {
String str =new String("indexOf-method");
System.out.println("문자열 : "+ str);
System.out.println(str.indexOf('o'));//소문자 'o'의 위치값
System.out.println(str.indexOf('O'));//대문자 'O'의 위치값
System.out.println(str.indexOf('a'));//소문자 'a'의 위치값
System.out.println(str.indexOf("-"));//특수문자 '-'의 위치값
System.out.println("indexOf() 메서드 호출 후 원본 문자열 : "+ str);
}
}
result
문자열 : indexOf-method
12
5
-1
7
indexOf() 메서드 호출 후 원본 문자열 : indexOf-method
5) trim( )
해당 문자열의 맨 앞과 맨 뒤에 포함된 모든 공백 문자를 제거한다
public class Grade {
public static void main(String[] args) {
String str =new String(" trim ");
System.out.println("문자열 : "+ str);
System.out.println(str +"end");
System.out.println("0"+str.trim()+"-end");
System.out.println("trim() 메서드 호출 후 문자열 : "+ str);
}
}
result
문자열 : trim
trim end
0trim-end
trim() 메서드 호출 후 문자열 : trim
6) toLowerCase()와 toUpperCase()
toLowerCase() : 해당 문자열의 모든 문자를 소문자로 변환한다
toUpperCase() : 해당 문자열의 모든 문자를 대문자로 변환한다
public class Grade {
public static void main(String[] args) {
String str =new String("toUpper/LowerCase");
System.out.println("문자열 : "+ str);
System.out.println(str.toLowerCase());
System.out.println(str.toUpperCase());
System.out.println("두 메서드 호출 후 문자열 : "+ str);
}
}
result
문자열 : toUpper/LowerCase
toupper/lowercase
TOUPPER/LOWERCASE
두 메서드 호출 후 문자열 : toUpper/LowerCase
7) 그 외 String 메서드 설명
char charAt(int index)
해당 문자열의 특정 인덱스에 해당하는 문자를 반환함.
String(char[ ] value)
주어진 문자열(char[ ])을 갖는 String으로 변환한다
int compareTo(String str)
해당 문자열을 인수로 전달된 문자열과 사전 편찬 순으로 비교함.
int compareToIgnoreCase(String str)
해당 문자열을 인수로 전달된 문자열과 대소문자를 구분하지 않고 사전 편찬 순으로 비교함.
String concat(String str)
해당 문자열의 뒤에 인수로 전달된 문자열을 추가한 새로운 문자열을 반환함.
int indexOf(int ch)int indexOf(String str)
해당 문자열에서 특정 문자나 문자열이 처음으로 등장하는 위치의 인덱스를 반환함.
int indexOf(int ch, int fromIndex) int indexOf(String str, int fromIndex)
해당 문자열에서 특정 문자나 문자열이 전달된 인덱스 이후에 처음으로 등장하는 위치의 인덱스를 반환함.
int lastIndexOf(int ch)
해당 문자열에서 특정 문자가 마지막으로 등장하는 위치의 인덱스를 반환함.
int lastIndexOf(int ch, int fromIndex)
해당 문자열에서 특정 문자가 전달된 인덱스 이후에 마지막으로 등장하는 위치의 인덱스를 반환함.
String[] split(String regex)
해당 문자열을 전달된 정규 표현식(regular expression)에 따라 나눠서 반환함.
String substring(int beginIndex)
해당 문자열의 전달된 인덱스부터 끝까지를 새로운 문자열로 반환함.
String substring(int begin, int end)
해당 문자열을 전달된 정규 표현식(regular expression)에 따라 나눠서 반환함.
참조변수[ ]에 배열의 값이 각각 자동으로 대입되며, 대입되는 값의 번호를 인덱스(index)라고 한다
index 의 범위는 0부터 '배열길이-1' 까지이며 '-1'을 하는 이유는 '0'부터 시작하기 때문이다
ublic class Grade {
public static void main(String[] args) {
int a=0, b=1, c=2, d=3, e=4; //a,b,c,d,e의 초기값 선언-5개 변수 사용
System.out.println(a); //a의 결과값 출력
System.out.println(b); //b의 결과값 출력
System.out.println(c); //c의 결과값 출력
System.out.println(d); //d의 결과값 출력
System.out.println(e); //e의 결과값 출력
int[] score = new int[5]; //int 타입의 참조변수 score에 대해 5개의 저장공간을 확보
score[0] = 1;
score[1] = 2;
score[2] = 3;
score[3] = 4;
score[4] = 5;
System.out.println(score[0]);//score의 0번째 값
System.out.println(score[1]);//score의 1번째 값
System.out.println(score[2]);//score의 2번째 값
System.out.println(score[3]);//score의 3번째 값
System.out.println(score[4]);//score의 4번째 값
}
}
result
0
1
2
3
4
1
2
3
4
5
//다중 변수의 연속 사용과 한개의 변수에 여러 값 사용의 차이
위에서 int a=0 은 정수 a에 대한 메모리 공간 4byte 1개를 확보한다
score는 int[5] 를 통해서 메모리에 5개의 저장공간을 연속으로 확보한다
'타입[ ] + 참조변수 = new 타입[ ]{요소 값}' 처럼 사용하기도 한다
public class Grade {
public static void main(String[] args) {
int[] score = new int[]{1,2,3,4,5}; //int 타입의 참조변수 score에 대해 5개의 저장공간을 확보
System.out.println(score[0]);//score의 0번째 값
System.out.println(score[1]);//score의 1번째 값
System.out.println(score[2]);//score의 2번째 값
System.out.println(score[3]);//score의 3번째 값
System.out.println(score[4]);//score의 4번째 값
}
}
result
1
2
3
4
5
.length 를 사용하여 배열의 길이를 확인할 수 있다
4. 다차원 배열
1) 다차원 배열이란?
1차원 이상의 논리적인 구조를 가진다는 의미이다
배열이 배열의 요소로 사용되는 경우이다
2) 2차원 배열
'타입[ ][ ] + 참조변수' 또는 '타입 + 참조변수[ index1] [index2] ]' 의 형태로 선언한다
String [ ] Arry = new String [ index ] - index : 단어의 갯수를 입력한다 Arry [1] = " 단어 " ; Arry [2] = " 단어 " ;
※ 문자와 문자열을 담는 기호에 주의한다
// 선언 후 각 배열에 값을 넣어 초기화하는 경우
String[] str = new String[3];
str[0] = "Hello";
str[1] = "Java";
str[2] = "World";
// 선언과 동시에 값을 넣어 초기화하는 경우
String[] str = new String[] {"Hello", "Java", "World"};
String[] str = {"Hello", "Java", "World"}; // new String[] 생략 가능
// String Class를 사용해서 선언하고 초기화하면 이렇게 간편하게 만들 수 있다
String str = "Hello Java World";
6. 객체의 배열
객체 배열 == 참조변수 배열
객체는 참조변수의 집합이므로 객체배열 또한 참조변수의 배열과 같다
Speak 클래스의 참조변수 speak1, speak2, speak3는 아래와 같이 작성할 수 있다 Speak speak1, speak2, speak3; // Spaea[ ] speakArr = new Speak[3];
classExample{ publicstaticvoidmain(String[] args){ int num1 = 1; // num1(변수) , 1(값) int num2 = 2; int num3 = 3; ... } }
2. 변수 사용의 목적
메모리에 데이터 저장 공간을 확보하기 위해서 사용한다
여러 개발자와 협업을 진행할 경우 변수명을 붙여 데이터의 흐름을 상호간에 식별하여 소통할 수 있게 한다
데이터를 재사용할 경우 변수명만으로 사용할 수 있어서 용이하다
public class Grade {
public static void main(String[] args) {
int a=10, b=2, c=5; //a, b, c의 초기값
System.out.println(a+b); //a+b의 결과값 출력
System.out.println(a+b*c); //a+b*c의 결과값 출력
System.out.println(a+b+c); //a+b+c의 결과값 출력
System.out.println(a+b/c); //a+b/c의 결과값 출력
}
}
result
12
20
17
10
//a,b,c 값을 한번 선언함으로 여러가지 수식에 의한 값을 도출할 수 있다
2) 변수의 선언 타입
변수 a의 값을 10으로 선언한다면 10이 정수이므로 int 타입으로 선언할 수 있다
public class Grade {
public static void main(String[] args) {
int a=10; //10이 정수이므로 int 타입으로 선언
}
}
데이터의 종류에 따라 타입을 사용할 수 있다
public class Grade {
public static void main(String[] args) {
int a=10; //10이 정수이므로 int 타입으로 선언
float b=1.23456789F; //실수이므로 float 타입으로 선언
double c=1.23456789012345678D; //실수이므로 double 타입으로 선언
char d=75; //K를 유니코드 75로 char 타입으로 선언
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
result
10
1.2345679
1.2345678901234567
K
변수는 동일한 타입일 경우 타입은 한번만 선언해도 된다
public class Grade {
public static void main(String[] args) {
int a=10, b=20, c=30, d=40; //10이 정수이므로 int 타입으로 선언
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
result
10
20
30
40
변수의 값은 마지막에 적용된 변수의 값으로 저장된다
public class Grade {
public static void main(String[] args) {
int a=10; //a의 초기값
a=a+1; //a+1의 결과값
System.out.println(a); //최종 a+1의 결과값 a 출력
}
}
result
11
3. 변수의 종류
1) 클래스 변수
클래스 영역 내에서 static이 붙는 변수이다
클래스 정의에서 static 필드로 객체가 공유하는 변수이다
선언된 클래스 내부에서 사용 가능하다
클래스 외부에서의 사용은 접근제어자(access modifier)에 따라 다르다
2) 인스턴스 변수
클래스 정의에서 static이 아닌 필드로 객체가 소유하는 변수이다
객체는 인스턴스 변수의 묶음이다
객체가 생성되었을 때 생성된다
선언된 클래스 내부에서 사용 가능하다
클래스 외부에서의 사용은 접근제어자(access modifier)에 따라 다르다
3) 지역 변수
메서드 내부 또는 블록 내부에서 선언된 변수이다
메서드가 실행될 때 만들어지고 실행 후 사라진다
초기값을 지정한 후 사용해야 한다
변수 선언 시 접근 제어자를 사용하지 않는다
4) 파라미터
메서드 호출 시 전달하는 값을 저장하기 위한 변수이다
메서드가 실행될 때 만들어지고 실행 후 사라진다
4. 변수명
변수명은 영문자(대문자, 소문자)나 숫자, _, $ 를 사용할 수 있다
영문자는 대소문자가 구별되어 인식된다 - a와A는 다른 문자로 인식한다
자바에서 변수명은 일반적으로 카멜 케이스(camelCase)를 사용한다 - 카멜케이스는 두 번째 단어부터 대문자로 시작해 구분한다 - camelCase 는 낙타와 닮았다고 붙여진 명칭이다
public class Grade {
int a[2];
int b[2];
void input_grade(){
a[0]=90;
a[1]=80;
b[0]=85;
b[1]=80;
}
void output_grade(){
System.out.printf("%c, %c", a[0]+b[0], a[1]+b[1]);
}
void main(void) {
input_grade();
output_grade();
}
}
해답은 아래에...
.
.
.
.
.
.
.
.
.
class Record {
int a;
int b;
void output_grade(){
System.out.println(a+b);
}
}
public class Grade{
public static void main(String[] args) {
Record c1=new Record();
Record c2=new Record();
c1.a=90;
c1.b=80;
c2.a=85;
c2.b=80;
c1.output_grade();
c2.output_grade();
}
}
※ 다음과 같이 작성할 수도 있다
class Record {
int e; //성적1을 위한 필드
int m; //성적2를 위한 필드
void input_record(int a,int b){ //input_record에 대한 함수 정의
e=a; //성적1 입력
m=b; //성적2 입력
}
void output_record(){ //output_record에 대한 함수 정의
System.out.println(e+m); //합계 출력
}
}
public class Grade{
public static void main(String[] args) {
Record c1=new Record(); //학생1에 대한 객체 생성
Record c2=new Record(); //학생2에 대한 객체 생성
c1.input_record(90,80); //학생1에 대한 성적 입력
c2.input_record(80,85); //학생2에 대한 성적 입력
c1.output_record(); //합계 출력
c2.output_record(); //합계 출력
}
}
데이터의 실제 값을 의미하며 4가지 타입으로 구분된다 - 정수 타입 : byte, short, int, long - 실수 타입 : float, double - 문자 타입 : char - 논리 타입 : Boolean
2)참조 타입(reference type)
데이터가 저장된 주소값을 의미한다
객체의 주소를 저장한다 - 참조타입변수 = 객체;
8개의 기본타입을 제외한 나머지를 참조 타입이라 한다
‘OO은 OO에서 찾을 수 있다’처럼 간접적으로 표현하는 데이터이다
class Example {
public static void main(String[] args) {
Object object = new Object(); //Object 객체를 참조변수 object에 저장한다
System.out.pringln(object); //참조변수 object가 저장하고 있는 값을 출력한다
}
}
상기 예제를 실행하면 다음과 같은 결과가 출력된다
System.out.println(object); 의 결과로 Object 객체에 대한 주소값을 출력한다
- int(4byte)보다 길다 - long 타입 변수에 값을 할당할 때 4byte의 데이터가 아니라 8byte의 데이터 값이라는 것을 컴파일러에 알려주기 위해 끝에 'L'을 붙인다
※ byte= 컴퓨터가 처리하는 정보의 기본 단위
1byte = 8bit = 하나의 문자를 나타내는 가장 작은 단위 1bit = 0 또는 1을 저장하는 최소 단위
2) 정수 타입의 특성
int는 정수형의 기본타입이다
정수를 입력하면 기본적으로 int 로 인식한다
ex1) byte 타입 변수 a에 값 120을 할당하면, byte 범위 내에 있으므로 컴파일러가 byte로 바꿔서 전달한다
byte 타입 변수 a1에 값 128을 할당하면, byte 범위 밖에 있으므로 컴파일러에서 오류가 발생한다
public class Main {
public static void main(String[] args){
Object object =new Object();
byte a = 120; //정상 실행
System.out.println(a);
byte a1 = 128; //byte 127의 범위를 벗어남으로 오류 발생
System.out.println(a1);
}
}
/*java: incompatible types: possible lossy conversion from int to byte 에러 코드 발생
( 호환이 안되는 유형: byte에서 int로 전환 가능하다 ) */
ex2) int 타입 변수 a에 값 120을 할당하면, int 범위 내에 있으므로 컴파일러가 byte로 바꿔서 전달한다
int 타입 변수 a1에 값 2147483648을 할당하면, int 범위 밖에 있으므로 컴파일러에서 오류가 발생한다
public class Main {
public static void main(String[] args){
Object object =new Object();
int a = 120;
System.out.println(a);
int a1 = 2147483648;
System.out.println(a1);
}
}
/*java: integer number too large 에러발생
(정수가 너무 크다 )*/
long타입은 입력값 마지막에 'L'을 붙여준다
변수의 값이 자료형의 범위를 넘을 경우 오버플로우(overflow)또는 언더플로우(underflow)가 발생하기 때문에 필요에 따라long과 같은 타입을 사용
ex3) long 타입 변수 a1에 값 2147483648+'l' 또는 2147483648+'L'을 할당하면, long 범위 내에 있으므로 컴파일러가 byte로 바꿔서 전달한다
public class Main {
public static void main(String[] args){
Object object =new Object();
int a = 2147483647;
System.out.println(a);
long a1 = 2147483648l;
//마지막에 'l'을 붙이지 않으면 java: integer number too large 에러 발생
System.out.println(a1);
long a2 = 2147483648L;
//마지막에 'l'을 붙여도 에러는 발생하지 않지만 'L'을 사용하여 준자
System.out.println(a2);
}
}
3) 오버플로우(Overflow)
자료형이 표현할 수 있는 범위 이상의 값을 표현한 경우 발생하는 현상
어떤 값이 byte형이고, byte형의 최댓값인 127을 값으로 가지는 경우, 이 값에 1을 더하면 128이 아니라 -128이 됩니다.
4) 언더플로우(Underflow)
자료형이 표현할 수 있는 범위 이하의 값을 표현한 경우 발생하는 현상
어떤 값이 byte형이고, byte 형의 최솟값인 -128을 값으로 가지는 경우, 이 값에 1을 빼면 -129가 아니라 127이 됩니다.
4. 실수 타입(float, double)
: 실수는 소숫점을 가지고 있는 값을 말한다
float
double
4byte = 32bit 소숫점 포함 9자리까지 표시
8byte = 64bit 소숫점 포함 18자리까지 표시
32비트 IEEE 754 부동 소수점
64비트 IEEE 754 부동 소수점
접미사 'f'를 사용
접미사 'd' 또는 'D'를 사용
정수가 아닌 소수점 단위의 값을 데이터로 가져올 때 사용한다
실수 타입의 값은 두가지 유형 모두 정확하지 않다
public class Grade {
public static void main(String[] args) {
float f1 = 12345.123456789012345678901234567890f;
double d1 =12345.123456789012345678901234567890;
System.out.println("float f1 : " + f1);
System.out.println("double d1 : " + d1);
}
}
result
float f1 : 12345.123
double d1 : 12345.123456789011
5. 논리 타입(boolean)
: 참(true) 또는 거짓(false)를 저장할 수 있는 타입이다
값으로 true 와 false를 가진다
컴퓨터 언어로 0과 1로 저장하며 1bit로 표현된다
JVM이 다루는 최소 단위가 1byte이므로 1byte의 크기를 차지한다
조건이 참 또는 거짓일 경우 사용한다
public class Grade {
public static void main(String[] args) {
boolean Rain = true;
if (Rain == false) {
System.out.println("우산을 들고 나간다");
}
else {
System.out.println("우산을 놓고 나간다");
}
System.out.println(Rain);
}
}
result
우산을 놓고 나간다
true
long longValue = 12345L;
float floatValue = longValue;
// float이 long보다 정밀하므로, 자동으로 타입이 변환된다
System.out.println(floatValue);
// 12345.0이 출력된다
2) 수동 변환
메모리 용량이 큰 타입에서 작은 타입으로 변환은 자동변환이 되지 않는다
큰 데이터 타입을 작은 데이터 타입의 변수에 저장하는 것을 캐스팅(casting)이라고 한다
캐스팅 연산자 ( )를 사용하며, 연산자 안에 변환하고자 하는 타입을 작성해 준다
int intValue = 128;
byte byteValue = (byte)intValue;
//int 타입으로 선언된 변수 intValue를 더 작은 단위인 byte로 변환
System.out.println(byteValue);
//출력값은 byte의 최대 표현 값인 127이 아니라 -128이다
//표현 범위를 넘으면 한 바퀴를 돌아 음수로 출력하기 때문이다
내부 클래스를 사용하면 외부 클래스의 멤버들에 쉽게 접근 할 수 있고, 코드의 복잡성을 줄일 수 있다
외부적으로 불필요한 데이터를 감출 수 있어 캡슐화(encapsulation)를 달성하는 데 유용하다
기본적으로 내부 클래스는 외부 클래스 내에 선언된다는 점을 제외하면 일반 클래스와 차이점이 없다 - 외부 클래스와 내부 클래스가 서로 연관되어 있을 때 사용의 편의성을 고려하여 만들어진 문법 요소이다
class Outer { // 외부 클래스
class Inner {
// 인스턴스 내부 클래스
}
static class StaticInner {
// 정적 내부 클래스
}
void run() {
class LocalInner {
// 지역 내부 클래스
}
}
}
내부 클래스의 종류는 세가지로 구분한다 - 인스턴스 내부 클래스 - 정적 내부 클래스 - 지역 내부 클래스
세 가지 내부 클래스는 변수가 선언 위치에 따라 인스턴스 변수, 클래스 변수, 그리고 지역 변수로 구분되는 것과 유사하게 그 위치를 중심으로 구분될 수 있다
각각의 유효범위(scope)와 특성이 변수의 구분과 매우 유사하다
내부클래스 종류
종 류
선언 위치
사용 가능한 변수
인스턴스 내부 클래스 (instance inner class)
외부 클래스의 멤버변수 선언위치에 선언(멤버 내부 클래스)
외부 인스턴스 변수 외부 전역 변수
정적 내부 클래스 (static inner class)
외부 클래스의 멤버변수 선언위치에 선언(멤버 내부 클래스)
외부 전역 변수
지역 내부 클래스 (local inner class)
외부 클래스의 메서드나 초기화블럭 안에 선언
외부 인스턴스 변수 외부 전역 변수
익명 내부 클래스 (anonymous inner class)
클래스의 선언과 객체의 생성을 동시에 하는 일회용 익명 클래스
외부 인스턴스 변수 외부 전역 변수
1) 인스턴스 내부 클래스(instance inner class)
인스턴스 내부 클래스는 외부 클래스의 내부에 위치해 있다
private 접근 제어자(해당 클래스 안에서만 접근 가능한 멤버에 사용)를 사용하고 있음에도 내부에서 외부 클래스의 인스턴스 변수와 정적 변수에 각각 접근하여 해당 값을 사용하고 있다
인스턴스 내부 클래스는 반드시 외부 클래스를 생성한 이후에 사용해야 한다
클래스의 생성과 상관없이 사용할 수 있는 정적 변수와 정적 메서드는 인스턴스 내부 클래스에서 선언할 수 없다
class Outer{
private int num = 1;
private static int sNum = 2;
private InnerClass innerClass;
public Outer(){
innerClass = new InnerClass();
}
class InnerClass{
int inNum = 10;
void innerMethod(){
System.out.println("Outer num = " + num + "(instance variable of outer class)");
System.out.println("Outer sNum = " + sNum + "(static variable of outer class");
}
}
public void testClass(){
innerClass.innerMethod();
}
}
public class MainClass {
public static void main(String[] args) {
Outer outer = new Outer();
System.out.println("call up inner class function used outer class");
outer.testClass();
}
}
2) 정적 내부 클래스
내부 클래스가 외부 클래스의 존재와 무관하게 정적 변수를 사용할 수 있는 것이 정적 내부 클래스이다
인스턴스 내부 클래스와 동일하게 클래스의 멤버 변수 위치에 정의하지만 static 키워드를 사용한다
class Outer1{
private int num = 3;
private static int sNum = 4;
void getPrint(){
System.out.println("Instance Method");
}
static void getPrintStatic(){
System.out.println("Static Method");
}
static class StaticInClass {
void test() {
System.out.println("Outer num = " + sNum + "(static variable of outer class)");
getPrintStatic();
}
}
}
public class StaticInnerClass {
public static void main(String[] args) {
Outer1.StaticInClass a = new Outer1.StaticInClass();
a.test();
}
}
4. 지역 내부 클래스(local inner class)
지역 내부 클래스는 클래스의 멤버가 아닌 메서드 내에서 정의되는 클래스이다
지역 변수와 유사하게 메서드 내부에서만 사용가능하다
일반적으로 메서드 안에서 선언 후에 바로 객체를 생성해서 사용한다
class Outer2{
int num = 5;
void test(){
int num2 = 6;
class LocalInClass{
void getPrint(){
System.out.println(num);
System.out.println(num2);
}
}
LocalInClass localInClass = new LocalInClass();
localInClass.getPrint();
}
}
public class LocalInnerClass {
public static void main(String[] args) {
Outer2 outer = new Outer2();
outer.test();
}
}
지역 내부 클래스 LocalInClass가 메서드 안에서 선언되고 생성된 후에 정의된 메서드를 호출하여 외부 클래스의 변수들을 출력하고 있다
내부 클래스는 기본적으로 개발자의 편의를 위해 서로 연관있는 클래스들을 연결시켜 주는 것이다