1) 참조 타입
- 객체의 번지를 참조하는 타입
- 배열, 열거, 클래스, 인터페이스 타입 등
- 기본 타입으로 선언된 변수는 값 자체를 저장하지만, 참조 타입으로 선언된 변수는 객체가 생성된 메모리 번지를 저장, 각각 고유의 주소값을 가지고 있다.
- 기본 타입은 즉시 값을 가져올 수 있고, 참조 타입은 주소 안에 있는 값을 가져온다.
- 기본 타입 : 정수, 실수, 문자, 논리 값을 직접 저장(정수 : int, short, char, bype, long / 실수 : float, double / 논리 : boolean)
- 참조 타입 : 객체의 주소를 저장(배열, 열거, 클래스, 인터페이스)
① 배열
String[] str = new String[5];
변수타입에 [] 대입
new 연산자로 객체 생성 및 길이 지정
public static void referenceSample() {
//문자열 형태의 배열을 선언, 길이는 5로 지정
String[] arr = new String[5];
arr[0] = "하이1";
arr[1] = "하이2";
arr[2] = "하이3";
arr[3] = "하이4";
arr[4] = "하이5";
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3] = "수정 하이3");
System.out.println(arr[4]);
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}

1-1. 하이3 들어있는 데이터를 반복문에서 hi3으로 변경
public static void referenceSample() {
String[] arr = new String[5];
arr[0] = "하이1";
arr[1] = "하이2";
arr[2] = "하이3";
arr[3] = "하이4";
arr[4] = "하이5";
for(int i = 0; i < arr.length; i++) {
if(arr[i].equals("하이3")) {
arr[i] = "hi3";
}
System.out.println(arr[i]);
}
}

② 열거타입
enum color{red; green;}
public static void referenceSample() {color fc = color red;}
- 클래스 블록 내부에 enum 선언 / 메서드 블록 내부에 enum 객체 생성 및 변수 접근 / enum 클래스 자체 생성
- 요일, 계절처럼 한정된 값을 갖는 타입(상수)
- 열거 타입 이름은 첫 문자를 대문자로 하고 캐멀 스타일로 지어주는 것이 관례
- 메서드 영역에 저장되지만 새로운 객체 생성시 힙영역으로 저장됨
③ 클래스
public class ReferenceEdu{}
- 패키지 내부에 클래스 파일 생성
- 기능을 구현하기 전 설계도
④ 인터페이스
public interface ReferInterface{public String refer1();}
- 패키지 내부에 클래스 파일 생성시 interface 유형으로 생성
- 추상메서드만 포함하는 클래스
- 다중 상속 지원
- 다형성
- 실제 기능을 구현하기 전 메서드를 정의하는 클래스
1-2) 메모리 사용 영역
- JVM은 운영체제에서 할당받은 메모리 영역을 메서드 / 힙 / 스택 영역으로 구분해서 사용
① 메서드 영역 : 바이트코드 파일을 읽은 내용이 저장되는 영역
클래스-1 (상수, 정적 필드 / 메서드 코드 / 생성자 코드 ) ... 클래스-n (상수 / 메서드 코드 / 생성자 코드)
② 힙 영역 : 객체가 생성되는 영역. 객체의 번지는 메서드 영역과 스택 영역의 상수와 변수에서 참조
객체-1 / 배열-2 / 객체-3 / 배열-4 / ...
③ 스택 영역 : 메서드를 호출할 때마다 생성되는 프레임이 저장되는 영역

1-3) null
- 참조타입은 변수의 초기값을 null로 할당할 수 있다.
- 참조타입의 변수에 null을 할당하여 변수에 담긴 데이터가 없다면 스택 영역의 메모리에만 변수가 등록된다.
- 참조타입의 변수에 초기값을 null로 할당하고 값을 대입할 때 객체 생성
public void refer4() {
//초기값 null로 할당
int[] intArray = null;
// 1. 첫 번째 방법
intArray = new int[5];
intArray[0] = 10;
intArray[1] = 20;
intArray[2] = 30;
System.out.println(intArray[0]);
System.out.println(intArray[1]);
System.out.println(intArray[2]);
// 2. 두 번째 방법
intArray = new int[] {10, 20, 30};
System.out.println(intArray[0]);
System.out.println(intArray[1]);
System.out.println(intArray[2]);
}

