클래스에서의 변수선언 : 전역변수

메소드에서의 변수선언 : 지역변수

 

 

 

클래스에서의 변수

 

변수의 종류

클래스에서의 변수는 아래와 같이 구분한다.

  • 1. 클래스 변수 : static 키워드를 가지고 필드에 선언하는 변수, 메모리의 static영역 사용
  • 2. 멤버 변수(인스턴스 변수) : static 키워드 없이 필드에 선언하는 변수, 메모리의 heap영역 사용
  • 3. 지역 변수 : 메소드, 생성자, 초기화 블록 내부에서 선언하는 변수

 

  • 더이상 참조하지 않는경우 가비지 콜렉터(GC)가 변수를 지워준다.

 

 

class KindsOfVariable
public class KindsOgVariable {

	/* 클래스 영역에 작성하는 변수를 필드라고 한다. */
	
	/* 필드 
	 * == 멤버변수 (클래스가 가지는 멤버라는 의미) 
	 * == 전역변수(클래스 전역에서 아용할 수 있는 변수라는 의미) 
	 * 
	 * */
	
	/* non-static field를 인스턴스 변수라고 한다. 
	 * (인스턴스 생성 시점에 사용가능한 변수라는 의미) */
	private int globalNum;
	
	
	/* static field 를 정적필드(클래스변수)라고 한다. 
	 * (정적 영역에 생성되는 변수라는 의미) 
	 * */
	private static int staticNum;
	
	
	
	public void testMethod(int num) {	// 메소드 영역의 시작
		
		/* 메소드 영역에서 작성하는 변수를 지역변수라고 한다.
		 * 메소드 괄호 안에 선언하는 변수를 매개변수라고 한다.
		 * 매개변수도 일종의 지역변수이다.
		 * 지역변수와 매개변수 모두 메소드 호출 시 stack을 할당받아 stack에 생성된다. 
		 * 호출이 종료되면 할당되었던 공간은 사라진다.
		 * */
		int localNum;
		
		
		
		
		/* 매개변수는 호출시 값이 넘어와서 변경되기 때문에 초기화가 필요없다.
		 * 그러나 지역변수는 선언외에 다시 사용하기 위해서는 반드시 초기화가 되어야 한다. */
		
		System.out.println(num);
		// System.out.println(localNum); // 컴파일 에러가 생긴다. 
		
		// he local variable localNum may not have been initialized
		// 초기화 되지않아서 오류
		// heap영역에 생성된 변수들은 알아서 초기값으로 들어가지만 
		// stack영역의 생성된 지역변수들은 반드시 선언과 동시에 초기화를 해주어야 한다.
		
		System.out.println(globalNum);
		System.out.println(staticNum);
		// 전역 변수(모든영역)
		// 전역 변수는 클래스 전역에서 사용가능하다.
		
		
	} //메소드 영역의 끝
	
	
	public void testMethod2() {
		
		//System.out.println(localNum); //testMethod 내의 지역변수
		System.out.println(globalNum);
		System.out.println(staticNum);
		
		// 지역변수는 해당지역 내에서만 사용가능하다. 지역을 벗어난다면 컴파일 오류
		// 번역 변수는 다른 메소드에서도 사용 가능하다. 
		
		
	}
	
	
	
} // 클래스 영역의 끝

class KindsOfVariable

 

 

 

 

초기화 순서

  • 인스턴스(non-static) 스태틱 키워드가 안붙어있음
  • 클래스변수(static) 스태틱 키워드가 붙음 

 

private int num = 10;
private static int num2 = 20;
클래스 변수의 경우 초기값 외의 정적 초기화, 인스턴스 초기화, 생성자를 생성하게 된다면 그 위에 값을 덮어쓰는 형태가 된다. 

 

 

Application
public class Application {

