[Java(8)] 생성자, static, string 클래스

2026. 6. 24. 00:09·웹 개발/JAVA

안녕하세요~ 경제적 자유입니다.

오늘은 Java의 생성자(Constructor), static 키워드, String 클래스에 대해 정리해보려고 합니다.

 

더 자세히 공부하고 싶다면 아래 문서도 함께 참고해보세요.

  • 참고 링크: Java Constructors
  • 참고 링크: Java static Keyword
  • 참고 링크: Java String

 


 

1. 객체가 만들어질 때 실행되는 생성자

 

생성자(Constructor)는 클래스를 이용해 객체를 만들 때 호출되는 특별한 코드입니다.

 

Person person = new Person("상구");

 

위 코드에서 new Person("상구")가 실행되면 새로운 Person 객체가 만들어지고, 그 과정에서 Person 클래스의 생성자가 호출됩니다.

 

  • 생성자 이름은 클래스 이름과 같아야 합니다.
  • 생성자에는 반환형을 작성하지 않습니다.
  • 객체를 생성할 때 호출됩니다.

 

생성자의 기본 문법

class 클래스이름 {

    클래스이름() {
        // 객체가 생성될 때 실행할 코드
    }
}

 

예를 들어 클래스 이름이 Person이라면 생성자 이름도 Person이어야 합니다.

 

class Person {

    Person() {
        // Person 객체가 생성될 때 실행
    }
}

 

다음과 같이 반환형을 작성하면 생성자가 아니라 일반 메서드가 됩니다.

 

class Person {

    void Person() {
        // 생성자가 아니라 이름이 Person인 일반 메서드
    }
}

 

겉보기에는 비슷하지만 void가 붙어 있기 때문에 생성자가 아닙니다.

 

매개변수가 없는 생성자

 

생성자는 매개변수 없이 만들 수 있습니다.

이러한 생성자를 매개변수가 없는 생성자 또는 no-argument constructor라고 부릅니다.

class Person {
    String name;

    Person() {
        name = "상구";
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person();

        System.out.println(person.name);
    }
}

// 실행 결과:
// 상구

 

new Person()이 실행되면 Person() 생성자가 호출됩니다.

생성자 안에서 name에 "상구"를 저장했기 때문에 새로 만들어진 객체의 이름은 처음부터 "상구"가 됩니다.

 

매개변수가 있는 생성자

객체를 만들 때 외부에서 값을 전달하려면 생성자에 매개변수를 선언할 수 있습니다.

class Person {
    String name;

    Person(String personName) {
        name = personName;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("상구");

        System.out.println(person.name);
    }
}

// 실행 결과:
// 상구

 

new Person("상구")에서 전달한 "상구"는 생성자의 personName 매개변수로 들어갑니다.

 

name = personName;

 

오른쪽의 personName에는 전달받은 "상구"가 들어 있고, 그 값이 객체의 name 변수에 저장되는 흐름입니다.

보통은 필드와 매개변수의 이름을 같게 작성하고 this를 사용하기도 합니다.

 

class Person {
    String name;

    Person(String name) {
        this.name = name;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("상구");

        System.out.println(person.name);
    }
}

// 실행 결과:
// 상구

 

여기에서 this.name은 현재 만들어지고 있는 객체의 name 변수를 의미합니다.

오른쪽의 name은 생성자로 전달받은 매개변수입니다.

따라서 다음 코드는 전달받은 이름을 현재 객체의 이름으로 저장한다는 뜻입니다.

 

this.name = name;

 

기본 생성자는 무엇일까?

클래스에 생성자를 하나도 작성하지 않으면 Java 컴파일러가 자동으로 매개변수가 없는 생성자를 제공합니다.

이렇게 컴파일러가 자동으로 제공하는 생성자를 기본 생성자(default constructor)라고 합니다.

class Person {
    String name;
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person();

        System.out.println(person.name);
    }
}

// 실행 결과:
// null

 

Person 클래스에는 직접 작성한 생성자가 없지만 new Person()을 사용할 수 있습니다.

컴파일러가 다음과 비슷한 형태의 기본 생성자를 자동으로 제공하기 때문입니다.

 

Person() {
}

 

name에는 별도의 문자열을 저장하지 않았기 때문에 참조 자료형의 기본값인 null이 출력됩니다.

 

