참조 타입과 참조 변수

 

기본 타입과 참조 타입

기본 타입 변수와 참조 타입 변수의 차이점은 저장되는 값이 무엇인지에 따라 결정

기본 타입은 실제 값을 변수에 저장, 참조타입은 메모리의 번지를 변수에 저장

 

메모리 사용 영역

 

메소드 영역

JVM이 시작할 때 생성, 모든 스레드가 공유하는 영역

메소드 영역에는 코드에서 사용되는 클래스(~class)들을 클래스 로더로 읽어 클래스별로

정적 필드(static field)와 상수(constant), 메소드 코드, 생성자 코드 등을 분류해서 저장

힙 영역

객체와 배열이 생성되는 영역, 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의

필드에서 참조, 만일 참조하는 변수나 필드가 없다면 의미 없는 객체가되기 때문에 JVM에서

가비지컬렉터를 실행시켜 자동으로 제거, 개발자는 객체를 제거하기 위해 별도 코드 작성 X 

 

JVM 스택 영역

JVM 스택은 메소드를 호출할 때마다 프레임을 추가(PUSH)하고

메소드가 종료되며 해당 프레임을 제거(POP) 

 

참조 변수의 ==. != 연산

참조 타입 변수의 값은 힙 영역의 객체 주소이므로 ==, != 연산은 결국 번지 값을 비교하는 것

동일한 번지 값을 갖고 있다면 동일한 객체를 참조하는 것 

 

refVar1 == refVar2 // false
refVar1 != refVar2 // true

refVar2 == refVar3 // true
refVar2 != refVar3 // false

 

==, != 연산자로 객체를 비교하는 코드는 일반적으로 if문에서 많이 사용

변수 refVar2와 refVar3이 같은 객체를 참조할 경우 if블록을 실행하도록 코딩한 것

if ( refVar2 == refVar3 ) {....}

 

 

null과 NullPointerException

참조 타입 변수는 힙 영역의 객체를 참조하지 않는다는 뜻으로 null 값을 가질 수 있음

null 값도 초기값으로 사용할 수 있기 때문에 null로 초기화된 참조 변수는 스택 영역에 생성

참조 타입 변수가 null 값을 가지는지 확인하려면 ==, =! 연산 수행

refVar1 == null // false
refVar1 != null // true

// null값 가진 refVar2
refVar2 == null // true
refVar2 != null // false

 

 참조변수가 null을 가지고 있을 경우, 참조 객체가 없으므로 변수를 통해 객체를 사용할 수 없음

만약 null 상태에서 있지도 않은 객체의 데이터(필드)나 메소드를 사용하는 코드를 실행하면

NullPointerException 발생

int[] intArray = null;
intArray[0] = 10; // NullPointerException 에러

위 코드에서 intArray는 배열 변수이므로 참조 변수, null로 초기화 가능

하지만 이상태에서 intArray[0]에 10을 저장하려고하면 NullPointerException 발생

intArray 변수가 참조하는 배열 객체가 없기 때문에

 

String str = null;
System.out.println("총 문자수:" + str.length());//NullPointerException 에러

String은 클래스이므로 참조 타입, str 변수도 null로 초기화할 수 있음

String 객체의 length()라는 메소드를 호출하면 NullPointerException 발생

이유는 str 변수가 참조하는 String 객체가 없기 때문에

 

 

String 타입

자바는 문자열을 String 변수에 저장하기 때문에 다음과 같이 String 변수를 우선 선언

String 변수;

 

String 변수에 문자열을 저장하려면 큰따옴표로 감싼 문자열 리터럴을 대입

변수 선언과 동시에 문자열을 저장할 수도 있음

String name;
name = "김가네";
String hobby = "자바";

 

자바는 문자열 리터럴이 동일하다면 String 객체를 공유하도록 되어 있음

다음과 같이 name1과 name2 변수가 동일한 문자열 리터럴인 "신용권"을 참조할 경우

name1과 name2는 동일한 String 객체를 참조하게 됨

String name1 = "신용권";
String name2 = "신용권";

 

일반적으로 변수에 문자열을 저장할 경우에는 문자열 리터럴을 사용하지만

new 연산자를 사용해서 직접 String 객체를 생성시킬 수도 있음

new 연산자는 힙 영역에 새로운 객체를 만들 때 사용하는 연산자로 "객체 생성 연산자"라고 함

 

String name1 = new String("신용권");
String name2 = new String("신용권");

위 코드의 경우 name1과 name2는 서로 다른 String 객체를 참조

 

동일한 문자열 리터럴로 String 객체를 생성했을 경우 == 연산의 결과는 true가 나오지만

new 연산자로 String 객체를 생성했을 경우 == 연산의 결과는 false