	public static void main(String[] args) {

		/* 초기화 블럭과 초기화 순서 */
		/* 초기화 블럭
		 * 복잡한 초기화를 수행할 수 있는 블럭을 제공하며, 
		 * 인스턴스 초기화 블럭과 정적초기화 블럭으로 구분된다.
		 * 
		 * 1. 인스턴스 초기화 블럭
		 *  : 인스턴스가 생성되는 시점에 생성자 호출 이전에 먼저 실행이 된다.
		 *    인스턴스를 호출하는 시점마다 호출이 된다.
		 *    인스턴스 변수를 초기화하며 정적 필드에는 실행 시점마다 값을 덮어쓴다.
		 *  
		 *  {
		 *  	초기화 내용 작성
		 *  }
		 * 
		 *  2. 정적 초기화 블럭
		 *    : 클래스가 로드 될 때마다 한번 동작한다.
		 *      정적 필드를 초기화하며, 인스턴스 변수는 초기화 하지 못한다.
		 *      
		 * static {
		 * 			초기화 내용 작성
		 * }
		 * 
		 * 
		 * 
		 *  */
		
		
		
		Product product = new Product();  // 없으므로 마우스오버하여 클래스 생성
		System.out.println(product.getInfomation());
		
//		정적 초기화 블록 동작함...
//		인스턴스 초기화 블록 동작함...
//		기본 생성자 호출함...
//		Product [name=사이언, price=900000, brand=헬지]
		
		
		Product product2 = new Product("대륙폰", 300000, "샤우미");
		System.out.println(product2.getInfomation());
		
//		인스턴스 초기화 블록 동작함...
//		매개변수 있는 생성자 호출됨...
//		Product [name=대륙폰, price=300000, brand=샤우미]
		
		

	}

}

 

 

class Product
public class Product {

	/* 필드를 초기화 하지않으면 jvm이 정한 기본 값으로 객체가 생성된다. */
//	private String name;
//	private int price;
//	private static String brand;
	
	
	/* 명시적인 초기화가 동작함, 기본값을 초기화가 덮어씀 */
	private String name = "갤럭시";
	private int price = 1000000;
	private static String brand = "삼송";
//	기본 생성자 호출함...
//	Product [name=갤럭시, price=1000000, brand=삼송]
	
	
	
	
	/* 인스턴스 초기화 블록 */
	{
		name = "사이언";
		price = 900000;  // 인스턴스 변수
		
		/* 인스턴스 초기화 블록에서는 static 필드를 초기화 할 수 있는 것처럼 보인다.
		 * 하지만 static 초기화 블록은 클래스가 로드 될 떄 이미 초기화를 진행했다. = 헬지
		 * 따라서 인스턴스 초기화 블럭이 동작하는 시점에는 이미 초기화가 진행 된 정적 필드에 = 샘송
		 * 인스턴스 초기화 블럭에서 대입한 값으로 덮어쓰게 되는 것이다. */
		
		brand ="사과";   //클래스 변수
		System.out.println("인스턴스 초기화 블록 동작함...");
		
	}
	
	
	/* static 초기화 블록 */
	static {
		/* static 초기화 블럭에서는 non-static 필드를 초기화 하지 못한다.
		* 정적 초기화 블럭은 클래스 로드시에 동작한다.
		* 따라서 정적 초기화 블럭의 동작 시점에는 인스턴스가 아무것도 존재할 수 없기 때문에,
		* 존재하지 않는 인스턴스 변수에 초기화 하는 것은 시기상으로 불가능하다.
		* 
		*/
		
	//	name = "아이뽕";
	//	price = 1000000; 
		// Cannot make a static reference to the non-static field name
		
		brand = "헬지";
		System.out.println("정적 초기화 블록 동작함...");
		// 왜 static  영역에서 name과 price를 초기화 할 수 없을까?
		// 인스턴스 변수는 객체가 만들어져서 heap영역에 메모리가 할당 됐을때 존재
		// 인스턴스가 생성된 적이 없으므로 초기화 자체가 불가능하다.
	}
	
	
	/* 실행 순서 확인 */
//	정적 초기화 블록 동작함...
//	인스턴스 초기화 블록 동작함...
//	기본 생성자 호출함...
//	Product [name=사이언, price=900000, brand=사과]
	
	
	
	
	