생성자를 하나라도 직접 작성하면 컴파일러는 기본 생성자를 자동으로 추가하지 않습니다.

 

class Person {
    String name;

    Person(String name) {
        this.name = name;
    }
}

public class Main {
    public static void main(String[] args) {
        // Person person = new Person();
        // 오류: 매개변수가 없는 생성자가 존재하지 않음

        Person person = new Person("상구");

        System.out.println(person.name);
    }
}

// 실행 결과:
// 상구

 

현재 Person 클래스에는 Person(String name) 생성자만 있습니다.

따라서 반드시 문자열을 전달해야 하며, new Person()처럼 매개변수 없이 객체를 만들 수는 없습니다.

 

생성자 오버로딩

하나의 클래스에 매개변수가 서로 다른 생성자를 여러 개 만들 수도 있습니다.

이를 생성자 오버로딩(Constructor Overloading)이라고 합니다.

 

class Person {
    String name;
    int age;

    Person() {
        name = "이름 없음";
        age = 0;
    }

    Person(String name) {
        this.name = name;
        age = 0;
    }

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person();
        Person person2 = new Person("상구");
        Person person3 = new Person("상구", 28);

        System.out.println(person1.name + ", " + person1.age);
        System.out.println(person2.name + ", " + person2.age);
        System.out.println(person3.name + ", " + person3.age);
    }
}

// 실행 결과:
// 이름 없음, 0
// 상구, 0
// 상구, 28

 

전달하는 값의 개수와 자료형에 따라 서로 다른 생성자가 호출됩니다.

 


 

2. 객체가 아니라 클래스에 속하는 static

 

필드(field)는 객체가 가지고 있는 데이터, 메서드(method)는 객체가 할 수 있는 행동

 

하지만 모든 객체가 같은 값을 공유해야 하는 경우에 사용할 수 있는 것이 static 키워드입니다.

 

static이 붙은 변수와 메서드는 특정 객체가 아니라 클래스 자체에 속합니다.

 

static 변수의 기본 문법

class 클래스이름 {
    static 자료형 변수이름;
}

 

예를 들어 다음과 같이 작성할 수 있습니다.

 

class Person {
    static int count = 0;
}

 

count는 각각의 Person 객체에 따로 만들어지는 변수가 아닙니다.

Person 클래스에 하나만 만들어지고, 모든 Person 객체가 그 값을 공유합니다.

 

static 변수 예제

class Person {
    String name;
    static int count = 0;

    Person(String name) {
        this.name = name;
        count++;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person("상구");
        Person person2 = new Person("민수");

        System.out.println(person1.name);
        System.out.println(person2.name);
        System.out.println(Person.count);
    }
}

// 실행 결과:
// 상구
// 민수
// 2

 

첫 번째 객체가 만들어질 때 count++가 실행되어 count가 1이 됩니다.

두 번째 객체가 만들어질 때 다시 count++가 실행되어 2가 됩니다.

 

count는 특정 객체의 값이 아니라 Person 클래스가 공유하는 값이기 때문에 다음과 같이 클래스 이름으로 접근했습니다.

 

Person.count

 

Java에서는 객체를 통해서도 static 변수에 접근할 수 있지만, 어떤 클래스의 값인지 명확하게 드러나도록 클래스 이름으로 접근하는 것이 좋습니다.

 

인스턴스 변수와 static 변수의 차이

class Person {
    String name;
    static int count = 0;
}

 

위 코드에서 두 변수는 소속이 다릅니다.

  • name은 객체마다 따로 존재하는 인스턴스 변수입니다.
  • count는 클래스에 하나만 존재하는 static 변수입니다.

 

class Person {
    String name;
    static int count = 0;

    Person(String name) {
        this.name = name;
        count++;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person("상구");
        Person person2 = new Person("민수");

        System.out.println(person1.name);
        System.out.println(person2.name);
        System.out.println(Person.count);
    }
}

// 실행 결과:
// 상구
// 민수
// 2

 

 

static 메서드의 기본 문법

메서드에도 static을 붙일 수 있습니다.

class 클래스이름 {

    static 반환자료형 메서드이름() {
        // 실행할 코드
    }
}

 

static 메서드는 객체를 만들지 않고 클래스 이름으로 호출할 수 있습니다.

 