( == 연사자는 변수에 저장된 객체의 번지가 동일한지를 검사하기 때문에 ) 

String name1 = "신용권";
String name2 = "신용권";
String name3 = new String("신용권");

name1 == name2; // true
name1 == name3; // false

 

내부 문자열을 비교하고 싶을 때에는 String객체의 equals() 메소드를 사용 

equals() 메소드는 원본 문자열과 매개값으로 주어진 비교 문자열이 동일한지 비교

한 후 true 또는 false를 리턴

boolean result = str1.equals(str2);
// str1 = 원본 문자열
// str2 = 비교 문자열

 

String 변수는 참조 타입이므로 초기값으로 null을 대입할 수 있는데

이때 null은 String 변수가 참조하는 String 객체가 없다는 뜻

String hobby = null;

 

다음 코드처럼 hobby 변수가 String 객체를 참조하였으나 null을 대입함으로써 더 이상

String객체를 참조하지 않도록 할 수도 있습니다.

String hobby = "여행";
hobby = null;

 

 

 

 

배열

배열이란?

배열은 같은 타입의 데이터를 연속된 공간에 나열, 각 데이터에 "인덱스"를 부여해놓은

자료구조, 밑에 사진은 학생들의 성적을 score 배열로 생성한 것

 

score 배열의 각 인덱스는 각 항목의 데이터를 읽거나 저장하는데 사용되며

배열 이름옆에 대괄호 [ ]에 기입, 인덱스는 0부터 시작

scre[인덱스];

 

성적을 배열로 만들면 성적의 평균값은 배열의 인덱스를 이용해서 for문으로 쉽게 구할수있음

int sum = 0;
for(int i=0; i<30; i++) {
    sum += score[i];
}
int avg = sum / 30;

for문이 30번 반복 실행하면서 i가 0~29 까지 변하고 있음

sum 변수에는 score[0]~score[29]까지 더해지고, 마지막으로 얻은 sum을 30으로 나누어

평균 avg를 얻음

학생 수가 30명이 아니라 수백 명이 되어도 for문의 조건식 i<30만 변경하면 되므로 

많은 양의 데이터를 적은 코드로 손쉽게 처리 가능

 

배열은 같은 타입의 데이터만 저장 가능하며 선언과 동시에 저장할 수 있는 타입이 결정

한 번 생성된 배열은 길이를 늘리거나 줄일 수 없음

 

배열 선언

배열을 사용하기 위해서는 우선 배열 변수를 선언해야 함 선언은 두 가지 형식으로 가능

//1번
타입[] 변수;

//2번
타입 변수[];
// 형식 1
int[] intArray;
double[] doubleArray;
String[] strArray;

//형식 2
int intArray[];
double doubleArray[];
String strArray[];

배열 변수는 참조 변수에 속합니다. 배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의

배열 객체를 참조하게 됨

참조할 배열 객체가 없다면 배열 변수는 null 값으로 초기화될 수 있음

 

 

배열 생성

배열 객체를 생성하려면 값 목록을 이용하거나 new 연산자를 이용하는 방법이 있음

값 목록으로 배열 생성

값의 목록이 있다면 다음과 같이 간단하게 배열 객체를 생성할 수 있음

타입[] 변수 = { 값0, 값1, 값2, 값3, … };

String[ ] names = { “신용권”, “홍길동”, “감자바” };

이렇게 생성된 배열에서 “신용권”는 names[0], “홍길동”은 names[1],

“감자바”는 names[2]로 읽을 수 있음

names[1] = “홍삼원”;

names[1]의 “홍길동”을 “홍삼원”으로 바꾸고 싶다면 위와 같이 대입 연산자를 사용

 

 

값의 목록으로 배열 객체를 생성할 때 주의할 점

배열 변수를 이미 선언한 후에는 다른 실행문에서 중괄호를 사용한 배열 생성이 허용되지 않음

타입[] 변수;
변수 = { 값0, 값1, 값2, 값3, … }; ← 컴파일 에러

 

 

배열 변수를 미리 선언한 후 값 목록들이 나중에 결정되는 상황이라면

다음과 같이 new 연산자를 사용해서 값 목록을 지정

new 연산자 바로 뒤에는 배열 변수 선언에서 사용한 “타입[ ]”를 붙여주고 중괄호 { }에는 값들을 나열

변수 = new 타입[] { 값0, 값1, 값2, 값3, … };

배열 names를 다음과 같이 생성할 수 있음

String[] names = null;
names = new String[] { “혼공자”, “혼공족장”, “자바맨” };

 

 

 

메소드의 매개값이 배열일 경우에도 마찬가지

int add(int[] scores) { … }

int result = add( {95, 85, 90} ); // 컴파일 에러
int result = add( new int[] {95, 85, 90} );

 

 

 