	public Product() {
		System.out.println("기본 생성자 호출함...");
	}
	
	
	
	public Product(String name, int price, String brand) {
		
		this.name = name;
		this.price = price;
		Product.brand = brand;
		System.out.println("매개변수 있는 생성자 호출됨...");
		
//		인스턴스 초기화 블록 동작함...
//		매개변수 있는 생성자 호출됨...
//		Product [name=대륙폰, price=300000, brand=샤우미]
	}
	
	
	
	
	
	public String getInfomation() {
		return "Product [name=" + this.name + ", price=" + this.price + ", brand=" + Product.brand + "]";
	}
	
}

 

 

 

 

 

 

 

 

 

객체배열

 

 

 

 

 

 

객체배열이란?

  • 레퍼런스 변수(주소값이 담김)에 대한 배열
  • 동일한 타입의 여러 인스턴스들을 배열로 관리할 수 있다.

 

 

 

 

 

1. 선언
클래스명[ ] 배열명;
클래스명 배열명[ ];

 

2. 할당
배열명 = new 클래스명[배열크기];

(new 연산자를 써야지만 힙 영역에 할당)

 

 

3. 선언과 동시에 할당
클래스명 배열명[ ] = new 클래스명[배열크기]

 

  • 힙 영역에 객체를 참조할 변수만 생성이 된 상태이다. 
  • 즉, 해당객체가 만들어진게 아니라 그 객체를 모아서 참조할 수 있는 참조변수가 만들어진 상태

 

 

 

 

 

객체배열 선언과 할당

 

인덱스를 이용한 초기화
배열명[ i ] = new 클래스명( );

 

 

선언과 동시에 할당 및 초기화
클래스명 배열명[ ] = {new 클래스명(), new 클래스명()};

 

 

 

 

 

객체배열 저장구조
Example arr[ ] = new Example[2];
  arr[0] = new Example( );      //0x678 주소값 참조
  arr[1] = new Example( );      //0x098 주소값 참조

 

* arr[index]이 하나의 참조형 변수라고 생각

 

 

class Application
public class Application {

	public static void main(String[] args) {

		/* 객체배열은 레퍼런스 변수에 대한 배열이다.
		 * 생성한 인스턴스도 배열을 이용해서 관리하면
		 * 동일한 타입의 여러개 인스턴스를 각각 취급하지 않고 연속 처리할 수 있어서 유용하다.
		 * 또한 반환값은 1개의 값만 반환할 수 있기 때문에
		 * 동일한 타입의 여러 인스턴스를 반환해야 하는 경우 객체배열을 이용할 수 있다. */
		
		
		/* 자동차 5대 인스턴스를 생성 후 모든 인스턴스가 최고 속도로 달리게 한다. */
		
		Car car1 = new Car("페라리", 300);
		Car car2 = new Car("람보르기니", 350);
		Car car3 = new Car("롤스로이스", 250);
		Car car4 = new Car("부가티베이론", 400);
		Car car5 = new Car("포터", 500);
		
		
		car1.driveMaxSpeed();
		car2.driveMaxSpeed();
		car3.driveMaxSpeed();
		car4.driveMaxSpeed();
		car5.driveMaxSpeed();
		
		
		
		/* 동일한 타입의 인스턴스를 여러 개 사용해야 할 때 객체배열을 이용하면
		 * 보다 효율적으로 사용이 가능하다.
		 * Car 타입의 인스턴스 주소를 보관할 5칸 짜리 배열 할당 */
		Car[] carArray = new Car[5];
		
		System.out.println(carArray);
		System.out.println(carArray[0]);
		// carArray[0]객체의 주소 : [Lcom.greedy.section01.init.Car;@3830f1c0
		// 인덱스 0의 값 : null
		
		
		
		/* 각 인덱스에는 기본값 null로 초기화 되어 있기 때문에 
		 * 인덱스별로 인스턴스를 생성해야 한다. */
		
		carArray[0] = new Car("페라리", 300);
		carArray[1] = new Car("람보르기니", 350);
		carArray[2] = new Car("롤스로이스", 250);
		carArray[3] = new Car("부가티베이론", 400);
		carArray[4] = new Car("포터", 450);
		
		
		
		/* 배열이기 때문에 반복문을 활용할 수 있다. */
		for( int i = 0; i <carArray.length; i++ ) {
			carArray[i].driveMaxSpeed();
		}
		/*
		페라리(이)가 최고시속 300km/h로 달려갑니다.
		람보르기니(이)가 최고시속 350km/h로 달려갑니다.
		롤스로이스(이)가 최고시속 250km/h로 달려갑니다.
		부가티베이론(이)가 최고시속 400km/h로 달려갑니다.
		포터(이)가 최고시속 450km/h로 달려갑니다. */
	}
	
	
	
	
	
