●
목차
●책
ㅡㅡㅡ
1.클래스 - 필드,멤버변수의 생명범위,저장위치,초기화
파일명 : day16/staticmember/Car,
day16/staticmember/CarExample
*
스택 -
(단일스레드,멀티스레드
(지역변수
주석많이 다는 것
static멤버 -클래스뱃속에서 실행
공통에서는 쓰는 것 - 공통영역에다가 올린다.
static - 정적
메모리에 올려와있찌만, 객체를 생성하지 않으면, 쓸수가 없다.
공통영역에 있지만, 객체를 생성하지않으면,,,
*
스택메모리
C
ㅡ
B
ㅡ
A
*
C가 먼저 실행, C 제거
B가 그 다음 실행, B 제거
A가 그 다음 실행, A 제거
이것이
LIFO(후입선출) = 라스트인 파이널아웃 = 가장 마지막에 넣은게 가장먼저 사라진다.
참고, FIFO(선입선출)
*
this
내 객체가 가지고 있는 변수
*
class에서 public을 생략한다면, default로 정해진다.
*
public이 범위가 가장 크다.
public > protected > default > private(숨긴다)
class가 default라면,기본생성자가 public을 쓰지 못한다.
*
생성자를 통해서 초기화 시킬수있다.
생성자는 초기화 시켜주는 역할을 하기 떄문에…
*
while문 안에 if문
- 그 안에 break; 만나면,
아래 문장을 읽지 않고 거기서부터 빠져나간다.
자기를 감싸는 중괄호를 빠져나간다.
while문 안에
- false개념(true false)
아래 문장까지 다 읽고 다시 위로 while로 올라간다.
메소드
- return(메소드 안에서)
(문장)메소드을 빠져나간다.
호출한곳으로 돌아간다.
●Car,CarExample
day16/staticmember/Car
//p271
//#1. 필드
String model;
//default String model - String mode에서 default가 생략되어 있다.
int speed2; //스택영역에 쌓인다.
Integer speed; // 주소가질수있게 객체타입을 가졌다. - 힙영역생성하고 주소값 넘겨준다
//컬렉션, 제네릭을 쓸수있을때, 쓴다 Integer 타입은
//int[] score; - 1) 배열
//필드는 왠만하면 private로 선언한다.
//메소드는 계산작업은 기본적으로 private 사용한다. - 메소드를 통해서만, 호출해서 나간다.
//출력은 안그래도되겠지만,
//#2. 생성자 - 클래스 이름과 같음
public Car(String model) {
this.model = model;
}
/* 1)배열 - 초기화
public Car(String model, int number){
this.model = model;
score = new int[number];
}
*/
//#3. 메소드
private void setSpeed(int speed) { //public으로 하지않고 default,private로 잡는다. 이 메소드를 메소드안에서 호출해서 쓴다면, private로 한다.
this.speed = speed;
return; //void는 생략되어 있다.
}
public void run() {
for(int i = 10; i <= 50; i++) {
this.setSpeed(i);
System.out.println(model + "가 달립니다.(시속 : " + speed +"km/h"); //지역변수가 없다면, 지금처럼 this를 생략해도된다.
//하지만, 밑에 코드는 명확하기때문에, 좋은 코딩이라고 할 수가 있다.
//System.out.println(this.model + "가 달립니다.(시속 : " + this.speed +"km/h");
}
}
day16/staticmember/CarExample
//#1. 객체 생성
Car myCar = new Car("포르쉐");
Car yourCar = new Car("벤츠");
myCar.run();
yourCar.run();
//private로 선언하면, 오류가 난다.
/*
myCar.setSpeed(10); //에러가 떨어진이유 : 접근제한자가 private이기 때문에
yourCar.setSpeed(10); //에러가 떨어진이유 : 접근제한자가 private이기 때문에
*/
//실제 코딩 :
/*
필드 메소드 웬만하면 숨겨라.
꼭 외부에 노출시켜야만 하는 것은 노출시켜라
패키지안에서 쓰고싶으면 default
public쓰고 싶으면 고민하면서 써라
*/
int score = 80;
System.out.println(score);
}
*
- 데이터영역
Car
생성자
setSpeed - 설계도를 꺼내놓은다.(누가부르면 실행시킬 준비)
run - 설계도를 꺼내놓은다.(누가부르면 실행시킬 준비)
Car라는 것만 미리 실행되어있다.
-스택
myCar - 객체이름
-힙
객체생성(model(“포르쉐”), speed(안정해져서,생성자가 초기값0 설정),setSpeed(private로 안보인다.), run()데이터영역의 주소가 있다. ) >> 이 모든것의주소를 스택에 있는 myCar 인스턴스에 넘긴다.
run실행
*LIFO(후입선출)
4번다 실행되었으면, 스피드 날라가고,run날라간다.
3번speed 그위에 깔리고
2번run이 그위에 깔리고
1번main이 먼저 깔리고
*객체 2개는
메소드는 같이 쓰는데 , 필드는 각각에 쓰는구나
*
static은 클래스에 있어요
static붙으면 언제나 메모리에 올라가있어요.
static에 안붙으면, 객체생성때 올라가요.
●
day16/staticmember/Pen
day16/staticmember/PenMainExam
day16/staticmember/Pen
//#1. 필드
private String color;
private int count;
private int allCount;
//private는 같은 클래스안에서 자유롭게 쓸수 있다.
//#2. 생성자
public Pen(String color) {
this.color = color;
//소문자만,대문자만, - color.equals("red")
//대소문자 - color.equalsIgnoreCase("red"); 대소문자 구분하지않는것.
if(this.color.equalsIgnoreCase("red")) { //this.color와 color는 다르다. 일단 색갈로 보면, 지역변수와 필드를 구분하고 있다. this.color를 써야, 객체를 생성하고 값이 들어갈때, 필드로 정상적으로 들어간다.
count++; //red pen의 개수를 누적, red pen 객체 개수
}
allCount++; //전체 pen의 개수 누적, 객체 생성 개수
}
public String getColor() { //private으로 설정된 필드 외부에서 읽어서 이용할 수 있도록
return color; // private 필드 호출해서 리턴
}
//개별 pen 건수
public int getCount() {
return count;
}
//전체 pen 건수
public int getAllCount() {
return allCount;
}
day16/staticmember/PenMainExam
//#1. pen 객체 생성
Pen red = new Pen("red");
Pen green = new Pen("green");
Pen red2 = new Pen("RED");
Pen blue = new Pen("blue");
Pen red3 = new Pen("Red");
int countResult = red3.getCount();
System.out.println(countResult); //나 : 1(정답1), 다른 객체
System.out.println(red3.getAllCount()); //나 : 3(정답1) ★★★ 객체가 다르기때문에, 다른것은 더해지지않는다.
//그렇다면, 공통된 데이터로 값을 저장할려면? => static이라는 것을 사용하면 된다.
*보안하는 법
1)private 필드 - db와 연동하게 된다.
2)setter를 생성하지 않는 것.
3)계산이되어있는 메소드 private 메소드.
●
day16/staticmember/PenStatic
day16/staticmember/PenStaticMainExam
: static으로 클래스안에 있는 값을 공유해서 사용하는 법
day16/staticmember/PenStaticMainExam
public static void main(String[] args) {
//#1. pen 객체 생성
PenStatic red = new PenStatic("red");
PenStatic green = new PenStatic("green");
PenStatic red2 = new PenStatic("RED");
PenStatic blue = new PenStatic("blue");
PenStatic red3 = new PenStatic("Red");
//변경 전(PenMainExam)
//System.out.println(red3.getAllCount()); //이렇게 사용한다.
//System.out.println(red.count);//되록 사용x, 이유 :
//static필드 호출 : 클래스명.필드명
System.out.println(PenStatic.count);
//private가 필드에 붙으면, 외부에서 호출할수없다.
//변경 후(PenStaticMainExam)
//static 메소드 호출 : 클래스명.메소드명()
System.out.println(PenStatic.getCount());
System.out.println(PenStatic.getAllcount());
//필드에 private가 붙어도 상관없이 메소드의 접근제한만 영향을 받는다.
}
day16/staticmember/PenStatic
//#1. 필드
private String color; //인스턴스 필드, 필드
//1). static 붙은거는 공통으로 사용한다.
//클래스영역(메소드영역,데이터영역)
//클래스 안에서 생성
//메소드 영역은 클래스가 메모리에 올라갈떄('로드된다' 라고한다.) 메모리와 함께 선언한다.
//그래서 어디서나 가져다 쓸 수 있음
//외부에서 사용할때 : 클래스명.필드명
// 클래스명.메소드명()
/*
private static int count = 0; //static 필드 : 외부에서 못고친다.
private static int allCount = 0; //static 필드
*/
private static int count = 0; //static 필드 : 외부에서 못고친다.
static int allCount = 0; //static 필드
//#2. 생성자
public PenStatic(String color) {
this.color = color;
//#2-1 색상이 red인 것만 누적
if(color.equalsIgnoreCase("red")) {
count++;
}
//#2-2.객체 생성시 마다 누적하기
allCount ++; // allCount = allCount + 1;
}// 생성자의 끝
//*문제가 생긴다. 이유는 static자가 붙은 것을 호출해도 상관은 없는데,
//되도록이면, static을 붙여야 좋다.
//빨강 펜 개수
public static int getCount() { //인스턴스 메소드
return count; //인스턴스 메소드에서 static 필드 호출해 사용가능?
//그러나 static이 붙은 static 메소드에서는
//인스턴스 필드 호출 할 수 없음
}
//전체 펜 개수
public static int getAllcount() {//필드 메소드
return allCount; //필드 리턴
}
*
static이 있는 위치
-데이터영역( class뱃속 안에) - 객체를 만들면서 누적시킴, 공통영역…
-스택영역
-힙영역
*static에 있는 공통된 변수값
굳이, 객체이름을 부르지 않고, 클래스 이름으로 불러도 값을 가져올수 있다.
객체를 불러도 클래스위치에 있는 값으로 다시 가기때문이다.
클래스이름으로 부른다는 것은 힙을 통해서 가지 않고 다이렉트로 클래스에서 있는 것을 호출한다.
객체(인스턴스)
*
필드에, static이 안붙으면 (힙영역)‘객체 안’에서 필드가 생성
필드에, staitc이 붙으면, (데이터영역)클래스안에 필드가 생성
class
생성자
static붙으면 클래스안에 필드를 생성한다.
클래스안에서, 메소드가 설계만 올려놓는것,
(메모리에 올려다 놓았다 라는것, 부를때 바로 생성한다.)
가져다가 실행하는 것,
static의실제 계산은 데이터영역에서 계산된다.
그러므로, 힙영역은 데이터영역의 주소를 가지고 있다.
각각의 프로그램은 필요할떄, 부르게 된다.
스타틱 - 실행하자마자 책상 위
인스턴스 - 책상서랍위, 필요할떄 꺼내야한다.
*어느뱃속
-static가 붙으면, 클래스안에서 공통으로 쓰여진다. static부른 메소드와 일치. 클래스안(데이터영역안에서 한다.
-static가 안 붙으면, 힙영역에서 개인객체로 쓰여진다. 계산 힙영역에서 한다.
1.스타틱의 사용여부.
스타틱을 붙일때와 붙이지 않을떄,
ex)학생 - 원래기존의 핛
개별성적 인스턴스 필드
학번 - 스타틱 필드(번호누적)
ex)커피
종류는 정해져있는 것
똑같은 제품명 - 스타틱
똑같은 가격 - 스타틱
판매 클래스
공급관련 클래스
ex)체인점
똑같은 메뉴
기본 가격 (유동인구,임대료)
- 각각에 개별역할 써야할떄,
- 공통 /사용/처리할때(누적,통계 할떄 사용할때)
static은 객체를 생성하지 않아도 사용할 수 있다.
인스턴스 필드는 객체를 생성해야만 쓸수 있다.
객체생성 못하게 하는 방법
final private 이외에 다른곳은 못쓰게 하는 것
●
●
CoffeeCountMain
CoffeeCount2
CoffeeCount
public class CoffeeCountMain {
public static void main(String[] args) {
CoffeeCount coffee1 = new CoffeeCount("커피");
CoffeeCount tea1 = new CoffeeCount("녹차");
CoffeeCount coffee2 = new CoffeeCount("coffee");
CoffeeCount coke = new CoffeeCount("coke");
/*
(1)
System.out.println("전체 주문 : " + CoffeeCount.allcount); //4(정답 4) //private 로인해 오류
System.out.println("커피 주문 : " + CoffeeCount.coffeeCount); //2(정답 2) //private 로인해 오류
*/
//(2)
//private로 접근제한자로 만들고 부를려면 getter로 불러오게 한다.(setter는 되도록 만들지 않기)
System.out.println("전체 주문 : " + CoffeeCount.getAllcount());
System.out.println("커피 주문 : " + CoffeeCount.getCoffeeCount());
}
public class CoffeeCount2 {
//인스턴스 필드,
private String beverage;
//static 필드, private이 붙어 있어서 이 클래스 내에서만 호출 할 수 있다.
private static int allcount = 0; //전체 음료 판매건수
private static int coffeeCount = 0; //커피 주문 건수
//생성자 - 음료 종류를 입력 받음
public CoffeeCount2(String beverage) {
this.beverage = beverage;
//static(=정적필드) : 사용법 = 클래스명.필드명
//스타틱 필드에는 this를 안붙인다. 이유 : this를 붙인다는거는 객체 나 자신을 의미한다.
//ex) this.allcount ++; (x) >>> allcount++;
boolean eq = beverage.equals("커피") || beverage.equalsIgnoreCase("coffee");
if(eq) {
coffeeCount++;
}//end of if
}//end of construct
public String getBeverage() {
return beverage;
}
//static이 붙은거는 static부은게 좋다.
public static int getAllcount() {
return allcount;
}
//static이 붙은거는 static부은게 좋다.
public static int getCoffeeCount() {
return coffeeCount;
}
public class CoffeeCount {
//인스턴스 필드,
private String beverage;
//static 필드, private이 붙어 있어서 이 클래스 내에서만 호출 할 수 있다.
private static int allcount = 0; //전체 음료 판매건수
private static int coffeeCount = 0; //커피 주문 건수
//생성자 - 음료 종류를 입력 받음
public CoffeeCount(String beverage) {
this.beverage = beverage;
//static(=정적필드)
allcount ++;
//스타틱 필드에는 this를 안붙인다. 이유 : this를 붙인다는거는 객체 나 자신을 의미한다.
//ex) this.allcount ++; (x) >>> allcount++;
boolean eq = beverage.equals("커피") || beverage.equalsIgnoreCase("coffee");
if(eq) {
coffeeCount++;
}//end of if
}//end of construct
public String getBeverage() {
return beverage;
}
//static이 붙은거는 static부은게 좋다.
public static int getAllcount() {
return allcount;
}
//static이 붙은거는 static부은게 좋다.
public static int getCoffeeCount() {
return coffeeCount;
}
}
●
CoffeeCountMain2
CoffeeCount2
CoffeeStaticCount
public class CoffeeCountMain2 {
public static void main(String[] args) {
//커피 주문, 객체 생성
CoffeeCount2 coffee1 = new CoffeeCount2("커피");
CoffeeCount2 tea1 = new CoffeeCount2("녹차");
CoffeeCount2 coke = new CoffeeCount2("콜라");
CoffeeCount2 coffee2 = new CoffeeCount2("coffee");
//확인
//정적필드(static필드)
System.out.println("전체 판매 : " + CoffeeStaticCount.allCount);
System.out.println("커피 판매 : " + CoffeeStaticCount.coffeeCount);
}
}
public class CoffeeCount2 {
//인스턴스 필드,
private String beverage;
//static 필드, private이 붙어 있어서 이 클래스 내에서만 호출 할 수 있다.
private static int allcount = 0; //전체 음료 판매건수
private static int coffeeCount = 0; //커피 주문 건수
//생성자 - 음료 종류를 입력 받음
public CoffeeCount2(String beverage) {
this.beverage = beverage;
//static(=정적필드) : 사용법 = 클래스명.필드명
CoffeeStaticCount.allCount++;
//스타틱 필드에는 this를 안붙인다. 이유 : this를 붙인다는거는 객체 나 자신을 의미한다.
//ex) this.allcount ++; (x) >>> allcount++;
boolean eq = beverage.equals("커피") || beverage.equalsIgnoreCase("coffee");
if(eq) {
CoffeeStaticCount.allCount++;
}//end of if
}//end of construct
public String getBeverage() {
return beverage;
}
//static이 붙은거는 static부은게 좋다.
public static int getAllcount() {
return allcount;
}
//static이 붙은거는 static부은게 좋다.
public static int getCoffeeCount() {
return coffeeCount;
}
}
public class CoffeeStaticCount {
/*
int allCount =0; //인스턴트 필드 //객체를 생성해야 사용 가능
int coffeeCount = 0; //인스턴트 필드 //객체를 생성해야 사용 가능
*/
static int allCount =0; //인스턴트 필드 //객체를 생성해야 사용 가능
static int coffeeCount = 0; //인스턴트 필드 //객체를 생성해야 사용 가능
//생성자에private을 붙이면 외부에서는 객체를 생성할 수 없음
private CoffeeStaticCount() {};
}
●
Calculator
CalculatorExam
public class Calculator {
//final - 여기 외에는 다른 곳에서 수정할 수 없음
//static - 공통
final static double PI = 3.14152; // 상수
static int jumsu1 = 7;
int instanceValue =3;
static int plus(int x, int y) {
return x + y;
}
static int minus(int x, int y) {
return x - y;
}
void showInfo(int num1, int num2) {
int result = plus(num1, num2);
System.out.println("결과:" + plus(num1,num2));
System.out.println(result);
System.out.println();
}
static void printShow() {
System.out.println(instanceValue);
showInfo(10,20);
}
//저장공간이 static은 클래스영역- 데이터영역
//인스턴스 필드나 메소드는 -객체안 힙영역
//객체가 만들어져야 메소드를 실행할수있다.
//메모리에 올라오는 순서가 달라서
//인스턴스는 객체 생성할때 메모리에 올라온다
//반면 스타틱은 바로메모리에 올라온다.
//스타틱붙은거는 스타틱붙인 상태에서 부를수있다.
//인스턴스는 언제 메모리 올라올지 모른다
}
public class CalculatorExam {
public static void main(String[] args) {
double result1 = 10 * 10 * Calculator.PI;
int result2 = Calculator.plus(10, 5);
int result3 = Calculator.minus(10, 5);
System.out.println("result1 : " + result1);
System.out.println("result2 : " + result2);
System.out.println("result3 : " + result3);
}
}
●
SingletonExam
SingletonExamMain
public class SingletonExam {
//#1. 생성자 - 생성자의 이름은 클래스명과 같다
// 생성자의 제한 타입이 private이면
// 외부에서는 객체를 생성할 수 있음
// 내부에서는 객체 생성 가능
private SingletonExam() {} //기본 생성자
//#2. 필드 - 정적 필드(=static(필드))
//접근제한자 static 참조타입 참조변수
private static SingletonExam instance = new SingletonExam();
//static이기에, 클래스에 주소값이 있다.
//힙에 값이 있고.
//getter를 이용해서 불러간다
//#3. 메소드
//리턴타입(반환타입) 메소드명(){}
static SingletonExam getInstance() {
return instance; //singletonExam 클래스를 가지고 만든 인스턴스(객체)를 반환
//SingletonExam형의 주소인 instance를 반환한다.
//getter를 이용해서 불러간다.
}
}
public class SingletonExamMain {
public static void main(String[] args) {
//에러 - 생성자가 private로 되어있기에,
//외부에서 객체 생성할 수 없음
//SingletonExam singleObj1 = new SinglentonExam();
SingletonExam singleObj1 = SingletonExam.getInstance();
SingletonExam singleObj2 = SingletonExam.getInstance();
//싱글톤 주소값 비교
if(singleObj1==singleObj2) {
System.out.println("같은 객체");
}else {
System.out.println("다른 객체");
}
}
//싱글톤
//장점
//단점도 있다.
//그래서 상황에 맞게 써야한다.
//객체를 단하나만 생성하는 것이 싱글톤이다.
//생성자에다가 private 붙이면, 외부에서 객체생성 x 내부에서 생성 ok
}
●
Person
PersonExample
public class Person {
final String nation = "Korea"; //final 필드
final static String NATION = "Korea"; // 상수 - 한번만들면 그누구도 못바꿈, static이라서 데이터영역으로 바로 만들어진다.
final String ssn;
String name;
final static int test = 10;
//final static int test는 final String ssn 과 다르다, static이라는 공통된 영역에, 이미 한번 선언했다.
//final String ssn는 객체가 생성할때, 만들어지기 떄문에, 생성자에 변수를 써도 무방하다. final static과는 다르다.
//*필드와 상수를 구분.
//#2. 생성자
public Person(String ssn, String name) {
super();
this.ssn = ssn;
this.name = name; //
// this.test = 0; final static 상수 이기때문에...
}
/*
//nation은 이미 선언과 동시에 초기화가 되어 있어서
//이것을 변경할 수 없음
public Person(String nation, String ssn, String name) {
this.nation = nation; // 파이널은 딱 한번 초기화되면, 고칠수가 없다.
this.ssn = ssn;
this.name = name;
}
*/
}
public class PersonExample {
public static void main(String[] args) {
Person p1 = new Person("12345", "홍길동");
System.out.println(p1.nation);
System.out.println(p1.ssn);
System.out.println(p1.name);
/*
p1.nation = "usa"; //nation 이 final 필드 이므로
// 초기화 시킨 후에는 값을 변경 할 수 없음
p1.ssn = "45678";
p1.name = "김자바"; //인스턴스 필드 - 언제든 변경 가능
*/
//객체를 생성한다음에, 변경할 수는 없다.
//그러나 새로운 객체를 생성할때, 값을 집어넣어서 초기화 시켜준다면 가능하다.
//파이널 필드는 그 객체를 단 한번 초기화 하지만,
//새로운 객체를 만들때는, 또 한번 초기화 시킬수있다라는 말.
Person p2 = new Person("7090","wer");
System.out.println(p1.nation);
System.out.println(p1.ssn);
System.out.println(p1.name);
//final 선언, 이미해서 안된다.
// p1.test = 30; //final static으로 이미 선언과 동시에 초기화 되었으므로
// Person.test = 30; //이미 선언과 동시에 초기화 되어 있는 상수이므로
//final static임
}
}
●
기존 문제 : Print
내가 변경한 클래스
'1. JAVA > 3). 자바_개념' 카테고리의 다른 글
자바_개념_Day_18 (1) | 2024.01.24 |
---|---|
자바_개념_Day_17 (1) | 2024.01.23 |
자바_개념_Day_15 (0) | 2024.01.19 |
자바_개념_Day_14 (0) | 2024.01.18 |
자바_개념_Day_13 (0) | 2024.01.17 |