(1) 인스턴스변수(iv)
(2) 클래스변수(cv)
(3) 지역변수(lv)
메서드 내에 선언되어 메서드 내에서만 사용 가능하며, 메서드가 종료되면 소멸되어 사용할 수 없게 된다. for문 또는 while문의 블럭 내에 선언된 지역변수는 지역변수가 선언된 블럭{} 내에서만 사용 가능하며, 블럭{}을 벗어나면 소멸되어 사용할 수 없게 된다.
종류 | 선언위치 | 생성시기 |
---|---|---|
클래스변수 | 클래스 영역 | 클래스가 메모리에 올라갈 때 |
인스턴스변수 | 클래스 영역 | 인스터스가 생성되었을 때 |
지역변수 | 클래스 영역 이외의 영역 | 변수 선언문이 수행되었을 때 |
class exam{
int iv; // 인스턴스 변수
static int cv; // 클래스 변수
void method()
{
int lv = 0; // 지역 변수
}
}
예시
public class CardTest {
public static void main(String[] args) {
System.out.println("Card.width="+Card.width);
System.out.println("Card.width="+Card.height);
Card c1 = new Card(); // 2개의 객체를 생성하여 c1,c2마다 kind와 number값을 설정함
c1.kind = "Heart"; // 각 객체마다 설정해야하는 값은 인스턴스 변수를 통해 설정
c1.number = 7;
Card c2 = new Card();
c2.kind = "Spade";
c2.number = 4;
System.out.println("c1은 "+c1.kind+", "+c1.number+"이며, 크기는("+c1.width+", "+c1.height+")");
System.out.println("c2은 "+c2.kind+", "+c2.number+"이며, 크기는("+c2.width+", "+c2.height+")");
System.out.println("c1의 width와 height를 각각 50,80으로 변경합니다");
c1.kind = "test"; // iv 변경
c1.number = 50;
Card.width = 50; // cv 변경
Card.height = 80; // cv는 참조변수가 아닌 Card 클래스 이름으로 작성해야함(iv와 구분하기위해)
System.out.println("c1은 "+c1.kind+", "+c1.number+"이며, 크기는("+c1.width+", "+c1.height+")");
System.out.println("c2은 "+c2.kind+", "+c2.number+"이며, 크기는("+c2.width+", "+c2.height+")");
// kind,number는 인스턴스변수로 객체에 따라 값이 변경됨 => "test",50,50,80
// width,height는 클래스변수로 값이 고정되어 있음 => "Spade",4,50,80
}
}
class Card{
String kind;
int number;
static int width = 100; // 여러개의 객체들마다 같은 값을 사용하는 변수는 클래스변수를 통해 설정
static int height = 250;
}
변수의 초기화
- 지역변수(lv)는 꼭!! 수동 초기화 해야함
- 멤버변수(iv,cv)는 자동 초기화 된다.
- 클래스 변수 초기화 시점 : 클래스가 처음 로딩될때 단 한번
- 인스턴스 변수 초기화 시점 : 인스턴스가 생성될 때 마다
class InitTest{ int x; // 인스턴스 변수(자동으로 0으로 초기화) int y = x; // 인스턴스 변수 void method1(){ int i; // 지역변수 int j = i; // 에러 발생(초기화 하지 않고 사용) } }
멤버변수의 초기화
(1) 명시적 초기화 (=) - 간단 초기화
(2) 초기화 블럭 ( { },static{ } ) - cv 초기화(복잡 초기화)class StaticBlockTest{ static int[] arr = nwe int[10]; // 명시적 초기화 static{ // 클래스 초기화 블럭(복잡 초기화) for(int i=0; i<arr.length; i++){ arr[i] = (int)(Math.random()*10) +1; } } }
(3) 생성자(iv초기화)
(4) 열거형(enum)
자바는 열거타입을 이용하여 변수를 선언할 때 변수타입으로 사용할 수 있다.
기존 방식
public class EnumExam {
public static final String MALE = "MALE";
public static final String FEMALE = "FEMALE";
public static void main(String[] args) {
String gender1;
gender1 = EnumExam.MALE;
gender1 = EnumExam.FEMALE;
}
}
문제점
String으로 선언된 gender1에는 문자열 모든 값이 들어올 수 있다. 하지만 나는 MALE, FEMALE만 입력받고 싶어한다.
이를 위해 enum을 사용하면 된다.
enum 사용방식
enum Gender{
MALE, FEMALE;
}
Gender gender2;
gender2 = Gender.MALE;
gender2 = Gender.FEMALE;
(1) 생성자
모든 클래스는 인스턴스화 될때 생성자를 사용한다.
객체의 생성과 동시에 인스턴스 변수를 원하는 값으로 초기화한다.
클래스 이름을 그대로 사용하여 설정해야 한다.
public class Car{
String name;
int number;
public Car(String name){
this.name = name;
}
}
(1) 생성자는 리턴타입이 없다.
(2) 매개변수가 없는 생성자를 기본생성자라고 한다. 예시) Car car = new Car();
(2) this
인스턴스가 바로 자기 자신을 참조하는 데 사용하는 변수이다.
this참조 변수는 해당 인스턴스의 주소를 가리키고 있다.
예시
class Car { // Car 클래스 생성
private String modelName; // (a)
private int modelYear; // (b)
private String color;
private int maxSpeed;
private int currentSpeed;
Car(String modelName, int modelYear, String color, int maxSpeed) { // 생성자 생성(꼭!! 클래스 이름과 같아야함)
this.modelName = modelName; // this를 사용하여 생성자 매개변수가 아닌 (a)를 가르키고 있음
this.modelYear = modelYear; // (b)를 가르키고 있음
this.color = color;
this.maxSpeed = maxSpeed;
this.currentSpeed = 0;
}
public String getModel() { // 리턴값 출력
return this.modelYear + "년식 " + this.modelName + " " + this.color;
}
}
public class Method02 { // 메인클래스
public static void main(String[] args) {
Car myCar = new Car("아반떼", 2016, "흰색", 200); // 생성자의 호출과 동시에 값 입력
System.out.println(myCar.getModel()); // 생성자에 의해 초기화되었는지를 확인함.
}
}
(1) 리턴하는 것이 없는 메서드(리턴하는 것이 없을 경우 void라고 작성한다.)
public class MyClass{
public void method1(){
System.out.println("method1이 실행됩니다.");
}
}
(2) 정수를 받아들인 후, 리턴하지 않는 메서드
public class MyClass{
public void method2(int x){
System.out.println(x + " 를 이용하는 method2입니다.");
}
}
(3) 아무것도 받아들이지 않고, 정수를 반환하는 메서드(리턴하는 값의 형식에 따라 반환타입도 같은 형식으로 작성해야 한다.)
ex) int형 반환 => public int method3() , String형 반환 => public String method3()
public int method3(){
System.out.println("method3이 실행됩니다.");
return 10;
}
(4) 정수를 2개 매개변수로 받고, 아무것도 반환하지 않는 메서드
public void method4(int x, int y){
System.out.println(x + "," + y + " 를 이용하는 method4입니다.");
}
(5) 정수를 한 개 받아들인 후, 정수를 반환하는 메서드
public void method4(int x, int y){
System.out.println(x + "," + y + " 를 이용하는 method4입니다.");
}
Static 메서드와 인스턴스 메서드 차이
class Mymathtest { long a,b; static long c,d; void instanceMethod(){} // 인스턴스 메서드 static void staticMethod(){} // static 메서드 long add(){ // 인스턴스 메서드 instanceMethod(); // 인스턴스 메서드 호출 가능 staticMethod(); // static 메서드 호출 가능 return a+b; } static long add(long a, long b){ // 클래스메서드(static 메서드) instanceMethod(); // 인스턴스 메서드 호출 불가능(오류 발생) staticMethod(); // static 메서드 호출 가능 return a+b; } } public class test{ public static void main(String[] args) { System.out.println(Mymathtest.add(200L,100L)); // 객체 생성없이 호출 Mymathtest m = new Mymathtest(); // 객체생성 m.a = 200L; m.b = 100L; System.out.println(m.add()); } }
- static메서드는 객체생성 없이도 호출이 가능하다
- 인스턴트 메서드는 인스턴스 변수만 필요하고 매개변수는 필요하지 않다
- 클래스메서드는 인스턴스변수는 필요없고 매개변수만 필요하다.
- 인스턴스메서드에서는 인스턴스 메서드, static메서드 호출 가능(변수도 같음)
- 클래스메서드에서는 인스턴스 메서드 호출 불가능(변수도 같음, 인스턴스 변수 사용 불가능)
이름은 같지만 매개변수가 다른 메소드
class MyClass2{
public int plus(int x, int y){ //2개의 매개변수를 갖는 메소드
return x+y;
}
public int plus(int x, int y, int z){ // 3개의 매개변수를 갖는 메소드
return x + y + z;
}
public String plus(String x, String y){ // String의 매개변수를 갖는 메소드
return x + y;
}
public void plus(int x, String y){ // int, String의 매개변수를 갖는 메소드
System.out.println("x:"+x+"y"+y);
}
}
오버로드된 메소드 사용
public MethodOverloadExam{
public static void main(String args[]){
MyClass2 m = new MyClass2();
System.out.println(m.plus(5,10));
System.out.println(m.plus(5,10,15));
System.out.println(m.plus("hello" + " world"));
}
}