변수

변수 선언 시 타입을 결정해야 한다

8가지 타입 중 중요한 타입 세 가지
1. int: 정수
2. double: 실수

3. boolean: True/False (주로 if문, switch문 같은 조건문에서 사용)

호출하기 위해서 인스턴스화를 해야 한다

변수 작성 양식

  • (접근제한자) 타입 변수이름 =(대입연산자) 값
    (대입연산자가 오면 초기화를 하겠다는 것)
  • 초기화 i=0;
    초기화를 하려면 1. 위치를 잘 잡아야 한다
package com.step1;

public class Variable1 extends Object {
      // 변수를 선언할 수 있다.
      // 접근제한자 타입 변수이름 = 
      public static void main(String[] args) {
          int i = 1;
          int j = 2;
          System.out.println(i+j); // 3출력된다
          System.out.println(hap); // 에러 발생 - 선언하지 않았으니까
	}
}

변수의 종류

1. 원시형 타입(primitive type)
: 값을 그대로 할당
: int, double, boolean

2. 참조형 타입(Reference Type)
: 값이 저장된 주소값을 할당(주소번지)
: 클래스인 것은 모두 여기에 해당됨

  • 클래스 타입은 주소번지(reference)를 갖는다
    (호출하면 값이 아닌 주소번지가 찍힌다)
  • 레퍼런스 변수를 가지려면 인스턴스화를 해야 한다
    (인스턴스화를 할 때 사용하는 예약어가 new)

변수의 선언 위치에 따라, 또 변수 선언시 붙는 수정자에 따라서

  • 전역 변수(global variable) - 인스턴스 변수 호출은 전역변수만 가능

  • 지역 변수(local variable) - 인스턴스 변수에 지역변수 호출은 불가(컴파일 안 됨)

  • 정적 변수(static variable) - 클래스 타입.변수명으로 사용함(싱글톤, 하나다, 공유된다)

    전역변수는 초기화를 생략할 수 있다(생성자가 대신 해주니까) -> 디폴트값이 정해져 있다(초기값 0)
    지역변수는 초기화를 생략할 수 없다

<인스턴스화>

<예제1>
package com.step1;

public class Sonata { 
	int speed = 0; 
	int wheelNum = 4;
	String carColor = "검정색";
    
	public static void main(String[] args) {
		Sonata myCar = null; 
		myCar = new Sonata();
        
		Sonata herCar = new Sonata();
		herCar.speed = 50;
        
		System.out.println(myCar.speed);
		System.out.println(herCar.speed);
	}
}
출력: 0
     50
     
<주석 참조>
package com.step1;

public class Sonata { 
	// 접근제한자 class 예약어를 사용해서 클래스 선언 
	// 클래스 이름: 대문자로 시작(낙타표기법)
	// 선언부 - 선언부에 선언하는 변수는 전역변수(global variable, member variable)
	// 자동차를 생각나게 하는 고유명사 - speed, wheelNum, carColor
	// 타입 + 변수이름 + 대입연산자 + 값
	int speed = 0; // 주차 돼있을 때 - 호출하면 값이 나온다 -> 원시형타입(primative data type)
	int wheelNum = 4; // 바퀴 수 4개
	String carColor = "검정색"; // 변수 선언 - 대문자로 시작하는 건(String) 클래스이다 -> 참조타입(reference data type)
	public static void main(String[] args) {
		Sonata myCar = null; // 선언만 한 것 -> 아직 생성하지 않았다
        // 변수 myCar를 아직 사용할 수 없다 / 타입만 결정되었다
        // myCar - 인스턴스화에 사용된 변수를 인스턴스변수라고 한다
		// 인스턴스변수를 통해서 호출할 수 있는 건 전역변수 뿐이다
		// 지역변수는 불가
		myCar = new Sonata(); // 생성하였다. 사용할 수 있다
        // myCar를 전역변수 호출하는데 사용하더라도 NullPointerException이 발생하지 않는다
		// 런타임에러시 발생하는 게 exception임
		Sonata herCar = new Sonata();
		// 선언과 생성을 나눠서 작성하면 시점의 문제를 당할 수 있다 - NullPointerException
		herCar.speed = 50;
		System.out.println(myCar.speed); // 0
		// 원시형 타입에는 한 번에 하나만 담을 수 있다 - 변수의 장애
		// 동시에 2개의 값을 가질 수 없다
		System.out.println(herCar.speed); // 0
	}
}
<예제2>
package com.step1;

public class Variable2 {
	static int i = 5; // 정적변수(static)
	// main메소드에서 non-static타입은 호출이 불가 하지만 static 타입은 가능
	// 전역 변수는 인스턴스화를 하면 접근 가능
	int j = 1; // 전역변수(정적변수X)
    
