자바 방식


이전 장에서는 System.out.println()을 자주 사용했는데 그게 무엇인가요?

println()은 메소드(Method)이고, System은 시스템 클래스(Class)이고, out은 표준 출력 객체(Object)입니다. 이 문장의 사용법은 시스템 클래스 System에 있는 표준 출력 객체의 println() 메서드를 호출하는 것입니다.

그럼 방법은 뭔가요?

Java 메소드는 함께 기능을 수행하는 명령문의 모음입니다.

  • 메서드는 특정 유형의 문제를 해결하기 위한 일련의 단계 조합입니다.

  • 메서드는 클래스나 객체에 포함되어 있습니다.

  • 메서드는 프로그램에서 생성되고 다른 곳에서 참조됩니다.


메소드 정의

일반적으로 메소드 정의에는 다음 구문이 포함됩니다.

修饰符 返回值类型 方法名 (参数类型 参数名){
    ...
    方法体
    ...
    return 返回值;
}

메소드에는 메소드 헤더와 메소드 본문이 포함됩니다. 다음은 메소드의 모든 부분입니다.

  • 수정자: 선택적인 수정자는 메소드 호출 방법을 컴파일러에 알려줍니다. 이 메소드에 대한 액세스 유형을 정의합니다.

  • 반환 값 유형: 메서드는 값을 반환할 수 있습니다. returnValueType은 메소드 반환 값의 데이터 유형입니다. 일부 메서드는 필요한 작업을 수행하지만 값을 반환하지 않습니다. 이 경우 returnValueType은 void 키워드입니다.

  • 메서드 이름: 은 메소드의 실제 이름입니다. 메소드 이름과 매개변수 목록이 함께 메소드 서명을 구성합니다.

  • 매개변수 유형: 매개변수는 자리표시자와 같습니다. 메소드가 호출되면 값이 매개변수로 전달됩니다. 이 값을 실제 매개변수 또는 변수라고 합니다. 매개변수 목록은 메소드의 매개변수 유형, 매개변수 순서 및 개수를 나타냅니다. 매개변수는 선택사항이며 메소드에는 매개변수가 포함될 수 없습니다.

  • 메서드 본문: 메서드 본문에는 메서드의 기능을 정의하는 특정 문이 포함되어 있습니다.

12-130Q1220955916.jpg

예:

public static int age(int birthday){...}

여러 매개변수가 있을 수 있습니다.

static float interest(float principal, int year){...}

참고: 일부 다른 언어에서는 메서드가 프로시저와 함수를 나타냅니다. void가 아닌 반환 값을 반환하는 메서드를 함수라고 하며, void 반환 값을 반환하는 메서드를 프로시저라고 합니다.

Example

다음 메소드에는 2개의 매개변수 num1과 num2가 포함되어 있으며 이 두 매개변수의 최대값을 반환합니다.

/** 返回两个整型变量数据的较大值 */
public static int max(int num1, int num2) {
   int result;
   if (num1 > num2)
      result = num1;
   else
      result = num2;

   return result; 
}

메소드 호출

Java는 두 가지 메소드 호출 방법을 지원하며, 메소드가 값을 반환하는지 여부에 따라 선택합니다.

프로그램이 메서드를 호출하면 호출된 메서드에 프로그램 제어 권한이 부여됩니다. 호출된 메서드의 return 문이 실행되거나 메서드 본문 닫는 대괄호에 도달하면 제어가 프로그램에 반환됩니다.

메서드가 값을 반환할 때 메서드 호출은 일반적으로 값으로 처리됩니다. 예:

int larger = max(30, 40);

메서드 반환 값이 void인 경우 메서드 호출은 문이어야 합니다. 예를 들어, println 메소드는 void를 반환합니다. 다음 호출은 명령문입니다.

System.out.println("Welcome to Java!");

Example

다음 예제에서는 메서드를 정의하고 호출하는 방법을 보여줍니다.

public class TestMax {
   /** 主方法 */
   public static void main(String[] args) {
      int i = 5;
      int j = 2;
      int k = max(i, j);
      System.out.println("The maximum between " + i +
                    " and " + j + " is " + k);
   }