1-3) String
- String 타입의 문자열 변수는 객체를 공유하도록 설계
- 변수명이 달라도 같은 데이터라면 프로그램 상에서 같은 객체로 인식
public static void singOperatorSamle13() {
//String 참조변수 타입 = 고유의 주소값이 부여됨.
//서로 다른 주소값을 가진 객체가 생성돼도 데이터가 같다면 덮어씌움.
String name1 = "홍길동";
String name2 = "홍길동";
System.out.println(System.identityHashCode(name1));
System.out.println(System.identityHashCode(name2));
boolean result1 = (name1 == name2);
System.out.println("result : "+ result1);
String name3 = new String("홍길동");
String name4 = new String("홍길동");
System.out.println(System.identityHashCode(name3));
System.out.println(System.identityHashCode(name4));
boolean result2 = (name3 == name4);
System.out.println("result2 : "+ result2);
/* == 연산자로 비교하면 메모리 주소를 비교한다.
* java에서 문자열 리터럴은 String pool이라는 데이터 영역에 저장되는데,
* 같은 문자열이 있는 경우 하나의 객체로 관리한다..
* 따라서 name1, name2의 "홍길동" 문자열은 같은 객체를 참조하게 된다..
* name1 == name2 비교연산은 메모리 상에서 같은 객체를 참조하는지 확인하므로,
* result1의 결과가 true가 된다@!@@
*
* result2는 String data type으로 name3, name4 객체참조변수를 선언하고,
* new 키워드로 생성자 메서드를 호출했기 때문에 새로운 객체가 생성되는데, 이 객체는
* 힙 메모리 영역에 할당되므로 문자열 리터럴과 다른 메모리 영역을 가진다.
* 새로운 객체가 생성되면 새로운 주소가 생성되어서 name3 == name4 비교연산은
* 변수의 주소를 비교하게 되고 따라서 false가 출력된다.....????
*/
boolean result3 = (name3.equals(name4));
System.out.println("result3 : "+ result3);
//문자열의 데이터를 비교하려면 equals() 메서드를 사용해야 한다....
}

1-4) 문자열 관련 메서드
1. 특정 위치 문자 추출
public static void referenceSample2() {
System.out.println("1. 특정위치 문자 추출");
String name1 = "안녕하세요";
System.out.println(name1.charAt(0));
System.out.println(name1.charAt(1));
System.out.println(name1.charAt(2));
System.out.println(name1.charAt(3));
System.out.println(name1.charAt(4));
}

2. 문자열 대체
public static void referenceSample3() {
System.out.println("3. 문자열 대체");
String name1 = "안녕하세요";
System.out.println(name1.replace("안녕", "hi"));
}

3. 문자열 잘라내기
public static void referenceSample4() {
System.out.println("4. 문자열 잘라내기");
String name1 = "안녕하세요";
//입력받은 자리부터 나머지
System.out.println(name1.substring(2));
//입력받은 자리부터 뒷 자리까지
System.out.println(name1.substring(2, 4));
}

4. 문자열 찾기
public static void referenceSample5() {
System.out.println("5. 문자열 찾기");
String name1 = "안녕하세요";
System.out.println(name1.indexOf("안녕")); //일치하는 단어가 있다면 0
}

5. 특정 문자를 기준으로 문자열 잘라내기
public static void referenceSample6() {
System.out.println("6. 특정 문자를 기준으로 문자열 잘라내기");
String name1 = "안녕, 하세요";
String[] reArr = name1.split(","); //기준이 되는 문자열은 생략됨
System.out.println(reArr[0]);
System.out.println(reArr[1]);
System.out.println(reArr.length);
}