	public static void main(String[] args) {
		System.out.println("i는 " + i); // 5출력
		~~System.out.println(j);~~ // 에러
		
		// 인스턴스화를 하자
		Variable2 myCar = new Variable2(); // myCar 선언
		System.out.println("j는 " + myCar.j); // 1출력
	}
}
  • 출력: i는 5
    j는 1

<예제3>

왜 아래 그림에서는 jft.initDisplay( );에 에러가 날까?

왜 2번에서는 에러가 날까?
선언한 JFrameTest2 클래스 안에 initDisplay( )가 구현되지 않았기 때문

<예제4> -> 다시 보기

package com.step1;
import javax.swing.JFrame;
public class JFrameTest2 { // 클래스 선언하기 좌중괄호, 우중괄호
	JFrame jf = new JFrame();
	// 선언부에서는 선언과 초기화를 두 줄에 나누어 적을 수 없다
	~~int i;~~ // 선언만 한 것 -> 전변
	~~i = 10;~~ // 초기화
	int j = 10; // 새로 선언한 변수
	jf.setSize(500, 400);
	jf.setVisible(true);
	public static void main(String[] args) {
		JFrameTest2 jft = new JFrameTest2();
		~~jft.initDisplay();~~ // 메소드 뒤에는 {}가 와야 함. 메소드 이름 뒤에 세미콜론이 오면 호출
		// 이건 선언을 안 한 상태로 호출했으니 에러가 나는 것이다
	}
}


에러가 뜨는 이유는?

<예제5>
package com.step1;

import javax.swing.JFrame;

public class JFrameTest3 { 
	static JFrame jf = new JFrame();
	public static void main(String[] args) {
		JFrameTest3 jft = new JFrameTest3();
		jf.setTitle("난 3번이야");
		jf.setSize(500, 400);
		jf.setVisible(true);
	}
}
→ 창 출력 완료
<예제6>
package com.step1;

import javax.swing.JFrame;

public class JFrameTest4 { 
	static JFrame jf = new JFrame();
	public static void main(String[] args) {
		JFrameTest3 jft = new JFrameTest3();
        // jft는 지역변수이다. 
		// 메소드 좌중괄호, 우중괄호 안에서 선언된 변수는 모두 지변(의 성격)이다. 
		jft.jf.setTitle("난 3번이야"); // jft는 3번을 참조하는 것이고, jf는 4번 참조
		jft.jf.setSize(500, 400);
		jft.jf.setVisible(true);
		jf.setTitle("난 4번이야");
		jf.setSize(500, 400);
		jf.setVisible(true);
        // 주소번지를 두 번 접근해서 메소드를 호출하는 소스임
		// 호출되는 setTitle메소드는 JFrameTest3에서 인스턴스화한 
        // JFrame에 정의된 메소드를 호출하는 것
	}
}
<예제7>
package com.step1;

import javax.swing.JFrame;

public class JFrameTest5 {
	JFrame jf = new JFrame(); // 전변의 성격 - 메소드 안에 선언하지 않았다
	// 인스턴스변수.변수명으로 호출이 가능함 -> 전변
	public static void main(String[] args) {
	// 내 안에 선언된 변수이더라도 static 영역 안에서 non-static 변수를 호출할 때는
	// 인스턴스화를 해야 한다
		JFrameTest5 jft = new JFrameTest5();
        // 인스턴스화를 하려면? JFrameTest4는 적으면 안 된다
		// 해결방법은 주소번지를 두 번 접근해야만 한다
		jft.jf.setTitle("난 5번이야");
		jft.jf.setSize(500, 400);
		jft.jf.setVisible(true);
	}
}

<예제8> 탭 만들기

package com.step1;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class JFrameTest6 implements ActionListener { 
	static JFrameTest6 jft = new JFrameTest6();
	JFrame jf = new JFrame(); 
	JButton jbtnAccount = new JButton("연산하기");
	JButton jbtnExit = new JButton("종료하기");
	// 인스턴스변수.변수명으로 호출이 가능함 -> 전변
	public static void main(String[] args) {
		JFrameTest6 jft = new JFrameTest6();
		jft.jf.setTitle("난 5번이야");
		jft.jbtnAccount.addActionListener(jft);
		jft.jf.add("North",jft.jbtnExit);
		jft.jf.add("South",jft.jbtnAccount);
		jft.jf.setSize(500, 400);
		jft.jf.setVisible(true);
	}
	// 버튼을 누르는 건 사용자이고, 버튼이 눌렀는지 느끼는 건 JVM이다
	@Override
	public void actionPerformed(ActionEvent e) {
		// 눌려진 버튼의 주소번지를 JVM으로부터 알아낸다
		Object obj = e.getSource(); // 눌려진 버튼의 주소번지를 가져옴
		// 오른쪽에 있는 값과 왼쪽에 있는 값이 같니? -> 대입연산자를 두 번 적는다
		// 파라미터는 사용자가 입력한 값을 받아오는 자리
		if(obj == jft.jbtnAccount) {
			System.out.println("버튼을 눌렀어요.");
		}
	}
}