   /** 返回两个整数变量较大的值 */
   public static int max(int num1, int num2) {
      int result;
      if (num1 > num2)
         result = num1;
      else
         result = num2;

      return result; 
   }
}

위 예제의 컴파일 및 실행 결과는 다음과 같습니다.

The maximum between 5 and 2 is 5

이 프로그램에는 main 메소드와 max 메소드가 포함되어 있습니다. Main 메소드는 JVM에 의해 호출됩니다. 그 외에는 다른 메소드와 다르지 않습니다.

메인 메소드의 헤더는 변경되지 않았습니다. 예제에 표시된 대로 수정자는 public 및 static이며 void 유형 값을 반환하고 메소드 이름은 main이며 String[] 유형 매개변수를 사용합니다. String[]은 매개변수가 문자열 배열임을 나타냅니다.


void 키워드

이 섹션에서는 void 메소드를 선언하고 호출하는 방법을 설명합니다.

다음 예제에서는 printGrade라는 메서드를 선언하고 이를 호출하여 주어진 성적을 인쇄합니다.

Example

public class TestVoidMethod {

   public static void main(String[] args) {
      printGrade(78.5);
   }

   public static void printGrade(double score) {
      if (score >= 90.0) {
         System.out.println('A');
      }
      else if (score >= 80.0) {
         System.out.println('B');
      }
      else if (score >= 70.0) {
         System.out.println('C');
      }
      else if (score >= 60.0) {
         System.out.println('D');
      }
      else {
         System.out.println('F');
      }
   }
}

위 예제의 컴파일 및 실행 결과는 다음과 같습니다.

C

여기서 printGrade 메소드는 void 유형 메소드이며 값을 반환하지 않습니다.

void 메서드에 대한 호출은 문이어야 합니다. 따라서 메인 메소드의 세 번째 줄에 있는 문장이라고 부릅니다. 세미콜론으로 끝나는 모든 명령문과 같습니다.


매개변수를 값으로 전달

메서드 호출 시 매개변수를 제공해야 하며, 매개변수 목록에 지정된 순서대로 제공해야 합니다.

예를 들어, 다음 메소드는 메시지를 n번 연속으로 인쇄합니다.

public static void nPrintln(String message, int n) {
  for (int i = 0; i < n; i++)
    System.out.println(message);
}

Example

다음 예는 값 전달의 효과를 보여줍니다.

이 프로그램은 두 변수를 교환하는 데 사용되는 메서드를 만듭니다.

public class TestPassByValue {

   public static void main(String[] args) {
      int num1 = 1;
      int num2 = 2;

      System.out.println("Before swap method, num1 is " +
                          num1 + " and num2 is " + num2);

      // 调用swap方法
      swap(num1, num2);
      System.out.println("After swap method, num1 is " +
                         num1 + " and num2 is " + num2);
   }
   /** 交换两个变量的方法 */
   public static void swap(int n1, int n2) {
      System.out.println("\tInside the swap method");
      System.out.println("\t\tBefore swapping n1 is " + n1
                           + " n2 is " + n2);
      // 交换 n1 与 n2的值
      int temp = n1;
      n1 = n2;
      n2 = temp;

      System.out.println("\t\tAfter swapping n1 is " + n1
                           + " n2 is " + n2);
   }
}

위 예제의 컴파일 및 실행 결과는 다음과 같습니다.

Before swap method, num1 is 1 and num2 is 2
        Inside the swap method
                Before swapping n1 is 1 n2 is 2
                After swapping n1 is 2 n2 is 1
After swap method, num1 is 1 and num2 is 2

두 개의 매개변수를 전달하여 스왑 메서드를 호출합니다. 흥미롭게도 실제 매개변수의 값은 메소드가 호출된 후에도 변경되지 않습니다.


메소드의 오버로딩

위에서 사용된 max 메소드는 int형 데이터에만 적용 가능합니다. 하지만 두 가지 부동 소수점 데이터 유형의 최대값을 얻으려면 어떻게 해야 할까요?