class Greeting {

    static void sayHello(String name) {
        System.out.println(name + "님, 안녕하세요!");
    }
}

public class Main {
    public static void main(String[] args) {
        Greeting.sayHello("상구");
    }
}

// 실행 결과:
// 상구님, 안녕하세요!

 

Greeting 객체를 생성하지 않았지만 다음과 같이 메서드를 호출할 수 있습니다.

 

Greeting.sayHello("상구");

 

sayHello()가 Greeting 객체가 아니라 Greeting 클래스에 속한 static 메서드이기 때문입니다.

 

static 메서드에서 인스턴스 변수에 바로 접근할 수 없는 이유

 

static 메서드는 객체를 만들지 않아도 호출할 수 있습니다.

그런데 인스턴스 변수는 객체가 만들어져야 존재합니다.

따라서 static 메서드에서는 특정 객체의 인스턴스 변수를 바로 사용할 수 없습니다.

 

class Person {
    String name = "상구";

    static void printName() {
        // System.out.println(name);
        // 오류: static 메서드에서 인스턴스 변수에 바로 접근할 수 없음
    }
}

 

printName()을 호출하는 시점에는 어떤 Person 객체의 name을 사용해야 하는지 알 수 없습니다.

인스턴스 변수에 접근하려면 먼저 객체를 만들어야 합니다.

 

class Person {
    String name = "상구";

    static void printName() {
        Person person = new Person();

        System.out.println(person.name);
    }
}

public class Main {
    public static void main(String[] args) {
        Person.printName();
    }
}

// 실행 결과:
// 상구

 

객체를 만든 다음 person.name처럼 접근하면 어떤 객체의 변수인지 분명해집니다.

 

main 메서드에 static이 붙는 이유

Java 프로그램을 실행할 때 JVM은 다음 메서드를 찾아서 호출합니다.

public static void main(String[] args)

 

프로그램이 시작되는 시점에는 아직 Main 객체가 만들어지지 않았습니다.

따라서 JVM이 객체를 생성하지 않고도 main()을 호출할 수 있도록 static이 붙어 있습니다.

 

public class Main {
    public static void main(String[] args) {
        System.out.println("프로그램 시작");
    }
}

// 실행 결과:
// 프로그램 시작

 

main()은 특정 Main 객체의 동작이라기보다 프로그램 실행을 시작하는 클래스 메서드라고 볼 수 있습니다.

 


 

3. 문자열을 객체로 다루는 String

Java에서 문자열은 String을 사용해 표현합니다.

String name = "상구";

 

겉으로 보기에는 int, double, boolean 같은 기본 자료형과 비슷해 보이지만, String은 기본 자료형이 아닙니다.

String은 문자열을 다루기 위해 Java에서 제공하는 클래스입니다.

String 클래스는 java.lang 패키지에 들어 있습니다.

java.lang 패키지는 Java에서 자동으로 불러오기 때문에 별도의 import 없이 사용할 수 있습니다.

 

String의 기본 문법

문자열 리터럴을 사용하면 다음과 같이 만들 수 있습니다.

String 변수이름 = "문자열";

 

예를 들어 이름을 저장한다면 다음과 같습니다.

 

String name = "상구";

 

new를 사용해 직접 String 객체를 만들 수도 있습니다.

 

String name = new String("상구");

 

두 코드 모두 문자열을 만들 수 있지만, 일반적인 문자열은 다음처럼 문자열 리터럴을 사용하는 방식이 더 간단하고 널리 사용됩니다.

 

String name = "상구";

문자열 출력과 연결

문자열은 + 연산자를 사용해 연결할 수 있습니다.

public class Main {
    public static void main(String[] args) {
        String name = "상구";
        String message = name + "님, 반갑습니다.";

        System.out.println(message);
    }
}

// 실행 결과:
// 상구님, 반갑습니다.

 

+ 연산자는 숫자끼리 사용하면 덧셈을 수행하지만, 문자열이 포함되면 값을 하나의 문자열로 연결합니다.

 

public class Main {
    public static void main(String[] args) {
        String name = "상구";
        int age = 28;

        System.out.println(name + "의 나이는 " + age + "살입니다.");
    }
}

// 실행 결과:
// 상구의 나이는 28살입니다.

 

