Java 정리(4월 19일)

47095 단어 JavaJava

TIP

final 상수값 최대한 활용하기

    final int maxHp = 50;       //최대 hp
    final int maxMp = 10;       //최대 mp
    String name;                //이름
    int hp = 50;                 //hp
    int mp = 10;                 //mp

위와 같이 초기화 하는것보단 상수값 최대한 활용해서 아래처럼 짜는것이 좋다

    final int maxHp = 50;       //최대 hp
    final int maxMp = 10;       //최대 mp
    String name;                //이름
    int hp = maxHp;                 //hp
    int mp = maxMp;                 //mp

또한 클래스에서 static 변수를 제외한 초기화는 생성자를 이용해서 하는것이 좋다

Code Test 방법

1. white box test

화이트박스 검사(White Box Test) 기법은 소프트웨어 내부 소스 코드를 테스트하는 기법이다.

테스트 예제 코드

import org.junit.Before;
import org.junit.Test;

import java.util.Random;

import static org.junit.Assert.*;

public class ClericTest {
    Cleric cleric;
    Random random = new Random();

    @Before
    public void setUp() {
        cleric = new Cleric();
    }

    @Test
    public void selfAid() {
        for (int i = 0; i < 100; i++) {
            cleric.mp = cleric.maxMp;
            cleric.hp = random.nextInt(51);
            cleric.selfAid();
            assertEquals(cleric.maxHp, cleric.hp);
        }

        for (int i = 0; i < 100; i++) {
            cleric.mp = 4;
            int hp = random.nextInt(51);
            cleric.hp = hp;
            cleric.selfAid();
            assertEquals(hp, cleric.hp);
        }
    }

    // 이전 mp 와
    @Test
    public void pray() {
        for (int i = 0; i < 100; i++) {
            int sec = random.nextInt(11);
            int mp = random.nextInt(11);

            cleric.mp = mp;
            int recoveryMp = cleric.pray(sec);

            assertTrue(cleric.mp <= cleric.maxMp);
            assertEquals(mp + recoveryMp, cleric.mp);
        }
    }
}

2. black box test

블랙박스 검사 기법은 소프트웨어의 내부를 보지 않고, 입력과 출력값을 확인하여, 기능의 유효성을 판단하는 테스트 기법이다

클래스

메모리 영역

그럼 여기서 static 변수는 어디에 저장이 될까?
static 변수는 객체에 같이 포함되는것이 아니라 DATA 영역에 저장된다

클래스 참조

package com.jinho.day7;

public class Code01 {
    public static void main(String[] args) {
        Hero hero1 = new Hero();
        hero1.hp = 100;

        Hero hero2 = hero1;
        hero2.hp = 200;

        System.out.println(hero1.hp);


    }
}

위와같은 예제 문제에서 hero1.hp 는 어떤값이 나올까?

그림에서 볼수 있듯이 200이 나온다

다른 클래스 형을 필드로 가지는 클래스

Sword 클래스

package com.jinho.day7;

public class Sword {
    String name;
    int damage;
}

Sword 클래스를 포함한 Hero 클래스

package com.jinho.day7;

public class Hero {
    
    
    String name;
    int hp;
    Sword sword;


    void attack() {
        System.out.println(this.name + "는 공격했다!");
        System.out.println("적에게 5포인트의 데미지를 주었다");
    }
}

main 문

package com.jinho.day7;

public class Code02 {
    public static void main(String[] args) {


        Sword sword = new Sword();
        sword.name = "불의 검";
        sword.damage = 10;


        Hero hero = new Hero();
        hero.hp = 100;
        hero.sword = sword;


        System.out.println("현재의 무기는 " + hero.sword.name);


    }
}

클래스 형을 인자로 가지는 클래스

Hero 클래스를 인자로 가지는 Wizard 클래스

package com.jinho.day7;

public class Wizard {
    String name;
    int hp;

    void heal(Hero hero) {
        hero.hp += 10;
        System.out.println(hero.name + "의 hp를 10만큼 회복했다!!");
    }

}

main 문

package com.jinho.day7;

public class Code03 {
    public static void main(String[] args) {
       
        Hero hero1 = new Hero();
        hero1.name = "최진호";
        hero1.hp = 100;

        Wizard wizard = new Wizard();
        wizard.name = "닥터 스트레인지";
        wizard.hp = 100;

        System.out.println(hero1.hp);
        wizard.heal(hero1); 
        System.out.println(hero1.hp);   
    }
}

String 타입의 확인

아래와 같은 코드를 실행하면 겉보기엔 name 변수에 "김진호" 가 업데이트 된것 같지만
String 타입 변수는 reference type 으로 new 가 생략되어있는것이다
따라서 새로운 메모리가 new 로 만들어 지고 가리키는 주소값만 바꾸어주었을 뿐이다!!

package com.jinho.day7;