해결 방법은 다음 코드에 표시된 것처럼 이름은 같지만 매개 변수가 다른 다른 메서드를 만드는 것입니다.

public static double max(double num1, double num2) {
  if (num1 > num2)
    return num1;
  else
    return num2;
}

max 메서드를 호출할 때 int 매개 변수를 전달하면 int 매개 변수의 max 메서드가 호출됩니다.

double 매개변수가 전달되면 double 유형의 max 메소드 본문이 호출되는데, 이를 메소드 오버로딩이라고 합니다.

즉, 클래스의 두 메소드는 이름은 같지만 매개변수 목록이 다릅니다.

Java 컴파일러는 메소드 서명을 기반으로 어떤 메소드를 호출해야 하는지 결정합니다.

메서드 오버로딩을 사용하면 프로그램을 더 명확하고 읽기 쉽게 만들 수 있습니다. 밀접하게 관련된 작업을 수행하는 메서드는 동일한 이름을 사용해야 합니다.

오버로드된 메서드에는 다른 매개변수 목록이 있어야 합니다. 수정자 또는 반환 유형만을 기반으로 메서드를 오버로드할 수 없습니다.


변수 범위

변수의 범위는 변수가 참조될 수 있는 프로그램의 일부입니다.

메서드 내에서 정의된 변수를 지역 변수라고 합니다.

지역 변수의 범위는 선언부터 시작하여 이를 포함하는 블록의 끝에서 끝납니다.

로컬 변수를 사용하려면 먼저 선언해야 합니다.

메서드의 매개변수 범위는 전체 메서드를 포괄합니다. 매개변수는 실제로 지역 변수입니다.

for 루프의 초기화 부분에서 선언된 변수는 루프 전체에 걸쳐 범위를 갖습니다.

그러나 루프 본문에 선언된 변수의 적용 범위는 선언부터 루프 본문 끝까지입니다. 여기에는 아래와 같은 변수 선언이 포함되어 있습니다.

12-130Q1221013F0.jpg

한 메서드, 중첩되지 않은 다른 블록에서 동일한 이름을 가진 지역 변수를 여러 번 선언할 수 있지만 중첩된 블록 내에서는 지역 변수를 두 번 선언할 수 없습니다.

명령줄 매개변수 사용

때로는 메시지를 전달하기 전에 프로그램을 실행하고 싶을 때가 있습니다. 이는 main() 함수에 명령줄 인수를 전달하여 수행됩니다.

명령줄 매개변수는 프로그램 실행 시 프로그램 이름 바로 뒤에 오는 정보입니다.

예제

다음 프로그램은 모든 명령줄 매개변수를 인쇄합니다.

public class CommandLine {

   public static void main(String args[]){ 
      for(int i=0; i<args.length; i++){
         System.out.println("args[" + i + "]: " +
                                           args[i]);
      }
   }
}

아래 표시된 대로 이 프로그램을 실행합니다.

java CommandLine this is a command line 200 -100

실행 결과는 다음과 같습니다.

args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

생성자 방법

객체가 생성되면 생성자 메서드 개체를 초기화하는 데 사용됩니다. 생성자는 자신이 속한 클래스와 이름이 동일하지만 생성자에는 반환 값이 없습니다.

생성자는 일반적으로 클래스의 인스턴스 변수에 초기 값을 할당하거나 완전한 객체를 생성하는 데 필요한 기타 단계를 수행하는 데 사용됩니다.

생성자를 사용자 정의하는지 여부에 관계없이 모든 클래스에는 생성자가 있습니다. Java는 모든 멤버를 0으로 초기화하는 기본 생성자를 자동으로 제공하기 때문입니다.

자신만의 생성자를 정의하면 기본 생성자가 무효화됩니다.

Example

다음은 생성자 메서드를 사용하는 예입니다.

// 一个简单的构造函数
class MyClass {
   int x;
   
   // 以下是构造函数
   MyClass() {
      x = 10;
   }
}