	/* 객체 배열도 할당과 동시에 초기화 할 수 있다. */
	Car[] carArray2 = {
		new Car("페라리", 300)	
		, new Car("람보르기니", 350)
		, new Car("롤스로이스", 250)
		, new Car("부가티베이론", 400)
		, new Car("포터", 500)
		
	}; 
	
	{
	
	
	
	
	/* 향상된 for문으로도 사용이 가능하다. 
	 * for ( 타입과 변수명 : 배열 ) */
	
	for(Car c:carArray2) {
		c.driveMaxSpeed();
		
	}
	
	
}


}

 

 

class Car
public class Car {

	private String modelName;
	private int maxSpeed;
	
	
	/* 매개변수 생성자 정의 */
	public Car (String modelName, int maxSpeed) {
		this.modelName = modelName;
		this.maxSpeed = maxSpeed;
	}
	
	/* 기능 */
	public void driveMaxSpeed() {
		System.out.println(modelName +"(이)가 최고시속 " + maxSpeed + "km/h로 달려갑니다.");
	}
	
	
	
}

 

 

 

 

 

 

 

 

 

 

 

 

추가 예제 

 

 

Application
import java.util.Scanner;

public class Application {

	public static void main(String[] args) {

		/* 동일한 타입의 여러개의 인스턴스를 인자로 전달하거나 
		 * 리턴 받는 경우에도 객체 배열을 이용할 수 있다. */
		
		/* DTO를 이용한 간단한 회원관리용 프로그램 */
		/* 
		 * 구현기능
		 * 1. 여러명의 회원 정보를 받아 한번에 여러 회원 정보를 등록
		 * 2. 전체 회원 조회 시 여러명의 회원정보를 반환
		 * 
		 *  */
		
		Scanner sc = new Scanner(System.in);
		
		MemberManager memberManager = new MemberManager();
		// 없으므로 생성
		
		
		menu : 
		while(true) {
			
			
			System.out.println("==========회원관리 프로그램==========");
			System.out.println("1. 회원등록");
			System.out.println("2. 회원 전체 조회");
			System.out.println("9. 프로그램 종료");
			System.out.print("메뉴 선택 : ");
			int no = sc.nextInt();
			
			
			switch(no) {
			case 1 : memberManager.signUpMembers(); break;
			case 2 : memberManager.printAllMembers(); break;
			case 9 : System.out.println("프로그램을 종료합니다."); break menu;
			default : System.out.println("잘못 된 번호를 입력하셨습니다."); break;
			
			}
			
			
			
			
		}

	}

}