문자열과 숫자를 함께 연결하면 숫자도 문자열 형태로 이어집니다.

 

자주 사용하는 String 메서드

String은 클래스이기 때문에 문자열을 다룰 수 있는 여러 메서드를 제공합니다.

public class Main {
    public static void main(String[] args) {
        String name = "상구";

        System.out.println(name.length());
        System.out.println(name.charAt(0));
        System.out.println(name.contains("상"));
    }
}

// 실행 결과:
// 2
// 상
// true

 

length()는 문자열의 길이를 반환합니다.

 

name.length()

 

"상구"는 두 글자이므로 2가 반환됩니다.

charAt(0)은 지정한 위치의 문자를 하나 가져옵니다.

 

name.charAt(0)

 

Java의 위치 번호는 0부터 시작하기 때문에 0번 위치에는 '상'이 있습니다.

contains("상")은 문자열 안에 해당 내용이 포함되어 있는지 확인합니다.

 

name.contains("상")

 

"상구" 안에는 "상"이 들어 있으므로 true가 반환됩니다.

 

문자열 비교에는 equals를 사용한다

문자열을 비교할 때는 ==보다 equals() 메서드를 사용해야 합니다.

public class Main {
    public static void main(String[] args) {
        String name = new String("상구");

        if (name.equals("상구")) {
            System.out.println("이름이 같습니다.");
        }
    }
}

// 실행 결과:
// 이름이 같습니다.

 

equals()는 문자열의 실제 내용이 같은지 비교합니다.

 

name.equals("상구")

 

반면 ==는 두 변수가 같은 객체를 가리키고 있는지 비교합니다.

 

public class Main {
    public static void main(String[] args) {
        String name1 = new String("상구");
        String name2 = new String("상구");

        System.out.println(name1 == name2);
        System.out.println(name1.equals(name2));
    }
}

// 실행 결과:
// false
// true

 

name1과 name2에는 같은 글자가 들어 있지만 new String()을 통해 서로 다른 객체가 만들어졌습니다.

따라서 객체의 위치를 비교하는 ==의 결과는 false입니다.

하지만 문자열 내용은 둘 다 "상구"이므로 equals()의 결과는 true입니다.

문자열의 내용을 비교하려는 상황에서는 다음과 같이 기억하면 됩니다.

 

문자열1.equals(문자열2)

 

String은 한 번 만들어지면 내용이 바뀌지 않는다

 

Java의 String 객체는 불변 객체(immutable object)입니다.

불변 객체는 한 번 만들어진 뒤 내부 내용이 바뀌지 않는 객체를 뜻합니다.

 

public class Main {
    public static void main(String[] args) {
        String name = "상구";

        name = name + "님";

        System.out.println(name);
    }
}

// 실행 결과:
// 상구님

 

위 코드만 보면 기존의 "상구"가 "상구님"으로 수정된 것처럼 보일 수 있습니다.

하지만 실제로는 기존 문자열의 내용이 바뀐 것이 아닙니다.

 

name + "님"

 

이 연산을 통해 "상구님"이라는 새로운 문자열이 만들어지고, name이 새 문자열을 가리키도록 변경된 것입니다.

흐름을 간단히 표현하면 다음과 같습니다.

 

name → "상구"

name = name + "님"

name → "상구님"

 

기존 "상구" 문자열을 직접 수정한 것이 아니라, 새로운 문자열을 만든 뒤 참조를 바꾼 것입니다.

반복문 안에서 문자열을 계속 이어 붙이면 새로운 String 객체가 여러 번 만들어질 수 있습니다.

문자열을 자주 수정해야 하는 상황에서는 StringBuilder를 사용하는 방법도 있지만, 간단한 문자열 연결에서는 String과 + 연산자만으로도 충분합니다.

 

String 메서드도 원본 문자열을 바꾸지 않는다

 

toUpperCase(), replace() 같은 메서드를 호출해도 원본 문자열 자체가 수정되는 것은 아닙니다.

새로운 문자열을 반환하는 흐름입니다.

 

public class Main {
    public static void main(String[] args) {
        String name = "상구";

        name.replace("상", "민");

        System.out.println(name);
    }
}

// 실행 결과:
// 상구

 

replace()를 호출했지만 반환된 문자열을 저장하지 않았기 때문에 name은 여전히 "상구"를 가리킵니다.

