[이것이 자바다] 12장 정리
이 포스트에는 다양한 자바 기능과 클래스에 대한 내용이 포함되어 있습니다. StringBuilder, StringTokenizer, Wrapper 클래스, Math, Random, Date, Calendar, LocalDateTime, DecimalFormat, Pattern, Car, Student 등 다양한 주제를 다룹니다.
Jan 15, 2024
Contents
StudentRecord.javaStudent.javaStudentExam.java핵심 키워드Member.javaMemberExam.java핵심 키워드ErrExam.java핵심 키워드SystemInExam.java핵심 키워드ExitExam.java핵심 키워드MeasureTimeExam.java핵심 키워드PropertyExam.java핵심 키워드BytesToString.java핵심 키워드StringbuilderExam.java핵심 키워드StringTokenaizerExam.java핵심 키워드WrapperExam.java핵심 키워드MathPractice.java핵심 키워드RandomExam.java핵심 키워드DateExam.java핵심 키워드CalanderExam.java핵심 키워드LocalDateTimeExam.java핵심 키워드DecimalFormatExam.java핵심 키워드PatternExam.javaEmailPhoneNumExam.java핵심 키워드Car.javaCarExam.java핵심 키워드Student.javaStudentDriver.java핵심 키워드결론StudentRecord.java
package ch12;
public record StudentRecord (int id, String name){
}
Student.java
package ch12;
public class Student {
int id;
String name;
Student(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Student s) {
if (this.id == s.id) {
return true;
} else {
return false;
}
}
return false;
}
@Override
public String toString() {
return "학번은 " + this.id + ", 이름은 " + this.name + "입니다.";
}
@Override
public int hashCode() {
return this.id + name.hashCode();
}
}
StudentExam.java
package ch12;
public class StudentExam {
public static void main(String[] args) {
// Student s = new Student();
// s.toString(); // object 클래스를 기본으로 상속받기 때문에 컴파일 오류 없음
Student s1 = new Student(1, "홍길동");
Student s2 = new Student(2, "홍길동");
Student s3 = new Student(1, "김자바");
if(s1.equals(s2)) {
System.out.println("두 객체는 동등하게 취급됩니다.");
}else {
System.out.println("두 객체는 다르게 취급됩니다.");
}
if(s1.equals(s3)) {
System.out.println("두 객체는 동등하게 취급됩니다.");
}else {
System.out.println("두 객체는 다르게 취급됩니다.");
}
System.out.println(s1); // toString() 메소드를 거쳐서 출력되는 것이므로 참조 변수를 출력 가능.
System.out.println(s2);
System.out.println(s3);
if(s1.hashCode()==s2.hashCode()) {
System.out.println("두 객체는 동등하게 취급됩니다.");
}else {
System.out.println("두 객체는 다르게 취급됩니다.");
}
if(s1.hashCode()==s3.hashCode()) {
System.out.println("두 객체는 동등하게 취급됩니다.");
}else {
System.out.println("두 객체는 다르게 취급됩니다."); // id는 같아도 리터럴이 다르므로 hashCode 번지값이 달라서 false 출력.
}
StudentRecord sr = new StudentRecord(1,"홍길동");
System.out.println(sr.id());
System.out.println(sr.name());
System.out.println(sr);
StudentRecord sr2 = new StudentRecord(1,"홍길");
System.out.println(sr.equals(sr2));
System.out.println(sr.hashCode()==sr2.hashCode());
}
}
핵심 키워드
- Object의 equals() 메소드를 재정의해서 동등 비교용으로 사용할 수 있다.
- 객체 해쉬코드란 객체를 식별하는 정수다. Object의 hashCode() 메소드는 객체의 메모리 번지를 이용해서 해쉬코드를 생성하기 때문에 객체마다 다른 정수값을 리턴한다.
- 만약 리터럴이 같으면 같은 해쉬코드값을 리턴한다.
- 자바 14부터 record 키워드를 통해 레코드를 선언할 수 있다. 선언된 레코드 소스를 컴파일하면 private final 필드가 자동 생성되고, 생성자 및 getter 메소드가 자동으로 추가된다.
- 하지만 record 보가 롬복을 사용하는 것이 좋다.
Member.java
package ch12;
import lombok.*;
@AllArgsConstructor // 모든 요소를 생성자의 파라미터로 받게 만든다.
@NoArgsConstructor // 기본 생성자를 만든다.
//@Data // 아래 어노테이션을 다 만들어준다. 만약 전부 다 쓸거라면 data를 사용. 아니라면 세부 항목만 사용
//@RequiredArgsConstructor // final을 붙인 필드를 파라미터로 받는 생성자를 만들어준다.
@Getter // getter만 만들어준다.
@Setter // setter만 만들어준다.
@EqualsAndHashCode // equals와 hashcode를 만든다.
@ToString // tostring을 만든다.
public class Member {
private String id; // getter setter를 사용하기 때문에 private로 설정
// @NonNull // final과 같은 점: null상태로 둬서는 안되고 초기값을 설정해야 한다. 따라서 RequiredArgsConstructor에 영향 받음 final과 다른 점:초기화는 강제지만 불변인 값은 아니다.
private String name;
private int age;
}
MemberExam.java
package ch12;
public class MemberExam {
public static void main(String[] args) {
Member m = new Member(); // 롬복은 기본 생성자를 만들어준다.
System.out.println(m); // 롬복을 라이브러리로 추가하면 해쉬 코드 값이 아닌 요소의 리터럴이 출력된다.
m.setId("test"); // getter, setter를 생성해준다.
m.setName("홍길동");
m.setAge(32);
System.out.println(m); // toString()도 만들어준다.
Member m2 = new Member("test", "홍길동", 32);
if(m.equals(m2)) System.out.println("동등합니다."); // equals()와
if(m.hashCode()==m2.hashCode())System.out.println("동등합니다."); // hashcode()도 생성한다.
}
}
핵심 키워드
- 롬복은 자동 코드 생성 라이브러리이다. 레코드와 마찬가지로 DTO 클래스를 작성할 때 getter나 setter와 같은 메소드를 자동으로 생성하기 때문에 작성할 코드의 양을 줄여준다.
- @NoArgsConstructor 어노테이션은 매개변수가 없는 기본 생성자를 생성한다.
- @AllArgsConstructor 어노테이션은 모든 필드를 초기화시키는 생성자를 포함한다.
- @RequiredArgsConstructor 어노테이션은 final을 붙인 필드를 파라미터로 받는 생성자를 포함한다.
- @Getter 어노테이션은 getter 메소드를 포함한다.
- @Setter 어노테이션은 setter 메소드를 포함한다.
- @EqualsAndHashCode 어노테이션은 equals() 와 hashCode() 메소드를 포함한다.
- @ToString 어노테이션은 toString()메소드를 포함한다.
- @Data 어노테이션은 @Getter, @Setter, @EqualsAndHashCode, @ToString, @RequiredArgsConstructor를 포함한다. 만약 이들을 전부 사용하지 않는다면 사용을 지양하는 것이 좋다.
- @NonNull 어노테이션은 null상태로 둬서는 안되고 초기값을 설정하게 한다는 점에서 final과 유사하다. 따라서 @RequiredArgsConstructor에 영향을 받는다. 하지만 초기화는 강제지만 불변인 값은 아니라는 점에서 final과 다르다.
ErrExam.java
package ch12;
public class ErrExam {
public static void main(String[] args) {
try {
int value = Integer.parseInt("1oo");
}catch(NumberFormatException e) {
System.err.println("[에러 내용]");
System.err.println(e.getMessage());
}
}
}
핵심 키워드
- err 필드는 out 필드와 같이 콘솔에 원하는 문자열을 출력할 수 있으나, 콘솔에 에러 내용을 출력하는 데 사용한다.
SystemInExam.java
package ch12;
import java.io.IOException;
public class SystemInExam {
public static void main(String[] args) {
int input = 0;
int speed = 0;
while (true) {
System.out.println("---------------------------");
System.out.println("1. 증속 | 2. 감속 | 3. 중지");
System.out.println("---------------------------");
System.out.println("현재 속도 = " + speed);
System.out.printf("선택: ");
try {
input = System.in.read();
System.in.read();
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
if (input == 49) {
speed++;
} else if (input == 50) {
speed--;
} else if (input == 51) {
System.out.println("프로그램 종료");
break;
}
}
}
}
핵심 키워드
- 자바는 키보드로부터 입력된 키를 읽기 위해 System 클래스에서 in 필드를 제공한다. System.in.read() 메소드를 호출하면 입력된 키의 코드값을 얻을 수 있다.
ExitExam.java
package ch12;
public class ExitExam {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println(i);
if(i==5) {
System.exit(0);
}
}
}
}
핵심 키워드
- 프로세스를 강제로 종료하고 싶다면 System.exit() 메소드를 사용한다.
MeasureTimeExam.java
package ch12;
public class MeasureTimeExam {
public static void main(String[] args) {
long sum = 0;
double nt1 = System.nanoTime();
for (int i = 1; i < 1000000; i++) {
sum += i;
}
double nt2 = System.nanoTime();
System.out.println((nt2 - nt1) / 1000000000);
}
}
핵심 키워드
- 프로그램의 처리 시간을 측정하고 싶다면, System.nanoTime() 메소드를 프로그램의 시작과 끝에 실행시켜서 두 시간의 차를 구하면 된다.
PropertyExam.java
package ch12;
public class PropertyExam {
public static void main(String[] args) {
System.out.println(System.getProperty("java.specification.version"));
System.out.println(System.getProperty("java.home"));
System.out.println(System.getProperty("os.name"));
// if(System.getProperty("os.name").split(" ")[0].equals("Windows")){
// System.out.println("윈도우 운영체제입니다.");
// }
System.out.println(System.getProperty("user.name"));
System.out.println(System.getProperty("user.home"));
System.out.println(System.getProperty("user.dir"));
}
}
핵심 키워드
- 자바에서 시스템 프로퍼티를 읽고싶다면, System.getProperty() 메소드를 사용한다.
BytesToString.java
package ch12;
import java.io.UnsupportedEncodingException;
public class BytesToString {
public static void main(String[] args) throws UnsupportedEncodingException {
String data = "자바";
byte[] bytes = data.getBytes("EUC-KR");
String receive = new String(bytes, "EUC-KR");
System.out.println(receive);
}
}
핵심 키워드
- 문자열을 byte 배열로 변환시키고, 다시 문자열로 복원시키는데 String 클래스를 사용할 수 있다.
StringbuilderExam.java
package ch12;
public class StringbuilderExam {
public static void main(String[] args) {
String name = "홍길동";
String age = "29";
String gender = "남성";
StringBuilder sb = new StringBuilder();
sb.append("이름은 ");
sb.append(name);
sb.append("이고 나이는 ");
sb.append(age);
sb.append("이고 성별은 ");
sb.append(gender);
sb.append("입니다.");
sb.insert(9, ",");
sb.insert(19, ",");
sb.delete(20, sb.length());
sb.delete(sb.length()-3, sb.length());
sb.append("입니다.");
sb.replace(sb.length()-6, sb.length()-4, "35");
String str = sb.toString();
System.out.println(str);
}
}
핵심 키워드
- String은 내부 문자열을 수정할 수 없지만, StringBuilder를 통해 내부 버퍼에 문자열을 저장해두고 그 안에서 추가, 수정, 삭제 작업을 할 수 있다.
StringTokenaizerExam.java
package ch12;
import java.util.StringTokenizer;
public class StringTokenaizerExam {
public static void main(String[] args) {
String str = "홍길동 26 남성";
String[] str_arr = str.split(" ");
String name = str_arr[0];
String age = str_arr[1];
String gender = str_arr[2];
System.out.println(name);
System.out.println(age);
System.out.println(gender);
System.out.println();
StringTokenizer st = new StringTokenizer(str, " ");
while (st.hasMoreTokens()) { // 토큰이 남아있는지 확인
System.out.println("남은 토큰의 수: " + st.countTokens());
System.out.println(st.nextToken());
}
// int count = st.countTokens(); // 꺼낼 때 마다 토큰이 몇개 남아있는지 확인하려면 사용
// for(int i=0; i<count; i++) {
// System.out.println(st.nextToken());
// }
}
}
핵심 키워드
- 문자열이 구분자로 연결되어 있을 경우, 구분자를 기준으로 문자열을 분리할 때 split을 이용하거나 StringTokenizer를 이용한다.
WrapperExam.java
package ch12;
import java.util.ArrayList;
public class WrapperExam {
public static void main(String[] args) {
// Integer i = new Integer(100); // deprecated 되었다. 앞으로 사용 안하기를 권장된다는 것.
// Integer i = 100; // 따라서 래퍼 클래스는 이런 식으로 원시 타입에 값을 넣듯이 초기화한다.
//
// int a = i.intValue(); // 래핑된 값을 언박싱하는 방법
// int b = 10;
// System.out.println(i+b); // 언박싱하지 않더라도 자바에서 자동으로 언박싱 해준다.
Integer a = 300;
Integer b = 300;
System.out.println(a == b); // 래퍼 객체는 내부 값이 아닌 객체 번지를 비교한다.
System.out.println(a.equals(b)); // 따라서 값을 비교하려면 equals()를 사용한다.
Character c = 'A';
Character d = 'A';
System.out.println(c.equals(d)); // 유니코드 값으로 비교하므로 true다.
}
}
핵심 키워드
- 자바는 기본 타입의 값을 가지는 객체를 생성할 수 있는데, 이를 포장 객체라고 부른다.
- 기본 타입의 값을 포장 객체로 만드는 과정을 박싱 이라고 하고, 반대로 포장 객체에서 기본 타입의 값을 얻어내는 과정을 언박싱이라고 한다.
- 포장 클래스는 내부 값을 비교하기 위해 ==와 != 연산자를 사용할 수 없다. 이 연산은 내부의 값을 비교하는 것이 아니라 포장 객체의 번지를 비교한다.
- 예외로 포장 객체의 효율적 사용을 위해 몇몇 범위의 값을 가지는 포장 객체는 ==와 != 연산자로 비교할 수 있지만, 포장 객체에 정확히 어떤 값이 저장될 지 모르는 상황이라면 ==과 !=은 사용하지 않는 것이 좋다.
MathPractice.java
package ch12;
public class MathPractice {
public static void main(String[] args) {
int[] arr = { -123, -56, -32, -256, -4, -96 };
System.out.println("두 점 사이의 거리는 " + distance(3, 6, 1, 2));
System.out.println("최댓값은 " + maxVal1(arr));
System.out.println("최댓값은 " + maxVal2(arr));
}
public static double distance(int x1, int y1, int x2, int y2) {
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}
public static int maxVal1(int[] arr) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, arr[i]);
}
return max;
}
public static int maxVal2(int[] arr) {
int max = Integer.MAX_VALUE;
for (int i = 0; i < arr.length; i++) {
max = Math.min(Math.abs(arr[i]), max);
}
return -max;
}
}
핵심 키워드
- Math 클래스는 수학 계산에 사용할 수 있는 메소드를 제공한다.
RandomExam.java
package ch12;
import java.util.Random;
public class RandomExam {
public static void main(String[] args) {
// Random rand = new Random(System.currentTimeMillis()); // 현재 시간을 이용해서 난수 생성
// System.out.println(rand.nextInt());
Random rand = new Random();
System.out.println(rand.nextInt(6));
}
}
핵심 키워드
- Random() 메소드에 파라미터로 현재 시간을 입력해주면 중복되지 않는 난수를 생성할 수 있다.
DateExam.java
package ch12;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateExam {
public static void main(String[] args) {
Date date = new Date(); // date 클래스가 있지만 LocalDateTime을 더 많이 쓴다.
System.out.println(date);
SimpleDateFormat sm = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String str = sm.format(date);
System.out.println(str);
}
}
핵심 키워드
- date 클래스를 사용하면 날짜 정보를 전달할 수 있다.
CalanderExam.java
package ch12;
import java.util.Calendar;
public class CalanderExam {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance(); // 싱글톤 패턴이라 인스턴스를 새로 못 만들고 이미 만들어진 정적 멤버 인스턴스를 가지고 와서 써야함.
// System.out.println(cal.get(Calendar.YEAR));
// System.out.println(cal.get(Calendar.MONTH) + 1);
// System.out.println(cal.get(Calendar.DATE));
// System.out.println(cal.get(Calendar.DAY_OF_MONTH));
// System.out.println(cal.get(Calendar.DAY_OF_WEEK)); // 일월화수목금토
// System.out.println(Calendar.MONDAY);
// System.out.println(cal.get(Calendar.AM_PM));
// System.out.println(cal.get(Calendar.HOUR));
System.out.println(cal.get(Calendar.YEAR) + "년 " + (cal.get(Calendar.MONTH) + 1) + "월 " + cal.get(Calendar.DATE) + "일");
if(cal.get(Calendar.DAY_OF_WEEK) == 4 && cal.get(Calendar.HOUR_OF_DAY)<13) {
System.out.println("수요일 오전");
}
System.out.println(cal.get(Calendar.HOUR) + "시 " + cal.get(Calendar.MINUTE) + "분 " + cal.get(Calendar.SECOND) + "초");
}
}
핵심 키워드
- Calendar 클래스를 통해 다양한 시간대별로 날짜와 시간을 얻을 수 있다.
LocalDateTimeExam.java
package ch12;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class LocalDateTimeExam {
public static void main(String[] args) {
LocalDateTime ldt = LocalDateTime.now();
LocalDateTime ldt2 = LocalDateTime.now();
// 포맷터 생성
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy.MM.dd a HH:mm:ss");
String date = ldt.format(dtf);
System.out.println(date);
LocalDateTime mY = ldt.minusYears(1);
System.out.println(mY.format(dtf));
LocalDateTime mM = ldt.minusMonths(1);
System.out.println(mM.format(dtf));
if (mY.isAfter(mM)) {
System.out.println("mM의 날짜가 더 이후입니다.");
} else {
System.out.println("mM의 날짜가 같거나 더 이전입니다.");
}
if (ldt.isEqual(ldt2)) {
System.out.println("두 날짜가 서로 같습니다.");
} else {
System.out.println("두 날짜가 다릅니다.");
}
LocalDateTime nextYear = LocalDateTime.of(2025, 1, 1, 0, 0, 0);
long dDay = ldt.until(nextYear, ChronoUnit.DAYS);
System.out.println("올해가 끝나기까지 남은 일 수: " + dDay);
}
}
핵심 키워드
- LocalDateTime 클래스를 사용하면 날짜와 시간을 받아오는 것 뿐만 아니라 조작을 할 수도 있다.
DecimalFormatExam.java
package ch12;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DecimalFormatExam {
public static void main(String[] args) {
double num = 1234567.89;
DecimalFormat df = new DecimalFormat("\u00A4#,###");
System.out.println(df.format(num));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd E a hh:mm:ss");
Date date = new Date();
System.out.println(sdf.format(date));
}
}
핵심 키워드
- DecimalFormat 클래스를 사용하면 숫자를 원하는 형태로 변환할 수 있다.
- 패턴에 유니코드 또한 포함시킬 수 있다.
PatternExam.java
package ch12;
import java.util.regex.Pattern;
public class PatternExam {
public static void main(String[] args) {
// Boolean result = Pattern.matches("\\d{2,3}-\\d{3,4}-\\d{4}", "051-1234-5678");
Boolean result = Pattern.matches("\\w+@\\w+\\.\\w+(\\.\\w+)?", "kim123@goole.com"); // 두번째 .부터는 몇개나 있어도 상관없다.
System.out.println(result);
}
}
EmailPhoneNumExam.java
package ch12;
import java.util.Scanner;
import java.util.regex.Pattern;
public class EmailPhoneNumExam {
private static String phoneNum;
private static String eMail;
private static Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
String eMailVal = "\\w+@\\w+\\.\\w+(\\.\\w+)?";
String phoneNumVal = "\\d{2,3}-\\d{3,4}-\\d{4}";
while(true) {
System.out.printf("이메일을 입력하세요: ");
eMail = scan.nextLine();
if(Pattern.matches(eMailVal, eMail)) {
break;
}else {
System.out.printf("잘못 입력하였습니다.");
}
}
while(true) {
System.out.printf("전화번호를 입력하세요: ");
phoneNum = scan.nextLine();
if(Pattern.matches(phoneNumVal, phoneNum)) {
break;
}else {
System.out.printf("잘못 입력하였습니다.");
}
}
System.out.println("\n이메일: " + eMail + "\n전화번호: " + phoneNum);
}
}
핵심 키워드
- 문자열이 정해져 있는 형식으로 구성되어 있는지 검증해야 하는 경우엔 정규 표현식을 통해 검증할 수 있다.
- []은 한 개의 문자를 나타낸다.
- \d는 한 개의 숫자를 나타낸다.
- \s는 공백을 나타낸다.
- \w는 한 개의 알파벳 또는 숫자를 나타낸다.
- \.은 .을 나타낸다.
- .은 모든 문자 중 한 개의 문자를 나타낸다.
- ?은 없음 또는 한 개를 나타낸다.
- *은 없음 또는 한 개 이상을 나타낸다.
- +은 한 개 이상을 나타낸다.
- {n}은 정확히 n개를 나타낸다.
- {n,}은 최소한 n개를 나타낸다.
- {n, m}은 n개부터 m개까지를 나타낸다.
- a|b는 a또는 b를 나타낸다.
- ()은 그룹핑을 나타낸다.
Car.java
package ch12;
public class Car {
private String model;
private String owner;
public Car() {}
public Car(String model) {
this.model = model;
}
public Car(String model, String owner) {
this.model = model;
this.owner = owner;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
}
CarExam.java
package ch12;
import java.lang.reflect.Field;
public class CarExam {
public static void main(String[] args) {
Class c = Car.class;
Car car = new Car();
Class c1 = car.getClass();
Class c2 = null;
try {
c2 = Class.forName("ch12.Car");
}catch(ClassNotFoundException e) {
System.out.println("해당 클래스가 존재하지 않습니다.");
}
System.out.println(c2.getPackageName()); // 패키지 이름 읽기
System.out.println(c2.getSimpleName()); // 패키지를 제외한 타입 이름 읽기
System.out.println(c2.getName()); // 패키지를 포함한 전체 타입 이름 읽기
Field[] fields = c2.getDeclaredFields();
for(Field f : fields) {
System.out.println(f.getType());
System.out.println(f.getName());
}
}
}
핵심 키워드
- Eclipse에서 자바 파일 우클릭 > Source > Generate Getters And Setters… 를 이용하면 getter와 setter를 자동으로 생성할 수 있다.
- 자바는 클래스와 인터페이스의 메타 정보를 Class 객체로 관리하는데, 이러한 메타 정보를 프로그램에서 읽고 수정하는 행위를 리플렉션이라고 한다.
Student.java
package ch08.example.exam4;
public class Student {
String name;
int quiz;
int midterm;
int finalterm;
double totalScore;
String totalGrade;
public Student(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public int getQuiz() {
return this.quiz;
}
public void setQuiz(int quiz) {
this.quiz = quiz;
}
public int getMidterm() {
return this.midterm;
}
public void setMidterm(int midterm) {
this.midterm = midterm;
}
public int getFinalterm() {
return this.finalterm;
}
public void setFinalterm(int finalterm) {
this.finalterm = finalterm;
}
public double getTotalScore() {
return this.setTotalScore();
}
public String getTotalGrade() {
return this.setTotalGrade();
}
public Double setTotalScore() {
double totalScore = this.getQuiz() * 0.2 + this.getMidterm() * 0.3 + this.getFinalterm() * 0.5;
this.totalScore = totalScore;
return this.totalScore;
}
public String setTotalGrade() {
if (this.getTotalScore() >= 90) {
this.totalGrade = "A";
return this.totalGrade;
} else if (this.getTotalScore() >= 80 && this.getTotalScore() < 90) {
this.totalGrade = "B";
return this.totalGrade;
} else if (this.getTotalScore() >= 70 && this.getTotalScore() < 80) {
this.totalGrade = "C";
return this.totalGrade;
} else if (this.getTotalScore() >= 60 && this.getTotalScore() < 70) {
this.totalGrade = "D";
return this.totalGrade;
} else {
this.totalGrade = "F";
return this.totalGrade;
}
}
public boolean valScore(int quiz) {
if (quiz < 0 || quiz > 100) {
return false;
} else {
return true;
}
}
public String getString() {
return this.getName() + "의 총점은 " + this.getTotalScore() + "이고 학점은 "
+ this.getTotalGrade() + "이다.";
}
}
StudentDriver.java
package ch08.example.exam4;
import java.util.*;
public class StudentDriver {
private static Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
Student[] student = new Student[2];
String[] name = { "선남", "선녀" };
for (int i = 0; i < student.length; i++) {
student[i] = new Student(name[i]);
try {
invokeMethod(student[i], "퀴즈", "setQuiz", "valScore");
invokeMethod(student[i], "중간시험", "setMidterm", "valScore");
invokeMethod(student[i], "기말시험", "setFinalterm", "valScore");
System.out.println(student[i].getString());
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static void invokeMethod(Student s, String keyword, String method1, String method2) throws Exception {
while (true) {
System.out.printf(s.getName() + "의 " + keyword + "점수를 입력하라: ");
int score = Integer.parseInt(scan.nextLine());
s.getClass()
.getDeclaredMethod(method1, int.class)
.invoke(s, score);
//이 함수를 호출하면 Object 타입이 되므로 강제 형변환 한다.
if ((boolean) s.getClass()
.getDeclaredMethod(method2, int.class)
.invoke(s, score)) {
break;
}
}
}
}
핵심 키워드
- 인스턴스.getClass().getDeclaredmethod(사용할 메소드명, 사용할 함수의 파라미터 타입 클래스).invoke(인스턴스, 파라미터) 메소드를 통해 객체의 함수를 호출할 수 있다.
결론
해당 문제를 풀면서 자바에서의 java.base 모듈들과 다양한 클래스의 사용법을 익힐 수 있었다.
Share article