본문 바로가기

자바스프링웹공부(2024)/자바

204.09.03.비정형인자. 기본형변수와 참조형변수. 패키지

반응형

* 비정형인자(=가변인자 , Variable Arguments)

- 메서드 파라미터 갯수가 정해져 있지 않을 때  다양한 갯수의 파라미터를 모두 전달받을 수 있는 인자.
- 메서드 정의 시 매개변수 데이터타입과 변수명  사이에 ... 기호를 붙여서 표기
- 전달되는 모든데이터는 해당 변수명으로 된 "배열"로 관리디며 0개 이상의 파라미터를 전달할 수 있음
- 메서드 정의 시 가변 인자 타입으로 매개변수를 선언하면  갯수 제한 업이 0개부터 무한대의 파라미터를 한꺼번에 전달 받을 수 있다.   
- 가변인자 사용시 주의사항!! 가변인자는 꼭 마지막 파라미터로 사용되어야 한다. 

가변인자는 단 한번만 사용가능. 둘중에 하나만 선택해서 사용하여야 한다.( = 마지막 파라미터로 사용되어야 한다는 사유에 포함됨.)

class VariableArguments {

public void print(int... nums) {
    System.out.println("print(int...nums) 호출됨.");
    for(int i = 0; i < nums.length; i++) {
	    Systehttp://m.out.print(nums[i] + " ");
    }
}
	// public void print(int...nums, String... str) {  // 가변인자는 여러개 사용할 수 없다.
	// public void print(int...nums, String str) { // 가변인자는 이 메서드의 마지막 파라미터로 사용되어야 한다. 
	public void print(String str, int...nums) { // (O)
	//  복수개의 매개변수 선언 시 가변 인자가 마지막에 사용되면 오류가 발생하지 않음.
    
------------
// ... 메인메서드 안에서 호출하기
VariableArguments va = new VariableArguments();
va.print(1,2,3,4,5,6);
va.print(1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6);
//va.print(1,2,"abc");// 타입에러.
va.print(arr); // 배열 전달 가능.
va.print(); // 심지어 파라미터 없이도 메서드 호출 가능

 

Q. 오늘의 문제 

package method;
/*
계산기 (Calculator) 클래스 정의
덧셈, 뺄셈, 곱셈, 나눗셈 기능을 모두 calc() 메서드로 처리
=> 첫번째 파라미터는 연산자(기호, char타입 opr)를 전달하고
	두번째 파라미터부터 피연산자(숫자, int 타입 numX)을 전달하고 2개이상 전달하여
	연산자에 따라 각각의 연산을 누적하여 결과 출력
*/

class Calculator2 {
	// 부호없이 결과(total)만 나오는 메서드
	public void calc (char opr, int... nums) {
		int total = nums[0];
		for(int i = 1; i < nums.length; i++) {
			switch (opr) {
				case '+': total += nums[i]; break;
				case '-': total -= nums[i];	break;
				case '*': total *= nums[i]; break;
				case '/': total /= nums[i]; break;
			}
		}
		makeStr(opr, nums);
		
		System.out.println(total);
	} // calc() 메서드 끝	
	
	// 부호 붙이는 메서드
	public void makeStr(char opr, int... nums) {
		String str = nums[0] + "";
		for(int i = 1; i < nums.length; i++) {
			str += " " + opr + " " + nums[i];
		}
		System.out.print(str + " = " );
	}
		
		/*
		int total = nums[0];
		System.out.print(total);
//		System.out.print(nums[0]);
//		String buho = nums[0] + "";
		for(int i = 1; i < nums.length; i++) {
			System.out.print(" " + opr + " " + nums[i]);
			switch (opr) {
				case '+':
//					buho += " + " + nums[i];
					total += nums[i];
					break;
				case '-':
//					buho += " - " + nums[i] ;
					total -= nums[i];
					break;
				case '*':
//					buho += " * " + nums[i] ;
					total *= nums[i];
					break;
				case '/':
//					buho += " / " + nums[i] ;
					total /= nums[i];
					break;
				default:
					break;
			}
		}
		System.out.println(" = "+total);
		*/
		/*
		if(opr == '+') {
			for(int i = 1; i < nums.length; i++) {
				buho += " + " + nums[i];
				total += nums[i];
			}
			System.out.println(buho+" = "+total);
		} else if (opr == '-') {
			for(int i = 1; i < nums.length; i++) {
				buho += " - " + nums[i] ;
				total -= nums[i];
			}
			System.out.println(buho+" = "+total);
		} else if (opr == '*') {
			for(int i = 1; i < nums.length; i++) {
				buho += " * " + nums[i] ;
				total *= nums[i];
			}
			System.out.println(buho+" = "+total);
		} else if (opr == '/') {
			for(int i = 1; i < nums.length; i++) {
				buho += " / " + nums[i] ;
				total /= nums[i];
				System.out.println(buho+" = "+total);
			}
		}
		-------------
		class Calculator2 {
	public void calc (char opr, int... nums) {
		int total = 0;
		if(opr == '+') {
			String buho = " + "; 
			for(int i = 0; i < nums.length; i++) {
				total += nums[i];
				if(i == nums.length-1) {
					buho = " = " + total;
				}
				System.out.print(nums[i] + buho);
			}
			System.out.println();
		} else if (opr == '-') {
			String buho = " - "; 
			for(int i = 0; i < nums.length; i++) {
				if(i == 0) {
					total = nums[0];
				} else {
					total -= nums[i];
				}
				if(i == nums.length-1) {
					buho = " = " + total;
				}
				System.out.print(nums[i] + buho);
			}
			System.out.println();
			
		} else if (opr == '*') {
			total = 1;
			String buho = " * "; 
			for(int i = 0; i < nums.length; i++) {
				total *= nums[i];
				if(i == nums.length-1) {
					buho = " = " + total;
				}
				System.out.print(nums[i] + buho);
			}
			System.out.println();
		} else if (opr == '/') {
		}
	}
}
		*/
}

public class Test2 {

	public static void main(String[] args) {
		Calculator2 cal = new Calculator2();
//		cal.makeStr('+', 10 , 20, 30);
		cal.calc('+', 10, 20, 30);		// 10 + 20 + 30 = 60
		
		/* 메서드 나누기 전
		Calculator2 cal = new Calculator2();
		cal.calc('+', 10, 20);			// 10 + 20 = 30
		cal.calc('+', 10, 20, 30, 40);	// 10 + 20 + 30 + 40 = 100
		
		cal.calc('-', 100, 10);
		cal.calc('-', 100, 10, 20);
		cal.calc('-', 100, 10, 20, 30);
		
		cal.calc('*', 1, 2);
		cal.calc('*', 1, 2, 3);
		*/
	}
}

*기본형 (Primitive Type) 변수와 참조형 (Reference Type) 변수의 차이

- 기본형 변수는 실제값(리터럴)을 저장하며,
  참조형 변수는 실제값이 저장된 인스턴스의 주소값(참조값 = 레퍼런스)을 저장
- 기본형 변수와 참조형변수의 값을 복사(전달)할 때 차이점
  1. 기본형 변수의 값을 복사할 경우
  - 변수에 저장된 실제 값을 복사(전달) = Pass by value
  - 실제 값을 복사하게 되면 원본 값과 동일한 값이 별도로 생성되어 전달되므로 복사된 값을 변경하더라도 원본 값과 상관없기 때문에 원본 값은 변경되지 않는다. 
 2. 참조형 변수의 값을 복사할 경우
  - 변수에 저장된 인스턴스 주소값을 복사(전달) = Pass by reference
  - 주소 값을 복사하게 되면 원본 값에 저장된 주소와 동일한 주소가 전달되므로 실제 인스턴스 하나를 함꼐 공유하게 된다. 따라서 한쪽에서 인스턴스에 접근하여 저장된 값을 변경할 경우 동일한 주소값을 참조하는 쪽에도 영향을 받게 된다. 
  => 즉, 한쪽에서 값을 변경하면 다른쪽의 값도 함꼐 변경된 효과를 갖는다. 

public class Ex1 {
	public static void main(String[] args) {
		int x = 10;
		int y = x;
		System.out.println(x+y);
		
		y = 99;
		System.out.println(x+y);
		//=> 기본형 변수 y의 값을 변경하더라도 원본데이터 기본형 변수 x의 값은 변경되지 않음.
		Num n = new Num();
		n.x = 10;
		n.y = n.x;
		
		n.y = 99;
		System.out.println(n.x + n.y); // 클래스라도 안에 기본데이터 타입이니까 결과는 위와 같다.
		// => Num 클래스의 인스턴스 내에 있는 기본형 변수 Y의 값을 변경하더라도 원본 데이터 기본형 변수 x의 값은 변경되지 않음.
		System.out.println("-------------------------------------------");
		
		Num n2 = new Num();
		n2.x = 10;
		n2.y = 10;
		
		Num n3 = n2; // Num 타입 참조형 변수 n3에 참조형 변수 n2 의 값 복사(=주소값 복사)
		// => 참조형 변수 n2가 가리키는 인스턴스 주소값을 n3에 복사(전달) 했으므로 n2와 n3가 가리키는 (참조하는)인스턴스가 동일함.
		System.out.println(n2.x + n2.y);
		System.out.println(n3.x + n3.y);
		
		// 참조형변수 n3의 인스턴스 내의 변수 y값을 99로 변경
		n3.y = 99; // 복사된 참조변수 값(인스턴스주소)에 접근하여 인스턴스 변수값 변경 //new 는 한번만 해서 사람이 한명이다. 그래서 n2.y && n3.y = 99
		System.out.println(n2.x + n2.y);
		System.out.println(n3.x + n3.y);
		// => n2, n3 모두 하나의 인스턴스를 참조하고 있으므로 한쪽에서 인스턴스 내의 변수 값으 변경하면 다른쪽의 인스턴스도 동일하므로 똑같이 변경된 사항이 적용됨.
		System.out.println("-------------------------------------------");
		PassValue pv = new PassValue();
		
		int xNum = 10;
		System.out.println("메서드 호출 전 x: " + xNum);
		pv.changeValue(xNum);
		System.out.println("메서드 호출 후 x: " + xNum);
		System.out.println("-------------------------------------------");
		
		Num num = new Num();
		num.x = 10;
		System.out.println("메서드 호출 전 x: " + num.x);
		pv.changeReferenceValu(num);
		System.out.println("메서드 호출 후 x: " + num.x);
	}
}

class PassValue {
	public void changeReferenceValu(Num num) {
		System.out.println("메서드 변경 전 x: " + num.x);
		num.x=999;
		System.out.println("메서드 변경 후 x: " + num.x);
	}
	public void changeValue (int x) {
		System.out.println("메서드 변경 전 x: " + x);
		x=999;
		System.out.println("메서드 변경 후 x: " + x);
	}
	
}
class Num {
	int x;
	int y;
}

 


* 패키지(Package)

- 윈도우에서의 폴더(Folder), 리눅스에서의 디렉토리(Directory)에 해당하는 개념
- 자바에서 클래스 파일들을 모아놓는 공간(물리적으로 폴더와 동일)
  => 서로다른 패키지에는 같은 이름의 클래스가 각각 존재할 수 있다. (=중복가능)
  (단, 하나의 패키지에는 같은 이름의 클래스가 중복될 수 없다.)
- 자바에서 패키지를 생성하면, 실제 물리적인 폴더가 생성됨.
  (만약, 패키지 생성 생략시, 물리적 폴더가 없는 default package가 생성됨.)
- 특정 클래스 파일은 하나의 패키지에만 소속되어야 함. 
- 원칙적으로 클래스에 접근하는 방법은 패키지명과 클래스 명을 동시에 지정하여 접근
  => '패키지명.클래스명'  형태로 지정
  => 만약, 패키지에 계층구조로 이루어져 있을 경우에는   '상위패키지명.하위패키지명.클래스명' 형태로 지정
  => 단, java.lang 패키지는 기본적으로 포함되는 유일한 패키지 이므로 java.lang 패키지 내의 클래스는 클래스명만으로 접근가능
- 실제 폴더 구조처럼 상위, 하위로 구분하여 패키지를 작성하며 이때, 패키지의 이름이 중복될 수 있으므로 도메인네임을 사용하여 패키지명을 지정
  google.co.kr  => kr.co.google. 
  naver.co.kr => kr.co.naver
  => 단, 도메인 네임을 역순으로 지정하여 포괄적인 이름이 상위패키지명이 되도록 함.

* package문 (키워드)
- 특정클래스 파일의 처번째 라인에 해당 클래스가 소속된 패키지를 명시하는데 사용
  => 주석을 제외한 소스코드에서 가장 먼저 실행되어야하는 코드(맨윗줄에 위치) - import문도 패키지문 밑에 있어야 함.
- 실제 클래스 파일이 위치한 패키지와 지정된 위치가 다를 경우 오류 발생.
- 클래스 파일 내에서 단 한번만 사용가능
- default package에 위치한 클래스는 실제 패키지가 없으므로 package문 생략함.

반응형

'자바스프링웹공부(2024) > 자바' 카테고리의 다른 글

2024.09.09.조건문 반복문 연습  (0) 2024.09.09
2024.09.05.import, static  (1) 2024.09.08
2024.08.27. 생성자, this  (0) 2024.08.27
2024.08.26.클래스, 인스턴스  (0) 2024.08.26
2024.08.12. 메서드  (0) 2024.08.17