new 연산자로 배열 생성

값의 목록을 가지고 있지 않지만, 향후 값들을 저장할 배열을 미리 만들고 싶다면

new 연산자로 다음과 같이 배열 객체를 생성

타입[] 변수 = new 타입[길이];

 

이미 배열 변수가 선언된 경우에도 new 연산자로 배열을 생성할 수 있음

타입[] 변수 = null;
변수 = new 타입[길이];

 

다음은 길이가 5인 int[ ] 배열을 생성

int[] intArray = new int[5];

 

scores 배열은 int 배열이므로 다음과 같이 scores[0] ~ scores[29]까지 모두 기본값 0으로 초기화

int[] scores = new int[30];

 

tring 배열을 생성했다면 names 배열의 경우 names[0] ~ names[29]까지 모두 null 값으로 초기화

String[] names = new String[30];

 

 

배열이 생성되고 나서 특정 인덱스 위치에 새로운 값을 저장하려면 다음과 같이 대입 연산자를 사용

변수[인덱스] = 값;

 

배열 scores의 0, 1, 2 인덱스에 각각 83, 90, 75를 저장하는 코드

int[] scores = new int[3];
scores[0] = 83;
scores[1] = 90;
scores[2] = 75;

 

 

 

배열 길이

배열의 길이란 배열에 저장할 수 있는 전체 항목의 개수

배열의 길이를 얻으려면 다음과 같이 배열 객체의 length 필드를 읽음 

( 필드는 객체 내부의 데이터를 뜻함 ) 

 

배열 변수.length;

 

intArray가 3개의 값을 가지고 있기 때문에 변수 num에는 3이 저장

int[] intArray = {10, 20, 30};
int num = intArray.length;

 

 

 

실습

 

짝수 구하기

package sec01.exam01;

import java.util.Iterator;

public class BreakContinu {
	public static void main(String[] args) {
		// 짝수 구하기
		for(int i=1; i<=10; i++) {
			if (i%2 != 0) {
				continue;
			}
			System.out.println(i);
		}
		
	}

}

 

do-while

package sec01.exam01;

public class DoWhile {

	public static void main(String[] args) {
		int i = 0;
		int j = 1;
		
		while (j < 3) {
			System.out.println(j);
			j++;
		}
		
		do {
			
			System.out.println(i);
			i++;
		}while (i > 3); // 조건에 안맞아도 1번은 실행

	}

}

 

참조변수 / 참조변수 비교, 문자열 비교

package sec01.exam01;

public class TestEx {

	public static void main(String[] args) {
		
		//참조변수
//		int[] scores = {10, 20, 30};
//		scores[0] = 20;
//		System.out.println(scores[0]);
//		for( int i = 0; i < 3; i++) {
//			if (scores[i] != 10)
//			System.out.println(scores[i]);
//			
//		}
		String name1 = "홍길동";
		String name2 = "홍길동";
		String name3 = new String("홍길동");
		String name4 = new String("홍길동");
		
		if (name3 == name4) {// 참조변수 비교
			System.out.println("같다");
		}else {
			System.out.println("다르다");
		}
		if (name3.equals(name4)) {// 문자열 비교 
			System.out.println("같다");
		}else {
			System.out.println("다르다");
		}
		
		
	}

}

 

배열 타입별

package sec02.exam01;

public class ArrayEx {

	public static void main(String[] args) {
		// 배열
//		int acores[] = {1,2,3,4};
//		int[] acores = new int[3];
//		for (int i=0; i < 3; i++) {
//			System.out.println(acores[i]);
//		0
//		0
//		0
//		}
		
//		String[] acores = new String[3];
//		for (int i=0; i < 3; i++) {
//			System.out.println(acores[i]);
//			null
//			null
//			null
//		}
//		double[] acores = new double[3];
//		for (int i=0; i < 3; i++) {
//			System.out.println(acores[i]);
//			0.0
//			0.0
//			0.0
//		}
		char[] acores = new char[3];
		for (int i=0; i < 3; i++) {
			System.out.println(acores[i]);
		
		}
	}

}

 

참조형 배열 메서드

package sec02.exam01;

public class ArrayEx03 {

	//참조형 배열 메서드
	public static void main(String[] args) {
		int[] scores = {70, 80, 90, 60};
		int sum = method(scores);
		for (int i=0; i < scores.length; i++) {
			System.out.println(scores[i]);
		}
		System.out.println("총점:" + sum);

	}
	public static int method(int[] nums) {
		int sum = 0;
		for (int i=0; i<nums.length; i++) {
			nums[i] += 10; 
			sum += nums[i];
			
		}
		return sum;
	}
}

 

배열 이름, 전화번호, 주소 저장