//==========회원관리 프로그램==========
//1. 회원등록
//2. 회원 전체 조회
//9. 프로그램 종료
//메뉴 선택 : 1
//회원을 등록합니다.
//김영희님은 회원 등록에 성공했습니다.
//홍길동님은 회원 등록에 성공했습니다.
//박진희님은 회원 등록에 성공했습니다.
//이순신님은 회원 등록에 성공했습니다.
//한지희님은 회원 등록에 성공했습니다.
//
//김영희님은 회원 등록에 성공했습니다.
//홍길동님은 회원 등록에 성공했습니다.
//박진희님은 회원 등록에 성공했습니다.
//이순신님은 회원 등록에 성공했습니다.
//한지희님은 회원 등록에 성공했습니다.
//총 5명의 회원 등록에 성공했습니다.
//==========회원관리 프로그램==========
//1. 회원등록
//2. 회원 전체 조회
//9. 프로그램 종료
//메뉴 선택 : 2
//==========가입된 회원 목록==========
//MeberDTO [num=1, id =user01, pwd =pass01, name =김영희, age =20, gender =여]
//MeberDTO [num=2, id =user02, pwd =pass02, name =홍길동, age =22, gender =남]
//MeberDTO [num=3, id =user03, pwd =pass03, name =박진희, age =24, gender =여]
//MeberDTO [num=4, id =user04, pwd =pass04, name =이순신, age =26, gender =남]
//MeberDTO [num=5, id =user05, pwd =pass05, name =한지희, age =28, gender =여]
//MeberDTO [num=1, id =user01, pwd =pass01, name =김영희, age =20, gender =여]
//MeberDTO [num=2, id =user02, pwd =pass02, name =홍길동, age =22, gender =남]
//MeberDTO [num=3, id =user03, pwd =pass03, name =박진희, age =24, gender =여]
//MeberDTO [num=4, id =user04, pwd =pass04, name =이순신, age =26, gender =남]
//MeberDTO [num=5, id =user05, pwd =pass05, name =한지희, age =28, gender =여]
//====================
//총 5명의 회원이 가입되어 있습니다.
//==========회원관리 프로그램==========
//1. 회원등록
//2. 회원 전체 조회
//9. 프로그램 종료
//메뉴 선택 : 4
//잘못 된 번호를 입력하셨습니다.
//==========회원관리 프로그램==========
//1. 회원등록
//2. 회원 전체 조회
//9. 프로그램 종료
//메뉴 선택 : 9
//프로그램을 종료합니다.

 

 

class MemberDTO
public class MemberDTO {

	/* 관리할 회원정보를 추상화해서 필드 작성 */
	private int num;
	private String id;
	private String pwd;
	private String name;
	private int age;
	private char gender;
	
	
	
	/* 아무것도 체크하지않으면 기본생성자 */
	public MemberDTO() {
		super();
	}


	/* 마우스 우클릭 - source - Generate Constructor using Fields */
	/* 모든 필드를 초기화하는 생성자 */
	public MemberDTO(int num, String id, String pwd, String name, int age, char gender) {
		super();
		this.num = num;
		this.id = id;
		this.pwd = pwd;
		this.name = name;
		this.age = age;
		this.gender = gender;
	}


	
	
	/* 마우스 우클릭 - source - Generate Getter and Setter */
	/* 게터세터 생성 */
	
	public int getNum() {
		return num;
	}


	public void setNum(int num) {
		this.num = num;
	}


	public String getId() {
		return id;
	}


	public void setId(String id) {
		this.id = id;
	}


	public String getPwd() {
		return pwd;
	}


	public void setPwd(String pwd) {
		this.pwd = pwd;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public int getAge() {
		return age;
	}


	public void setAge(int age) {
		this.age = age;
	}


	public char getGender() {
		return gender;
	}


	public void setGender(char gender) {
		this.gender = gender;
	}



	
	/* 모든 필드값을 문자열로 반환 */
	public String getInformation() {
		
		return  "MeberDTO [num=" + num + ", id =" + id + ", pwd =" + pwd + ", name =" + name +
				", age =" + age + ", gender =" + gender + "]";
		
	}
	
}

 

 

class MemberInsertManager
public class MemberInsertManager {

	
	/** <pre> 
	 * 여러명의 회원 정보를 한 번에 등록할 수 있는 기능 제공
	 * </pre>
	 * @param members 회원 정보를 객체배열 형태로 전달
	 * */
	