1-5) 다차원 배열
public static void referenceSample7() {
//다차원 배열의 길이를 명시하여 객체 생성 = 배열에 저장되는 데이터가 없을 시
String[][] arr = new String[2][3];
arr[0][0] = "1번째 배열의 1번째 데이터";
arr[0][1] = "1번째 배열의 2번째 데이터";
arr[0][2] = "1번째 배열의 3번째 데이터";
arr[1][0] = "2번째 배열의 1번째 데이터";
arr[1][1] = "2번째 배열의 2번째 데이터";
arr[1][2] = "2번째 배열의 3번째 데이터";
System.out.println(arr[0][0]);
System.out.println(arr[0][1]);
System.out.println(arr[0][2]);
System.out.println(arr[1][0]);
System.out.println(arr[1][1]);
System.out.println(arr[1][2]);
//값 목록으로 다차원 배열 객체 생성 및 데이터 할당 = 배열에 저장되는 데이터가 있을 시
String[][] arr2 = {
{"1번째 배열의 1번째 데이터", "1번째 배열의 2번째 데이터", "1번째 배열의 3번째 데이터"},
{"2번째 배열의 1번째 데이터", "2번째 배열의 2번째 데이터", "2번째 배열의 3번째 데이터"}
};
System.out.println(arr2[0][0]);
System.out.println(arr2[0][1]);
System.out.println(arr2[0][2]);
System.out.println(arr2[1][0]);
System.out.println(arr2[1][1]);
System.out.println(arr2[1][2]);
}

* 다차원 배열을 선언해 아래의 데이터를 할당 후 반복문을 이용해 출력
id001, pw001, 관리자, 홍01, test01
id002, pw002, 관리자2, 홍02, test02
id003, pw003, 관리자3, 홍03, test03
public static void referenceSample8() {
//다차원 배열의 길이를 명시하여 객체 생성 = 배열에 저장되는 데이터가 없을 시
String[][] arr = new String[3][5];
arr[0][0] = "id001";
arr[0][1] = "pw001";
arr[0][2] = "관리자";
arr[0][3] = "홍01";
arr[0][4] = "test1";
arr[1][0] = "id002";
arr[1][1] = "pw002";
arr[1][2] = "관리자2";
arr[1][3] = "홍02";
arr[1][4] = "test2";
arr[2][0] = "id003";
arr[2][1] = "pw003";
arr[2][2] = "관리자3";
arr[2][3] = "홍03";
arr[2][4] = "test3";
for(int i = 0; i < arr.length; i++) {
for(int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}

*p201 7.주어진 배열 항목에서 최대값,최소값을 출력하는 코드를 작성 int[] arr = {1,5,3,8,2};
public static void referenceSample11() {
int[] arr = {1,5,3,8,2};
int max = arr[0];
int min = arr[0];
for (int i = 0; i < arr.length; i++) {
//최고점수
if (arr[i] > max) {
max = arr[i];
}
//최저점수
if (arr[i] < min) {
min = arr[i];
}
}
System.out.println("최고점수: " + max);
System.out.println("최저점수: " + min);
}
* p201 8. 주어진 배열 항목의 전체 합과 평균을 구해 출력하는 코드 int[][] arr = {{95,86},{83,92,96},{78,83,93,87,88}};
public static void referenceSample11() {
double sum = 0.0;
double avg = 0.0;
int cnt = 0;
int[][] arr = {
{95,86},
{83,92,96},
{78,83,93,87,88}
};
for(int i=0; i < arr.length; i++) {
for(int j=0; j < arr[i].length; j++) {
sum += arr[i][j];
}
cnt += arr[i].length;
}
avg = (double)sum / cnt;
System.out.println("합계: " + sum);
System.out.println("평균점수: " + avg);
}
* p201 9.학생점수분석프로그램
public static void referenceSample9() {
Scanner sc = new Scanner(System.in);
boolean stu = true; //프로그램 상태를 확인하는 변수
int studentNum = 0; //학생 수를 입력받는 변수
int[] scores = null; //입력받은 학생수에 따라 배열길이를 지정하기 위해 초기값(null)을 할당한 배열 선언
while(stu) {
System.out.println("------------------");
System.out.println("1.학생수 | 2. 점수입력 | 3. 점수리스트 | 4. 분석 | 5. 종료");
System.out.println("선택 > ");
int number = sc.nextInt();
if(number==1) {
System.out.println("학생수 > ");
studentNum = sc.nextInt(); //학생수 입력
scores = new int[studentNum]; //입력받은 학생수로 배열 길이 지정
}else if(number==2) {
for(int i = 0; i < studentNum; i++) { //입력받은 학생수의 길이만큼 반복
System.out.print("score[" + i + "] > ");
scores[i] = sc.nextInt(); //입력받은 학생수의 길이만큼 점수를 입력해 배열에 데이터 할당
}
}else if(number==3) {
for (int i = 0; i < studentNum; i++) { //입력받은 학생수의 길이만큼 반복
System.out.println("scores[" + i + "]> " + scores[i]);//입력받은 점수리스트 출력
}
}else if(number==4) {
if(studentNum > 0) { //학생수를 입력받았는지 검증(분석단계에서 에러가 발생할 수 있음)
int max = scores[0]; //최고점수를 구하기 위해 입력받은 점수배열의 첫 번째 값 할당
int min = scores[0]; //최저점수를 구하기 위해 입력받은 점수배열의 첫 번째 값 할당
double sum = 0.0; //평균을 구하기 위해 입력받은 점수들을 더하는 변수
double avg = 0.0; //평균값이 계산될 때 담을 수 있는 변수 선언
for (int i = 0; i < studentNum; i++) {
if (scores[i] > max) { //최고점수
max = scores[i];
}
if (scores[i] < min) { //최저점수
min = scores[i];
}
sum += scores[i]; //평균점수를 내기 위해 총 점수 더하기
}
avg = sum / studentNum; //평균점수
System.out.println("최고점수: " + max);
System.out.println("최저점수: " + min);
System.out.println("평균점수: " + avg);
}else{
System.out.println("학생수를 입력해주세요.");
}
}else if(number==5) {
stu = false;
}
}
System.out.println("프로그램 종료");
}

1-6) 배열 복사
1. 얕은 복사
- 배열을 그대로 복사하지만 메모리 값이 동일하다.
- 새로 담은 배열에서 데이터 수정 시 원본배열의 데이터도 변경된다.
- 주로 데이터의 수정이 이뤄지지 않고 데이터만 다른 사람들하고 공유할 때 사용된다.
2. 깊은 복사(권장하는 방법)
- 배열을 그대로 복사하지만 메모리 값이 동일하지 않다.
- 새로 담은 배열에서 데이터 수정 시 원본배열의 데이터도 변경되지 않는다
- 다른 사람의 코드에 영향을 미치지 않기 때문에 얼마든지 기능 구현이 가능하다.
- arraycopy()
public static void referenceSample13() {
String[] oldArr = new String[2];
oldArr[0] = "안녕1";
oldArr[1] = "안녕2";
String[] newArr = new String[5];
System.arraycopy(oldArr, 0, newArr, 0, 2);
// System.arraycopy(원본배열, 원본배열 복사 시작 인덱스, 새 배열, 새 배열 붙여넣기 시작 인덱스, 복사 항목 수);
System.out.println(newArr[0]);
System.out.println(newArr[1]);
System.out.println(newArr[2]);
System.out.println(newArr[3]);
System.out.println(newArr[4]);
}

1-7) 배열 for문
public static void referenceSample14() {
String[] arr = {"하이1", "하이2", "하이3", "하이4", "하이5", "하이6"};
/*
for(int i=0; i < arr.length; i++) {
if(arr[i].equals("하이3")) {
arr[i] = "변경";
}
System.out.println(arr[i]);
}
*/
for(String newArr : arr) {
if(newArr.equals("하이3")) {
newArr = "변경";
}
System.out.println(newArr);
}
}

