-static을 붙이면 프로그램 실행시 메모리에 올라감
-객체생성을 하지 않아도 사용가능
-static을 붙인 변수는 객체간의 변수 값 공유(똑같은 값을 가짐)
-static이 붙은 멤버의 명칭: 클래스 변수, 클래스 메서드
-static이 붙지 않은 멤머의 명칭: 인스턴스 변수, 인스턴스 메서드
package e_oop;
public class Static {
//값을 공유하기 위해 변수에 static을 붙힌다.-> 클래스 변수이며 변수의 값 공유하며 값이 전부 똑같음
static int var;
public static void main(String[] args){
//변수에 static 안붙히는 경우
Saram s1 = new Saram();
Saram s2 = new Saram();
s1.name = "철수";
s2.name = "영희";
s1.saveMoney(100000);
s2.saveMoney(200000);
s1.saveDateMoney(300000);
s2.saveDateMoney(300000);
System.out.println("문자열 입력>");
String str = ScanUtil.nextLine();
System.out.println(str);
System.out.println("숫자 입력>");
int num = ScanUtil.nextInt();
System.out.println(num);
}
}
class Saram{
String name; //사람의 이름
int account; //가지고 있는 돈
void saveMoney(int money){
account += money;
System.out.println(name+"의 통장 잔고: "+account);
}
static int dateAccount; //데통
void saveDateMoney(int money){
dateAccount += money;
System.out.println("데이트통장 잔고: "+dateAccount);
}
}
//메서드는 자주 사용되서 객체생성을 하기 싫어함 그래서 스태틱 붙은 매서드를 만들수 있다.
package e_oop;
import java.util.Scanner;
public class ScanUtil {
private static Scanner s = new Scanner(System.in);
//static이 붙은 변수는 메모리에 올리는 것 하지만 Scanner는 입력받아야함
//문자열 입력 받는 메서드
public static String nextLine(){
return s.nextLine();
}
//인트 타입 입력 받는 메서드
public static int nextInt(){
return Integer.parseInt(s.nextLine());
}
}
* - 자바로 만들어진 프로그램이 실행되는 컴퓨터 안의 가상 컴퓨터
* - 운영체제 -> JVM -> 자바 프로그램
* - 장점: 운영체제에 상관없이 실행 할 수 있다.
* - 단점: 속도가 느리다
*
* JVM 메모리 구조
* - Method Area(메서드 영역): 클래스 멤버가 저장된다.
-- static이 붙은애는 프로그램 실행 전 한번만 저장하며 객체는 여러 객체를 많이 만들어도 한번만생성
* - Heap: 객체가 저장된다. - static이 안들어있는것
* - call stack(호출 스택):현재 호출되어 있는 메서드가 저장된다.
package e_oop;
public class JVM {
public static void main(String[] args) {
//1. 프로그램 실행 시 main(), classVar, classMethod()가 MethodArea에 저장됨
//2. main()이 호출되어 CallStack에 저장됨
System.out.println(classVar);
//3. System 클래스의 out이 MethodArea에 저장됨 (out=static)
//4. println()이 호출되어 CallStack에 저장됨
//5. println()이 classVar를 출력 후 CallStack에서 삭제됨
classMethod();
//6. classMethod()가 호출되어 CallStack에 저장되었다가 메거드가 종료되면 삭제됨
JVM jvm = new JVM();//instanceVar를 위해 객체생성
//7. JVM객체가 Heap에 저장됨
//8. jvm 변수가 CallStack에 생성되고 JVM 객체의 주소가 저장됨
System.out.println(jvm.instanceVar);
//9. println()이 호출되어 CallStack에 저장되어 있다가 instanceVar를 출력 후 삭제됨
jvm.instanceMethod();
//10. instanceMethod()가 호출되어 CallStack에 저장되었다가 메서드가 종료되면 삭제
jvm = null;
//11. jvm변수에 null이 저장됨 ,주소거 사라진것 = 필요 없어진 객체 = 가비지컬렉터가 발견 후 삭제
//12. 어디에서도 주소를 참조하지 않는 JVM객체는 GdrbageCollector에 의해 삭제됨
//13. main()의 실행이 종료되어 CallStack에서 삭제됨
//14. 프로그램이 종료되고 MerhodArea의 데이터가 삭제됨
}
int instanceVar;
static int classVar;
void instanceMethod(){
System.out.println(instanceVar);
System.out.println(classVar);
}
static void classMethod(){//메모리에 올라온것
// System.out.println(instanceVar);
//컴파일에러가 발생하는 이유는 변수가 메모리에 올라와 있지 않기 때문.
//instanceVar는 static가 붙지 않아서 메모리에 올라오지 않아서 사용할 수 없다.
//사용하려면 객체 생성을 해줘야 함
System.out.println(classVar);
}
}
package e_oop;
public class Variablelnit {
1. 명시적 초기화
int var = 10;
static int classVar = 20;
2. 초기화 블럭 - 블럭을 열구 초기화 하면댐 - 스태틱 안붙은 인스턴스 변수의 초기화
//- 초기화 블럭을 이용하면 여러 줄의 로직을 사용할 수 있기 때문에 사용
{
var = 30;
}
//스태틱 붙힌것
static{
classVar = 30;
}
/* 생성자
* - 클래스와 같은 이름의 메서드
* - 인트턴스 변수를 초기화하기 위해 사용
* - 클래스에 생성자는 반드시 하나 이상 존재
* - 직접 선언해 주지 않으면 컴파일러가 기본 생성자를 만들어줌
* - 생성자는 리턴타입이 없다.
*/
Variablelnit(){//클래스 이름을 작성하고 괄호만 치면 생성
var = 50; //변수 생성
//*생성자를 사용하는 이유
//초기화에 여러줄의 코드가 필요할 때
//초기화에 파라미터가 필요할 때(파라미터가 필요한 이유: 외부에서 값을 결정한다는 것)
}
public static void main(String[] args) {
Init i = new Init(); //객체 생성
//클래스 이름과 같은 메서드(생성자)를 호출함
i.a = 10;// 클래스 밖에서 변수들 초기화할 경우 생성자를 사용하는 것이 좋음
i.b = 20;
i.c = 30;
Init i2 = new Init(); //컴파일 에러가 발생하는 이유: 우리가 따로 만들었기 때문
-> 파라미터가 없는 생성자를 생성하면 컴파일 에러가 사라진다.
i2.a = 40;
i2.b = 50;
i2.c = 60;
Init i3 = new Init(70,80,90); //생성자와 파라미터는 값만 넘겨주면 초기화 가능(간단)
System.out.println();//오버로딩이 된 메서드
}
}
class Init{
int a;
int b;
int c;
Init(int a, int b, int c){//파라미터로 값을 받아옴
this.a = a;//받아온 값으로 초기화
this.b = b;
this.c = c;
//this: 인스턴스 변수와 지역변수(int a, int b, int c)의 이름이 같을 때 둘을 구분하기 위해 사용, 객체의 주소가 저장되는 변수
}
//오버로딩: 같은 이름의 메서드를 여러개 정의 하는것(반드시 파라미터가 달라야 함: 개수나 타입)
Init(){ // 파라미터가 없는 생성자를 생성하면 컴파일 에러가 사라진다.
this(10,20,30); //생성자의 첫줄에서만 사용할 수 있다.
//this(): 생성자에서 다른 생성자를 호출할때 사용 - Init(10,20,30);으로 호출하지 않음
//메서드는 똑같은 이름이 존재 할 수 있다. 구분하는 방법은? 파라미터로
}
package e_oop;
public class ClassMaker2 {
//1.인스턴스변수(static이 붙지 않은 변수) 하나를 선언하고 명시적으로 초기화 해주세요
int a = 10;
//2.위에서 선언한 인스턴스변수를 초기화 블럭을 사용해 초기화 해주세요
{
a = 3;
}
//3.위에서 선언한 인스턴스변수를 생성자(클래스 이름과 똑같은 메서드)의 파라미터를 사용해 초기화
ClassMaker2(int a){
this.a = a;
}
//4.위에서 선언한 인스턴스 변수를 생성자를 하나 더 만들어서 초기화 해주세요
ClassMaker2(){//3을 호출해서 초기화 한것
this(10);
}
//초기화 순서: 명시적 초기화 -> 초기화 블럭 -> 생성자
}