public class Code04 {
    public static void main(String[] args) {
        String name = "최진호";
        name = "김진호";

    }
}

그래서 name = name + "i" 와 같이 string 을 붙여주는 경우
뒤에 붙은것처럼 보이나 이것 또한 new로 새로 만들어서 주소값만 바꾼것이다
따라서 문자열을 합칠때는 StringBuilder 을 사용해야한다

이것들에 대한 해시코드와 예제이다

package com.jinho.day7;

public class Code04 {
    public static void main(String[] args) {
        String name = "최진호";

        for (int i = 0; i < 10; i++) {
            name = name + "i";
            System.out.println(name.hashCode() + "   " + name);
        }

        System.out.println();
        System.out.println();

        StringBuilder sb = new StringBuilder("최진호");
        for (int i = 0; i < 10; i++) {
            sb.append("i");
            System.out.println(sb.hashCode() + "   " + sb);
        }

    }
}

생성자 예제

클래스는 생성자가 꼭 필요하다


package com.jinho.day7.quiz9;

import java.util.Random;

public class Cleric {

    static final int maxHp = 50;       //최대 hp
    static final int maxMp = 10;       //최대 mp
    String name;                //이름
    int hp;                 //hp
    int mp;                 //mp


    //생성자 A (이름,hp,mp)
    Cleric(String name, int hp, int mp) {
        this.name = name;
        this.hp = hp;
        this.mp = mp;
    }

    //생성자 B  (이름,hp)
    Cleric(String name, int hp) {
        this.name = name;
        this.hp = hp;
        this.mp = Cleric.maxMp;
    }

    //생성자 C (이름)
    Cleric(String name) {
        this.name = name;
        this.hp = Cleric.maxHp;
        this.mp = Cleric.maxMp;

    }
    
    //기본 생성자
    Cleric() {
    
    }

}

위 예제는 생성자를 오버로드해서 여러개 만든 예제이다
A -> 이름,HP,MP
B -> 이름,HP
C -> 이름
D -> 기본생성자

여기서 기본생성자를 만드는 이유??

우리가 생성자를 만들지 않으면 기본생성자가 있다고 가정해서 호출한다
즉 생성자는 무조건 1개는 있어야만한다

근데 만약 기본생성자 말고 다른 생성자를 오버로드 해서 만들면 기본생성자가 없다고 인식해서 기본생성자로 만드는 방식은 오류가 난다

따라서 생성자 오버로드해서 만든경우에는 기본생성자도 만들어주어야한다

package com.jinho.day7.quiz9;


public class GameMain {
    public static void main(String[] args) {

        System.out.println("static 최대 HP : " + Cleric.maxHp);
        System.out.println("static 최대 MP : " + Cleric.maxMp);

        Cleric clericA = new Cleric("jinHo", 30, 20);
        Cleric clericB = new Cleric("minHo", 15);
        Cleric clericC = new Cleric("lala");

        //Cleric clericD = new Cleric(); 기본생성자 안되도록 했음


        System.out.printf("이름 : %s  HP : %d  MP : %d\n", clericA.name, clericA.hp, clericA.mp);
        System.out.printf("이름 : %s  HP : %d  MP : %d\n", clericB.name, clericB.hp, clericB.mp);
        System.out.printf("이름 : %s  HP : %d  MP : %d\n", clericC.name, clericC.hp, clericC.mp);


    }
}

static 예제

package com.jinho.day7;

public class StaticExample {

    static int staticNum = 5;
    int justNum = 10;

    static void staticMethod() {
        System.out.println("staticMethod");
    }

    void justMethod() {
        System.out.println("justMethod");
    }

}
package com.jinho.day7;

public class Code06 {
    public static void main(String[] args) {

        //int num = StaticExample.justNum;   static이 아닌 인스턴스 변수는 무조건 new로 객체를 생성해야만 사용할수있다
        int num = StaticExample.staticNum;  //static 으로 정의한 클래스 변수는 new로 객체 생성하지않아도 사용할수있다 프로그램 시작과 동시에 DATA 영역에 저장되기때문이다
        System.out.println(num);

        //StaticExample.justMethod();   //매서드도 변수와 동일하다
        StaticExample.staticMethod();


        //아래처럼 new로 객체 생성하면 인스턴스 변수, 인스턴스 메서드 모두 사용이 가능하다
        StaticExample ex = new StaticExample();
        num = ex.justNum;
        System.out.println(num);
        ex.justMethod();

    }
}

static으로 정의한 클래스 변수,메서드 는 프로그램 시작과 동시에 DATA 영역에 저장이 되기 때문에

따로 new로 객체를 생성하지 않아도 사용할수있다

다만 static으로 정의하지 않은 인스턴스 변수,메서드는 무조건 new로 객체를 생성해야만
사용할수있다

그리고 static 변수,메서드는 사용할때 그 클래스 이름으로 사용해야한다

좋은 웹페이지 즐겨찾기