1-8) 열거(enum) 타입
public enum Week{
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURDAY, FRIDAY, STATURDAY
}
public static void referenceSample15() {
Week today = null;
Calendar cal = Calendar.getInstance();
//System.out.println(cal);
int week = cal.get(Calendar.DAY_OF_WEEK);
System.out.println(week);
switch(week) {
case 1:
today = Week.SUNDAY;
break;
case 2:
today = Week.MONDAY;
break;
case 3:
today = Week.TUESDAY;
break;
case 4:
today = Week.WEDNESDAY;
break;
case 5:
today = Week.THURDAY;
break;
case 6:
today = Week.FRIDAY;
break;
case 7:
today = Week.STATURDAY;
break;
}
if(today == Week.SUNDAY) {
System.out.println("휴식");
}else {
System.out.println("공부");
}
}

'JAVA, JSP' 카테고리의 다른 글
| java - 클래스(리턴데이터타입, 오버로딩, 정적, final, gatter, setter), import문 자동 추가 단축키 (0) | 2024.08.08 |
|---|---|
| java 6장- 객체지향프로그래밍 (0) | 2024.08.01 |
| java - 반복문 (0) | 2024.07.25 |
| java - 논리연산자, 대입연산자, 삼항연산자 (0) | 2024.07.18 |
| JDBC(Java data base connectivity) 프로그램 순서 7단계 (0) | 2024.07.18 |