	public void insert(MemberDTO[] members) {
		System.out.println("회원을 등록합니다.");
		
		
		/* 일반 for문 */
		for (int i = 0; i < members.length; i++) {
			System.out.println(members[i].getName() + "님은 회원 등록에 성공했습니다.");
		}
		
		
		System.out.println();
		
		
		
		/* 향상된 for문 */
		/* 타입과 변수:멤버의 이름 */
		for (MemberDTO member:members) {
			System.out.println(member.getName() + "님은 회원 등록에 성공했습니다.");
		}
		
		
		System.out.println("총 " + members.length + "명의 회원 등록에 성공했습니다.");
		
	}

	
	
}

 

 

class MemberManager
public class MemberManager {

	/** <pre>
	 * 여러 명의 회원 정보를 등록
	 *  </pre>
	 *  */
	
	
	public void signUpMembers() {
		
		/* 5명의 회원 정보를 담을 객체배열 생성 */
		MemberDTO[] members = new MemberDTO[5];
		
		
		/* 5명의 회원정보를 각 인덱스에 할당 */
		members[0] = new MemberDTO(1, "user01", "pass01", "김영희", 20, '여');
		members[1] = new MemberDTO(2, "user02", "pass02", "홍길동", 22, '남');
		members[2] = new MemberDTO(3, "user03", "pass03", "박진희", 24, '여');
		members[3] = new MemberDTO(4, "user04", "pass04", "이순신", 26, '남');
		members[4] = new MemberDTO(5, "user05", "pass05", "한지희", 28, '여');
		
		
		/* 회원 정보를 입/출력할 용도의 MemberInsertManager 작성 */
		MemberInsertManager memberInsertManager = new MemberInsertManager();
		// 없으므로 생성 
		memberInsertManager.insert(members); 
		//memberDTO 5개의 참조변수에 대한 주소값을 인자로 전달
		
		
	}

	
	
	
	/** <pre>
	 * 모든 회원 목록을 조회하여 정보를 출력
	 *  </pre>
	 *  */
	
	public void printAllMembers() {
		
		/* MemberSelectManager 클래스 작성 */
		/* 작성한 메소드를 호출하고 반환받은 값을 객체배열 레퍼런스 변수에 저장한다. */
		
		
		MemberDTO[] selectedMembers = new MemberSelectManager().selectAllMembers();
		
		
		
		/* 가입되어 있는 회원 목록을 출력한다. */
		System.out.println("==========가입된 회원 목록==========");
		for (int i = 0; i < selectedMembers.length; i++) {
			System.out.println(selectedMembers[i].getInformation());
		}

		
		for (MemberDTO member : selectedMembers) {
			System.out.println(member.getInformation());
			
		}
		
		System.out.println("====================");
		System.out.println("총 " + selectedMembers.length + "명의 회원이 가입되어 있습니다.");
		
	}

	
	
	/* 클래스를 여러개 작성하는 이유: 클래스는 하나의 기능, 책임만을 가지고 있어야 함 */
	/* 인자로 전달하는 테스트, 리턴받은 테스트를 하기 위함이었다. */
	
	
}

 

 

 

class MemberSelectManager
public class MemberSelectManager {

	/** <pre>
	 * 회원 정보 전체를 반환하는 메소드
	 *  </pre>
	 *  @return 전체 회원 정보 객체 배열로 반환
 	 *  
	 *  */
	
	public MemberDTO[] selectAllMembers() {
		
		/* MemberDTO배열을 리턴하는 메소드 */
		return new MemberDTO[] {
		new MemberDTO(1, "user01", "pass01", "김영희", 20, '여')
		, new MemberDTO(2, "user02", "pass02", "홍길동", 22, '남')
		, new MemberDTO(3, "user03", "pass03", "박진희", 24, '여')
		, new MemberDTO(4, "user04", "pass04", "이순신", 26, '남')
		, new MemberDTO(5, "user05", "pass05", "한지희", 28, '여')
		
		
		};	
	}	
}

 

 

 

 

 

 

'Programming > JAVA' 카테고리의 다른 글

다형성  (0) 2022.01.05
상속  (0) 2022.01.04
클래스와 객체(3)  (0) 2021.12.30
클래스와 객체(2)  (0) 2021.12.29
배열, 클래스와 객체  (0) 2021.12.28

+ Recent posts