다음과 같이 생성자 메서드를 호출하여 객체를 초기화할 수 있습니다.

public class ConsDemo {

   public static void main(String args[]) {
      MyClass t1 = new MyClass();
      MyClass t2 = new MyClass();
      System.out.println(t1.x + " " + t2.x);
   }
}

대부분의 경우 매개변수가 있는 생성자 메서드가 필요합니다.

예제

다음은 생성자 메소드 사용 예입니다.

// 一个简单的构造函数
class MyClass {
   int x;
   
   // 以下是构造函数
   MyClass(int i ) {
      x = i;
   }
}

다음과 같이 생성자 메소드를 호출하여 객체를 초기화할 수 있습니다.

public class ConsDemo {

   public static void main(String args[]) {
      MyClass t1 = new MyClass( 10 );
      MyClass t2 = new MyClass( 20 );
      System.out.println(t1.x + " " + t2.x);
   }
}

실행 결과는 다음과 같습니다.

10 20

변수 매개변수

시작 JDK 1.5에서는 Java가 동일한 유형의 변수 매개변수를 메소드에 전달하는 것을 지원합니다.

메서드의 변수 매개변수 선언은 다음과 같습니다.

typeName... parameterName

메서드 선언에서 매개변수 유형을 지정한 후 줄임표(...)를 추가합니다.

메서드에는 하나의 변수 매개변수만 지정할 수 있으며, 이 매개변수는 메소드의 마지막 매개변수여야 합니다. 모든 일반 매개변수는 그 앞에 선언되어야 합니다.

Instance

public class VarargsDemo {

   public static void main(String args[]) {
      // 调用可变参数的方法
	  printMax(34, 3, 3, 2, 56.5);
      printMax(new double[]{1, 2, 3});
   }

   public static void printMax( double... numbers) {
   if (numbers.length == 0) {
      System.out.println("No argument passed");
      return;
   }

   double result = numbers[0];

   for (int i = 1; i <  numbers.length; i++)
      if (numbers[i] >  result)
      result = numbers[i];
      System.out.println("The max value is " + result);
   }
}

위 예제의 컴파일 및 실행 결과는 다음과 같습니다.

The max value is 56.5
The max value is 3.0

finalize() method

Java를 사용하면 객체가 파괴(재활용)되기 전에 호출되는 이러한 메서드를 정의할 수 있습니다. 가비지 컬렉터입니다. 이 메소드는 finalize()라고 하며 재활용된 객체를 지우는 데 사용됩니다.

예를 들어 finalize()를 사용하여 객체에 의해 열린 파일이 닫혔는지 확인할 수 있습니다.

finalize() 메서드에서는 객체가 소멸될 때 수행할 작업을 지정해야 합니다.

finalize()의 일반적인 형식은 다음과 같습니다.

protected void finalize()
{
   // 在这里终结代码
}

protected 키워드는 finalize() 메서드가 클래스 외부의 코드에 의해 호출되지 않도록 보장하는 한정자입니다.

물론, Java의 메모리 재활용은 JVM에 의해 자동으로 완료될 수 있습니다. 수동으로 사용하실 경우 위의 방법을 사용하시면 됩니다.

Example

public class FinalizationDemo {  
    public static void main(String[] args) {  
        Cake c1 = new Cake(1);  
        Cake c2 = new Cake(2);  
        Cake c3 = new Cake(3);  
          
        c2 = c3 = null;  
        System.gc(); //调用Java垃圾收集器
    }  
}  
  
class Cake extends Object {  
    private int id;  
    public Cake(int id) {  
        this.id = id;  
        System.out.println("Cake Object " + id + "is created");  
    }  
      
    protected void finalize() throws java.lang.Throwable {  
        super.finalize();  
        System.out.println("Cake Object " + id + "is disposed");  
    }  
}

위 코드를 실행하면 출력 결과는 다음과 같습니다.

C:>java FinalizationDemo  
Cake Object 1is created  
Cake Object 2is created  
Cake Object 3is created  
Cake Object 3is disposed  
Cake Object 2is disposed