package sec02.exam01;

public class ArrayEx2 {

	public static void main(String[] args) {
		int[] score = {1,2,3,4};
		int[] socres = new int[4];
		socres[0] = 1;
		socres[1] = 2;
		socres[2] = 3;
		socres[3] = 4;
		
		String[] header = {"성명", "전화번호", "주소"};
		String[] content = new String[3];
		content[0] = "홍길동";
		content[1] = "010-1234-2345";
		content[2] = "서울 서대문구";
		
		for (int i=0; i<3; i++) {
			System.out.print(header[i]+"\t");
		}
		System.out.println();
		
		for (int i=0; i<3; i++) {
			System.out.print(content[i]+"\t");
		}
		System.out.println();
		
		
	}

}

 

배열 두 수의 합

package sec02.exam01;

import java.lang.reflect.Method;
import java.util.jar.Attributes.Name;

public class ArrayExTotall {

	public static void main(String[] args) {
		int sum = add(3, 5);


		
	}
	public static int add(int a, int b) {
		int sum = a+b;
		System.out.println("두 수의 합은" + sum + "입니다.");
		return sum;

		
} 
	}

 

배열 1부터 100까지 합계

package sec02.exam01;

public class ArrayMethodEx {

	public static void main(String[] args) {
//		aaa(100); // 호출 // c = 100
//		int num = bbb(); // int -> double로 바꿀시 double로 출력
//		System.out.println("main()" + num);
		sum(100);// ccc(100); -> ccc(i <= n)
		
		int num = 100;
//		int tot = sum(num);
		sum(num);
		System.out.println("1부터 "+num+"까지의 합계:");

	}
//	public static void aaa(int c) { // int = c 매개변수
//		System.out.println("aaa()");
//	}
//	public static int bbb() {
//		System.out.println("bbb()");
//		return 100; // 14줄 int type만 return 가능
//	}
	
	public static void sum(int n) { 
		int sum = 0;
		for (int i=1; i <= n; i++) {
			sum += i;
		}
		System.out.println("1부터 "+n+"까지의 합계:" + sum);
		
	}
		
}

 

maing( ) 메소드의 매개 변수 1, 2 번째 데이터 받기

package sec02.exam01;

public class ArreayEx04Main {

	public static void main(String[] args) {
		//main() 메소드의 매개 변수
		if(args.length != 2) {
			System.out.println("값의 수가 부족합니다.");
			System.exit(0); // 프로그램 강제 종료
		}
		String strNum1 = args[0];//첫번째 데이터 받기
		String strNum2 = args[1];//두번째 데이터 받기
		
		int num1 = Integer.parseInt(strNum1);//문자열을 정수로 변환
		int num2 = Integer.parseInt(strNum2);
		
		int result = num1 + num2;
		System.out.println(num1 + " + " + num2 +" = " + result);
	}

}

 

JSP 자바스크립트 Login

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="res.jsp" onsubmit="return checkForWhiteSpace()">
	<h1>로그인 하기</h1>
<a> 아이디 : </a><input type="text" name="kor" id="kor" oninput="validateInput()" /> 
		<div></div>
<a> 패스워드 :</a>		<input type="password" name="eng" id="eng" /> 
		<input type="submit" value="확인" />
		<script>
			function checkForWhiteSpace() {
				var kor = document.getElementById("kor").value; // "kor" id값
				var eng = document.getElementById("eng").value; // "eng" id값
				if (kor.trim() == "") {
					alert("공백은 입력할 수 없습니다.");
					return false;
				}
				if (eng.trim() == "") {
					alert("공백은 입력할 수 없습니다.");
					return false;
				}
				return true;
			}
			function validateInput() {
				  var input = document.getElementById("kor").value;
				  var pattern = /^[a-zA-Z0-9!@#$%^&*()]*$/; // 영문자, 숫자, 특수 기호만 허용하는 정규표현식
				  
				  if (!pattern.test(input)) {
					  document.getElementById("kor").value = input;
				    alert("영문자, 숫자, 특수 기호만 입력해주세요.");
				  }
				}
		</script>
	</form>
</body>
</html>

 

JSP 자바스크립트 Login 값 넘기는 곳

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=request.getParameter("kor") %>
<%=request.getParameter("eng") %>
</body>
</html>

 

JSP 자바스크립트 css 파일

h1 {
  color : blue;
}

h2 {
  color : green;
}

p {
  margin-left: 10px;
}

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-05-25 8일차  (0) 2023.05.25
2023-05-24 7일차  (2) 2023.05.24
2023-05-22 5일차  (0) 2023.05.22
2023-05-19 4일차  (0) 2023.05.19
2023-05-18 3일차  (0) 2023.05.18

+ Recent posts