출력

<예제9>

package com.step1;
public class Variable3 {
	public void account(int i, int j) { 
		System.out.println("account 호출 성공");
		System.out.println(i); 
		System.out.println(j); 
	}
	public static void main(String[] args) {
		Variable3 v = new Variable3();
		v.account(1,2);
	}
}
출력: account 호출 성공
     1
     2
  • 지역변수 선언할 수 있는 위치: 메소드 안에서 하거나, 파라미터 자리에 할 수 있다
  • 파라미터 자리란, 메소드 괄호 안을 말하는 것(사용자가 입력한 값을 받아오는 자리). 괄호 안에서는 선언만 가능하다(초기화는 불가능)
  • Q. 파라미터 자리에 선언된 변수는 지역변수. 초기화는 반드시 해야 한다 했는데, 그럼 언제 초기화가 되는 걸까?
    → 메소드를 호출할 때 값이 결정된다
  • String[] args -> 선언만 돼있음

<예제9 주석 설명>

package com.step1;
public class Variable3 {
	public void account(int i, int j) { 
    // 메소드 타입과 개수까지도 결정할 수 있어야 한다
	// 사용자, 즉 개발자가 임의의 메소드를 얼마든지 선언할 수 있고 구현할 수 있음
    // 파라미터 자리에 선언된 변수는 지역변수
    // 값이 결정되지 않음 → 언제 결정되나요? 
    // → v.account(1,2);에서 초기화됨
		System.out.println("account 호출 성공");
		System.out.println(i); // 1
		System.out.println(j); // 2 
        // call by value: 호출할 때 값이 복사/결정/초기화가 된다
	}
		// 컴파일을 하는 언어는 컴파일 타임에 문법 체크를 한다는 뜻
	public static void main(String[] args) {
		// 내가 정의한 메소드 account 호출하기
		// 내 안에 정의된 메소드라 하더라도 static 영역에서 			// static 없는 메소드를 호출하려면 인스턴스화
		~~account(1.2);~~
        // 주소번지 or 인스턴스변수 와야한다(해당메소드가 선언된 소유주 의미)
        
		// 인스턴스화 해야한다
		Variable3 v = new Variable3();
		v.account(1,2);
        ~~v.account();~~ // 개수가 맞지 않음
		~~v.account(5);~~ // 개수가 맞지 않음
		~~v.account(5,3,5);~~ // 개수가 맞지 않음
        // 파라미터의 개수가 다르면 같은 이름의 메소드라 하더라도 JVM이 다른 메소드로 인지한다
        ~~v.account(true, false);~~
	}
}

Double

<예제1>
package com.step1;
public class Double3 {
	public static void main(String[] args) {
		int i = 1;
		double d = 3.14;
		// 강제형전환시에는 0.14는 int타입에 담을 수 없다
		i = (int)d; 
        // 여기서 괄호는 캐스팅 연산자라 부름 - 강제형 전환
		System.out.println(i); // 출력: 3
		System.out.println(d); // 출력: 3.14
	}
}
  • 캐스팅 연산 시, 괄호 안에는 왼쪽 타입명을 적는다(대입연산자는 오른쪽 값을 왼쪽에 대입하는 것이니까
<예제2> 세 학생 점수의 평균 구하기
package com.step1;
public class Double4 {
	public static void main(String[] args) {
		int jumsu1 = 70;
		int jumsu2 = 85;
		int jumsu3 = 90;
		int total = jumsu1 + jumsu2 + jumsu3;
		double d = 3.14;
		System.out.println(total/3.0); 
        // 출력(double): 81.66666666666667
		System.out.println(total/3); 
        // 출력(int): 81
		d = 150.0/3;
		d = 151/3.0;
		d = 152/3; 
		// 오른쪽에 더블도 되고 int도 됨
		total = (int)(150.0/3); 
        // 강제 변환 - 원래는 total이 int기 때문에 불가능
	}
}
  • int + double = double
  • int - double = double
  • int * double = double
  • int / double = double

🖱 단축키

  • alt + shift + a + 좌클릭으로 영역 선택하면 한 번에 묶임
  • ctrl + alt + 화살표 아래 = 밑으로 복사

0개의 댓글