[2025년] 정보처리기사 실기 - Java 언어
2025년도 1회, 2회, 3회의 정보처리기사 실기 기출문제 속 Java 언어 문제를 정리하였다.
2025년 1회 정보처리기사 실기
문제 1. 예외 처리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Main {
public static void main(String[] args) {
int a = 5, b = 0;
try {
System.out.print(a/b);
} catch (ArithmeticException e) {
System.out.print("출력1");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.print("출력2");
} catch (NumberFormatException e) {
System.out.print("출력3");
} catch (Exception e) {
System.out.print("출력4");
} finally {
System.out.print("출력5");
}
}
}
더보기
[정답]
출력1출력5
[풀이]
a/b ⟹ 5 ÷ 0의 몫 구하기
수학적으로 0으로 나누기가 불가능하다. 따라서 ArithmeticException 예외가 발생한다.
이 예외 발생으로 “출력1”을 출력한 후, finally문으로 이동하여 “출력5”을 출력하고 종료한다.
최종 출력형식은 print()이기에 줄바꿈과 띄어쓰기 없이 출력1출력5가 답이 된다.
[예외처리 규칙]
- 여러 catch문 중 맞는 것 하나만 실행한다.
finally문은 예외 발생 여부와 관계없이 항상 실행된다.
[java의 주요 예외 클래스]
- IOException
- 입/출력 작업 중 발생하는 예외
- (예시) 파일 읽기/쓰기 오류
- NullPointerException
- 객체가
null인데, 메서드 호출이나 필드 접근을 시도할 때 발생
- 객체가
- ArrayIndexOutOfBoundsException
- 배열의 유효 범위를 벗어난 인덱스에 접근할 때 발생
- ArithmeticException
- 잘못된 산술연산 시 발생
- (예시) 0으로 나누기
- NumberFormatException
- 숫자로 변환 실패했을 시 발생
문제 2. 객체 생성 시 초기화 순서
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class parent {
static int total = 0;
int v = 1;
parent() {
total += (++v);
show();
}
public void show() {
total += total;
}
}
class child extends parent {
int v = 10;
child() {
v += 2;
total += (v++);
show();
}
@Override
public void show() {
total += total * 2;
}
}
class Main {
public static void main(String[] args) {
new child();
System.out.println(parent.total);
}
}
더보기
[정답]
54
[풀이]
Java에서 객체 생성 시 초기화 순서는 다음과 같다.
- 부모 필드 초기화
- 부모 생성자 실행
- 자식 필드 초기화
- 자식 생성자 실행
- new child();
- parent 필드 초기화 ➔
parent()생성자 호출 ➔ child 필드 초기화 ➔child()생성자 호출
- parent 필드 초기화 ➔
1
2
3
4
5
6
7
8
9
class child extends parent {
child() {
super(); // 자동 삽입이 된다.
v += 2;
total += (v++);
show();
}
//...
}
1. parent 필드 초기화
1
parent.v = 1
2. parent() 생성자 호출
1
2
3
4
parent() {
total += (++v);
show();
}
++v➔ 전위 증가- parent.v = 1 ➔ 2
- total += 2;
현재 total 값은 2이다.
show()호출- 자식이 메서드를 오버라이딩했기 때문에, 실제로 호출되는 것은 child의 show()이다.
parent()생성자가 실행 중이지만, 객체의 실제 생성 타입은 child이다.
따라서 오버라이딩된child의 메서드가 호출된다. ⟹ 동적 바인딩의 개념
1
2
3
public void show() {
total += total * 2; // total = 2 + (2 * 2) = 2 + 4 = 6
}
3. child 필드 초기화
parent 생성자가 호출이 끝난 뒤에 초기화가 된다.
1
child.v = 10
4. child() 생성자 호출
1
2
3
4
5
child() {
v += 2;
total += (v++);
show();
}
- v += 2;
- child.v = 10 ➔ 12
- total += (v++);
- total += 12;
total = 6 + 12 = 18 - child.v = 13; ← 후위 증가
- total += 12;
- show() 호출
- child의 show()가 호출된다.
1
2
3
public void show() {
total += total * 2; // total = 18 + (18 * 2) = 18 + 36 = 54
}
최종 결과
1
System.out.println(parent.total);
total 값은 static 클래스 변수이기 때문에 모든 객체가 공유한다.
따라서 parent.total 값은 54이며, 출력되는 결과 값은 54이다.
⭐️ 알아두기 ⭐️
객체의 실제 타입이 child 이기에
생성자 안에서 호출해도
오버라이딩 된 자식 메서드가 실행된다.
문제 3. 재귀 호출 트리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Main {
static int func(int[] a, int st, int end) {
if (st >= end) return 0;
int mid = (st + end) / 2;
return a[mid] + Math.max(func(a, st, mid), func(a, mid + 1, end));
}
public static void main(String[] args) {
int[] data = {3, 5, 8, 12, 17};
int result = func(data, 0, data.length - 1);
System.out.println(result);
}
}
더보기
[정답]
20
[풀이]
1
int result = func(data, 0, data.length - 1);
초기 호출 : func(data, 0, 4);가 된다.
1
2
3
a = {3, 5, 8, 12, 17}
st = 0
end = 4
1
2
3
4
5
6
7
static int func(int[] a, int st, int end) {
if (st >= end) return 0; // 해당 x
int mid = (st + end) / 2; // mid = (0 + 4) / 2 = 2
return a[mid] + Math.max(func(a, st, mid), func(a, mid + 1, end));
// 8 + Math.max(func(a, 0, 2), func(a, 3, 4));
// 8 + Math.max(8, 12) = 8 + 12 = 20
}
1
2
3
4
5
6
7
8
9
func(0,4)
= 8 + max(func(0,2), func(3,4))
/ \
func(0,2) = 8 func(3,4) = 12
/ \ / \
func(0,1)=3 func(2,2)=0 func(3,3)=0 func(4,4)=0
/ \
func(0,0) func(1,1)
0 0
따라서 최종 result 값은 20이다.
[참고]
이 함수는 각 구간의 중간값을 선택하고, 왼쪽/오른쪽 중 더 큰 값을 재귀적으로 선택하여 더하는 구조이다
1. func(a, 0, 2) 값 구하기 ⟹ “8”
1
2
3
a = {3, 5, 8, 12, 17}
st = 0
end = 2
1
2
3
4
5
if (st >= end) return 0; // 해당 x
int mid = (st + end) / 2; // mid = 1
return a[mid] + Math.max(func(a, st, mid), func(a, mid + 1, end));
// 5 + Math.max(func(a, 0, 1), func(a, 2, 2));
// 5 + Math.max(3, 0) -> 5 + 3 -> 8
1-1. func(a, 0, 1) 값 구하기 ⟹ “3”
1
2
3
a = {3, 5, 8, 12, 17}
st = 0
end = 1
1
2
3
4
5
if (st >= end) return 0; // 해당 x
int mid = (st + end) / 2; // mid = 0
return a[mid] + Math.max(func(a, st, mid), func(a, mid + 1, end));
// 3 + Math.max(func(a, 0, 0), func(a, 1, 1));
// 3 + Math.max(0, 0) -> 3
1-2. func(a, 2, 2) 값 구하기 ⟹ “0”
1
2
3
a = {3, 5, 8, 12, 17}
st = 2
end = 2
1
if (st >= end) return 0; // 해당 o => 0 반환
2. func(a, 3, 4) 값 구하기 ⟹ “12”
1
2
3
a = {3, 5, 8, 12, 17}
st = 3
end = 4
1
2
3
4
5
if (st >= end) return 0; // 해당 x
int mid = (st + end) / 2; // mid = 3
return a[mid] + Math.max(func(a, st, mid), func(a, mid + 1, end));
// 12 + Math.max(func(a, 3, 3), func(a, 4, 4));
// 12 + Math.max(0,0) -> 12 + 0 -> 12
문제 4. 메서드 오버로딩
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Main {
static int calc(int value) {
if (value <= 1) return value;
return calc(value - 1) + calc(value -2);
}
static int calc(String str) {
int value = Integer.valueOf(str);
if (value <= 1) return value;
return calc(value - 1) + calc(value - 3);
}
public static void main(String[] args) {
System.out.println(calc("5"));
}
}
더보기
[정답]
4
[풀이]
메서드 오버로딩 - 같은 이름의 메소드를 중복하여 정의
1
System.out.println(calc("5"));
“5” ← String 타입이기에
static int calc(String str) 메서드가 실행된다.
1
2
3
4
5
6
7
8
/* calc("5") 실행 */
static int calc(String str) {
int value = Integer.valueOf(str); // 5
if (value <= 1) return value; // 해당 x
return calc(value - 1) + calc(value - 3);
// return calc(4) + calc(2);
}
- calc(4) ⟹ 3
- return calc(3) + calc(2) ⟹ 2 + 1 = 3
- calc(3) = calc(2) + calc(1) = 1 + 1 = 2
- calc(2) = calc(1) + calc(0) = 1 + 0 = 1
- return calc(3) + calc(2) ⟹ 2 + 1 = 3
- calc(2) ⟹ 1
return calc(4) + calc(2); 값은 4이므로,
4가 출력된다.
2025년 2회 정보처리기사 실기
문제 5. Call by Value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Main {
public static void change(String[] data, String s) {
data[0] = s;
s = "Z";
}
public static void main(String[] args) {
String data[] = { "A" };
String s = "B";
change(data, s);
System.out.print(data[0] + s);
}
}
더보기
[정답]
BB
[풀이]
Java는 항상 Call by Value이다.
1
2
3
4
public static void change(String[] data, String s) {
data[0] = s; // 실제 값이 바뀐다.
s = "Z"; // change() 메서드 안의 지역변수이기에 main()의 s에 영향 x
}
- data ➔ 배열의 참조값(주소)이 전달된다.
- s ➔ 문자열 참조값이 복사된다.
1
2
3
4
5
6
7
public static void main(String[] args) {
String data[] = { "A" };
String s = "B";
change(data, s); // data[0] = "B", s = "B"
System.out.print(data[0] + s); // "B" + "B" = "BB"
}
문제 6. 람다식 실행 중 예외 발생 여부에 따라 try-catch 흐름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Main {
static interface F {
int apply(int x) throws Exception;
}
public static int run(F f) {
try {
return f.apply(3);
} catch (Exception e) {
return 7;
}
}
public static void main(String[] args) {
F f = (x) -> {
if (x > 2) {
throw new Exception();
}
return x * 2;
};
System.out.println(run(f) + run((int n) -> n + 9));
}
}
더보기
[정답]
19
[풀이]
1
System.out.println(run(f) + run((int n) -> n + 9));
1. run(f) ⟹ 7
1
2
3
4
5
6
F f = (x) -> {
if (x > 2) {
throw new Exception();
}
return x * 2;
};
run(f)호출 시f.apply(3)이 실행된다.x = 3이므로x > 2조건을 만족 ➔ Exception 발생 🚨- 이 예외는
run()메서드의 try-catch에서 잡힌다.
1
2
3
catch (Exception e) {
return 7;
}
따라서 run(f)의 반환 값은 7이다.
2. run((int n) -> n + 9) ⟹ 12
1
2
3
(int n) -> {
return n + 9;
}
- 이 람다는 단순히 값을 반환하는 함수이며, 예외를 발생시키지 않는다.
run()에서f.apply(3)실행 ➔ 3 + 9 = 12- 예외가 없으므로 catch로 가지 않고 그대로 반환된다.
따라서 run((int n) -> n + 9)의 반환 값은 12이다.
3. 최종 결과
1
2
System.out.println(run(f) + run((int n) -> n + 9));
// 7 + 12 = 19
문제 7. static 메서드 숨김(hiding)과 동적 바인딩
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Main {
public static class Parent {
public int x(int i) { return i + 2; }
public static String id() { return "P"; }
}
public static class Child extends Parent {
public int x(int i) { return i + 3; }
public String x(String s) { return s + "R"; }
public static String id() { return "C"; }
}
public static void main(String[] args) {
Parent ref = new Child();
System.out.println(ref.x(2) + ref.id());
}
}
더보기
[정답]
5P
[풀이]
⭐️ static 메서드는 오버라이딩되지 않으며, hiding이 발생한다 ⭐️
부모 클래스의 static 메서드는 오버라이딩이 되지 않고,
자식 클래스에서 동일한 이름의 메서드를 정의하면
부모의 메서드를 숨기는(hiding) 효과가 발생한다.
static 메서드는 객체가 아닌 클래스에 바인딩되기 때문에,
참조 변수의 실제 객체가 아닌 선언된 타입 기준으로 결정된다.
1
2
3
4
public static void main(String[] args) {
Parent ref = new Child();
System.out.println(ref.x(2) + ref.id());
}
1. ref.x(2)
1
Parent ref = new Child();
- 참조 타입 : Parent
- 실제 객체 : Child
인스턴스 메서드이므로 오버라이딩이 적용되며,
실제 객체 타입인 Child 기준으로 메서드가 호출된다. (동적 바인딩)
1
2
Child.x(int i) -> i + 3
// 2 + 3 = 5
2. ref.id()
id()는static메서드- ⭐️
static은 컴파일 시점에 타입으로 결정된다 ⭐️- ref의 타입은
Parent이기에 Parent.id()➔ “P”
- ref의 타입은
3. 최종 결과
1
System.out.println(ref.x(2) + ref.id()); // 5 + "P" = 5P
알아두기
| 구분 | 인스턴스 메서드 | static 메서드 |
|---|---|---|
| 바인딩 | 런타임 (동적) | 컴파일 시점 (정적) |
| 오버라이딩 | o | x (대신 hiding 발생) |
| 기준 | 실제 객체 (Child) | 참조 타입 (Parent) |
오버로딩 (Overloading)
메서드의 이름은 같고, 매개변수의 유형과 개수가 다르도록 하는 것오버라이딩(Overriding)
상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용하는 것
문제 8. 참조 변수와 객체 상태 변화 (배열과 객체 공유)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Main {
public static class BO {
public int v;
public BO(int v) {
this.v = v;
}
}
public static void main(String[] args) {
BO a = new BO(1);
BO b = new BO(2);
BO c = new BO(3);
BO[] arr = {a, b, c};
BO t = arr[0];
arr[0] = arr[2];
arr[2] = t;
arr[1].v = arr[0].v;
System.out.println(a.v + "a" + b.v + "b" + c.v);
}
}
더보기
[정답]
1a3b3
[풀이]
1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
BO a = new BO(1); // a → (v=1)
BO b = new BO(2); // b → (v=2)
BO c = new BO(3); // c → (v=3)
BO[] arr = {a, b, c}; // arr[0] → a, arr[1] → b, arr[2] → c
BO t = arr[0]; // t → a
arr[0] = arr[2]; // arr[0] → c
arr[2] = t; // arr[2] → a
arr[1].v = arr[0].v; // b.v = c.v -> 3
System.out.println(a.v + "a" + b.v + "b" + c.v);
}
최종 값
1
2
3
a.v = 1
b.v = 3
c.v = 3
1
System.out.println(a.v + "a" + b.v + "b" + c.v); // 1a3b3
👻 Tip
- 배열에는 객체 자체가 아니라 참조값이 저장됨
- 객체의 필드를 변경하면 ➔ 해당 객체를 참조하는 모든 변수에 영향
- 배열 요소를 바꾸는 것은 ➔ 객체를 바꾸는 것이 아니라 참조를 바꾸는 것
2025년 3회 정보처리기사 실기
문제 9. 인터페이스 구현
아래 코드는 Machine 이라는 인터페이스를 정의하고 WashingMachine 클래스에서 해당 인터페이스를 사용하고자 한다. 빈칸에 들어갈 올바른 키워드를 작성해라.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
interface Machine {
void run();
}
class WashingMachine (_____) Machine {
private String name;
public WashingMachine() {
this.name = "LG Washer";
}
public void run() {
System.out.println("Washing machine running");
}
}
public class Main {
public static void main(String[] args) {
WashingMachine wm = new WashingMachine();
wm.run();
}
}
더보기
[정답]
implements
[풀이]
Machine은 인터페이스이므로,
이를 사용하는 클래스는 해당 메서드를 반드시 구현해야 한다.
인터페이스는 메서드의 구현이 아닌 “명세(규약)”만 정의하기 때문에,
클래스에서 이를 구현할 때 implements 키워드를 사용한다.
따라서 빈칸에는 implements가 들어간다.
[참고]
1
2
3
class
↓ implements (구현)
interface
1
2
3
class
↓ extends (상속)
class
1
2
3
interface
↓ extends (확장)
interface
- extends (상속) ⇒ “클래스 확장”
부모 클래스의 필드와 메서드를 물려받아 확장하는 개념이다.
이미 구현된 기능을 그대로 사용할 수 있으며, 필요에 따라 오버라이딩하여 기능을 변경할 수도 있다.
🚨 자바에서는 클래스의 다중 상속은 불가능하다.
1
2
public class Parent {...}
public class Child extends Parent {...}
- implements (구현) ⇒ “인터페이스를 구현”
클래스가 인터페이스를 구현할 때, 사용된다.
인터페이스에 정의된 메서드를 반드시 구현해야 한다.
인터페이스는 다중 구현이 가능하다.
문제 10. 상속과 생성자 호출
밑줄에 알맞은 단어를 작성해라.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Rectangle {
int width, height;
Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
}
class Square extends Rectangle {
Square(int a) {
______(a,a);
}
int getSquareArea() {
return width * height;
}
}
public class Main {
public static void main(String[] args) {
Square sq = new Square(10);
System.out.println(sq.getSquareArea());
}
}
더보기
[정답]
super
[풀이]
부모 클래스 Rectangle에는 기본 생성자(매개변수 없는 생성자)가 없고, 매개변수 2개를 받는 생성자만 존재한다.
자식 클래스의 생성자는 반드시 부모 클래스의 생성자를 호출하며,
이는 컴파일러에 의해 자동으로 super()가 추가된다.
하지만 부모 클래스에 기본 생성자가 없기 때문에, 명시적으로 생성자를 호출해야 한다.
따라서 Square 생성자에서 super(a, a);와 같이 작성해야 한다.
이는 부모 클래스 Rectangle의 생성자를 호출하여 width와 height를 각각 a로 초기화한다.
super()
- 자식 클래스의 생성자에서 부모 클래스의 생성자를 호출하기 위해 사용된다.
- 생성자 내부에서 사용할 경우, 맨 첫줄에 위치해야 한다.
- 자식 클래스의 생성자는 반드시 부모 클래스의 생성자를 호출해야 하며,
기본 생성자가 없을 경우super(...)를 명시적으로 호출해야 한다.
문제 11. enum 메서드 활용 (values, name)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
enum Tri {
A("A"), B("AB"), C("ABC");
private String code;
Tri(String code) {
this.code = code;
}
public String code() {
return code;
}
}
public class Main {
public static void main(String[] args) {
Tri t = Tri.values()[Tri.A.name().length()];
System.out.print(t.code());
}
}
더보기
[정답]
AB
[풀이]
1
Tri t = Tri.values()[Tri.A.name().length()]; // Tri.B
1. Tri.values()
enum에 정의된 상수들을 선언된 순서대로 배열로 반환한다.
1
[Tri.A, Tri.B, Tri.C]
2. Tri.A.name()
enum 상수의 이름을 문자열로 반환한다.
1
"A"
3. 문자열 길이 계산
1
2
Tri.A.name().length()
// "A".length() ➔ 1
4. 배열 인덱스 접근
1
Tri t = Tri.values()[Tri.A.name().length()]; // Tri.B
5. 최종 결과
1
System.out.print(t.code()); // Tri.B.code() ➔ "AB"