변경된 결과를 사용하려면 반환값을 다시 변수에 저장해야 합니다.

 

public class Main {
    public static void main(String[] args) {
        String name = "상구";

        name = name.replace("상", "민");

        System.out.println(name);
    }
}

// 실행 결과:
// 민구

 

replace()가 반환한 새로운 문자열을 다시 name에 저장했기 때문에 "민구"가 출력됩니다.

 


 

생성자, static, String을 함께 사용해보기

지금까지 정리한 세 가지 개념을 하나의 코드에 함께 사용해보겠습니다.

class Person {
    static int count = 0;

    String name;

    Person(String name) {
        this.name = name;
        count++;
    }

    void introduce() {
        String message = "안녕하세요. 제 이름은 " + name + "입니다.";

        System.out.println(message);
    }

    static void printCount() {
        System.out.println("생성된 사람 수: " + count);
    }
}

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person("상구");
        Person person2 = new Person("민수");

        person1.introduce();
        person2.introduce();

        Person.printCount();
    }
}

// 실행 결과:
// 안녕하세요. 제 이름은 상구입니다.
// 안녕하세요. 제 이름은 민수입니다.
// 생성된 사람 수: 2

 

new Person("상구")가 실행되면 생성자가 호출되고, 전달한 "상구"가 객체의 name에 저장됩니다.

객체가 만들어질 때마다 모든 객체가 공유하는 static 변수 count가 1씩 증가합니다.

introduce()에서는 String과 + 연산자를 사용해 인사 문장을 만들었습니다.

마지막에는 객체를 따로 지정하지 않고 다음과 같이 static 메서드를 호출했습니다.

 

Person.printCount();

 

정리하면 다음과 같은 흐름입니다.

 

생성자 → 객체가 만들어질 때 초기값 설정
static → 모든 객체가 함께 사용할 값이나 기능 관리
String → 이름이나 문장 같은 문자열 데이터 관리

 

각각 따로 보면 단순한 문법이지만, 실제 코드에서는 이렇게 서로 연결되어 사용됩니다.

 


 

마무리

오늘은 Java의 생성자, static 키워드, String 클래스에 대해 정리해봤습니다.

 

특히 문자열과 char이라는 것 그리고 그것을 사용할때 다르게 사용된다는 점이 가장 흥미로웠고 특히 이것은 알고리즘을 사용할 때 매우 편하다는 것을 알 수 있었습니다.

 

공부화이팅!

'웹 개발 > JAVA' 카테고리의 다른 글

[Java(9)] 접근 제한자, this, final  (0) 2026.06.24
[Java(7)] 클래스, 메서드, 오버로딩  (0) 2026.06.19
[Java(5)] 흐름제어: break, continue, switch  (0) 2026.06.18
[Java(6)] 배열, 한번에 여러 값을 다루는 가장 기본적인 방법  (0) 2026.06.18
[Java(4)] 반복문, for문부터 do-while문까지 흐름으로 이해하기  (0) 2026.06.18
'웹 개발/JAVA' 카테고리의 다른 글
  • [Java(9)] 접근 제한자, this, final
  • [Java(7)] 클래스, 메서드, 오버로딩
  • [Java(5)] 흐름제어: break, continue, switch
  • [Java(6)] 배열, 한번에 여러 값을 다루는 가장 기본적인 방법
Sangenie
Sangenie
경제적 자유를 위한 하루 공부.
  • Sangenie
    새싹
    Sangenie
  • 전체
    오늘
    어제
    • 분류 전체보기 (43)
      • AI (0)
        • 하네스 엔지니어링 (0)
      • 웹 개발 (25)
        • Javascript (16)
        • JAVA (9)
      • 토막지식 (1)
      • TIL (7)
      • 경제 (8)
        • 경제뉴스 (7)
        • 비트코인 분석 (1)
      • Library (1)
        • IT (1)
        • Finance (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    프론트엔드
    til
    경제뉴스
    가상자산
    java
    TodayILearned
    자바
    객체
    코딩공부
    자바스크립트
    개발공부
    자바기초
    java공부
    프론트엔드공부
    조건문
    경제공부
    반복문
    JavaScript
    비트코인
    암호화폐
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
Sangenie
[Java(8)] 생성자, static, string 클래스
상단으로

티스토리툴바