타입 파라미터에 지정되는 구체적인 타입 제한할 필요
상속 및 구현 관계 이용해 타입 제한
상위 타입은 클래스 뿐만 아니라 인터페이스도 가능
타입 파라미터를 대체할 구체적인 타입
상위타입이거나 하위 또는 구현 클래스만 지정 가능
숫자타입만 제네릭으로 받아야 할때 extends Number할 수 있다.(타입 제한)
와일드 카드 사용 generic 타입 제한
extends : 본인, 하위객체만 가능.
super : 하위제한. 본인,부모,object 가능
package generic05_wild_card;
// 교육 과정 별 학생을 관리하는 class
public class Course<S> {
private String title; // 교육 과정 명
private S[] students; // 학생 목록
// 교육과정명과 등록 가능한 학생 인원수
@SuppressWarnings("unchecked")
public Course(String title, int capacity) {
this.title = title;
this.students = (S[])new Object[capacity];
}
public String getTitle() {
return title;
}
public S[] getStudnets() {
return students;
}
//학생 정보 추가
public void add(S s) {
for(int i = 0; i< students.length;i++) {
if(students[i] == null) {
students[i] = s;
break;
}
}
}
}
package generic05_wild_card;
public class CourseExample {
//<?> : 매개변수가 전달될때 데이터타입 결정된다고 알려주는 것
public static void registerCourse(Course<?> course) {
System.out.println("["+course.getTitle()+"]");
}
// 학생 과정 등록
public static void registerStudent(Course<? extends Student> course) {
System.out.println("["+course.getTitle()+"]");
}
//직장인, 일반인 과정 등록
public static void registerWorker(Course<? super Worker> course) {
System.out.println("["+course.getTitle()+"]");
}
public static void main(String[] args) {
Person person1 = new Person("일반인1");
Person person2 = new Person("일반인2");
Student student = new Student("학생");
HighStudent highStudent = new HighStudent("고등학생");
Worker worker = new Worker("직장인");
Course<Person> normalCourse = new Course<>("일반인과정",5);
normalCourse.add(person1);
normalCourse.add(person2);
normalCourse.add(student);
normalCourse.add(highStudent);
normalCourse.add(worker);
// 학생만 등록 가능
Course<Student> studentCourse = new Course<>("학생 과정",5);
// studentCourse.add(person1);
//studentCourse.add(worker);
studentCourse.add(student);
studentCourse.add(highStudent);
Course<HighStudent> highCourse = new Course<>("입시과정", 5);
highCourse.add(highStudent);
Course<Worker> workerCourse = new Course<>("재직자 과정",5);
workerCourse.add(worker);
System.out.println("============================");
registerCourse(normalCourse);
registerCourse(studentCourse);
registerCourse(highCourse);
registerCourse(workerCourse);
System.out.println("============================");
//registerStudent(normalCourse);
registerStudent(studentCourse);
registerStudent(highCourse);
System.out.println("============================");
registerWorker(normalCourse);
registerWorker(workerCourse);
}
}
package generic05_wild_card;
//고등학생
public class HighStudent extends Student{
public HighStudent(String name) {
super(name);
}
}
package generic05_wild_card;
//강의를 수강하는 학생의 정보를 저장
public class Person {
private String name;
//이름을 전달받는 생성자만 존재
public Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public String toString() {
return "Person [name = "+name+"]";
}
}
package generic05_wild_card;
public class Student extends Person{
public Student(String name) {
super(name);
}
}
package generic05_wild_card;
// 직장인
public class Worker extends Person{
public Worker(String name) {
super(name);
}
}

2. object
객체 문자정보(toString())
객체를 문자열로 표현한 값
Object 클래스의toString() 메소드는 객체의 문자 정보 리턴
일반적으로 의미 있는 문자정보가 나오도록 재정의
Date 클래스- 현재 시스템의 날짜와 시간 정보 리턴
String 클래스 - 저장하고 있는 문자열 리턴
System.out.pritnln(Object) 메소드
Object의 toString()의 리턴값 출력
package a_object.toString;
class Person extends Object
{
String name;
int height;
double weight;
public Person(String name, int height, double weight) {
this.name = name;
this.height = height;
this.weight = weight;
}
@Override
public String toString() {
return "Person [name = "+name+", height = "+height+", weight = "+weight+"]";
}
}
public class ToStringExample {
public static void main(String[] args) {
Person person = new Person("최기근",180,75);
System.out.println(person);
}
}
객체 비교(equals() 메소드)
기본적으로 == 연산자와 동일한 결과 리턴 (번지 비교)
논리적 동등 위해 오버라이딩 필요
논리적 동등이란?
같은 객체이건 다른 객체이건 상관없이 객체 저장 데이터 동일
Object의 equals() 메소드
재정의하여 논리적 동등 비교할 때 이용
package a_object.equals;
public class Member {
String id;
public Member(String id) {
this.id = id;
}
// alt +s +s +s
@Override
public String toString() {
return "Member [id=" + id + "]";
}
@Override
public boolean equals(Object obj) {
if(this == obj) { return true;}
if(obj instanceof Member) {
Member member = (Member)obj;
if(this.id.equals(member.id)) {
return true;
}
}
return false;
}
}
package a_object.equals;
public class EqualsExample {
public static void main(String[] args) {
Member member1 = new Member("id001");
Member member2 = new Member("id001");
System.out.println(member1==member2);
System.out.println(member1.equals(member2));
}
}
객체 복제(clone())
원본 객체의 필드 값과 동일한 값을 가지는 새로운 객체 생성하는 것
복제 종류
얕은 복제(thin clone): 필드 값만 복제 (참조 타입 필드는 번지 공유)
깊은 복제(deep clone): 참조하고 있는 객체도 복제
package a_object.clone;
public class Car {
String model;
//생성자
public Car(String model) {
this.model = model;
}
@Override
public String toString() {
return "Car [model=" + model + "]";
}
}
package a_object.clone;
public class CloneExample {
public static void main(String[] args) throws CloneNotSupportedException {
Member member = new Member(
"최기근",
28,
new int[] {100,95,99},
new Car("캐스터")
);
System.out.println(member);
Member cloned = (Member)member.clone();
System.out.println(cloned);
cloned.scores[0] = 90;
System.out.println(member.scores == cloned.scores);
System.out.println(cloned);
System.out.println(member);
}
}
package a_object.clone;
import java.util.Arrays;
//implements Cloneable : 복제 허용 (마커형 인터페이스)
public class Member implements Cloneable{
public String name;
public int age;
public int[] scores;
public Car car;
//모든 값을 넘겨받는 생성자 추가
public Member(String name, int age, int[] scores, Car car) {
this.name = name;
this.age = age;
this.scores = scores;
this.car = car;
}
@Override
public String toString() {
return "Member [name=" + name + ", age=" + age + ", scores=" + Arrays.toString(scores) + ", car=" + car + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
Member cloned = (Member)super.clone(); // 얕은 복제
//참조타입은 주소값이 들어가있기 때문에 서로 다른 곳을 참조할때는 직접 구현해야함.(깊은 복제)
// scores, Car
int[] score = new int[this.scores.length];
for(int i = 0; i < this.scores.length;i++) {
score[i] = this.scores[i];
}
cloned.scores = score;
Car car = new Car(this.car.model);
cloned.car = car;
// return super.clone();
return cloned;
}
}
객체 소멸자(finalize())
GC는 객체를 소멸하기 직전 객체 소멸자(finalize()) 실행
Object의 finalize() 는 기본적으로 실행 내용이 없음
객체가 소멸되기 전에 실행할 코드가 있다면?
Object의 finalize() 재정의
될 수 있으면 소멸자는 사용하지 말 것
GC는 메모리의 모든 쓰레기 객체를 소멸하지 않음
GC의 구동 시점이 일정하지 않음
package a_object.finalize;
public class FinalizeTest {
public static void main(String[] args) {
for(int i = 0; i< 50; i++) {
Counter counter = new Counter(i);
counter = null;
System.gc();
}
}
}
package a_object.finalize;
public class Counter {
private int no;
public Counter(int no) {
this.no = no;
}
@Override
protected void finalize() throws Throwable {
System.out.println(no+"번째 객체의 finalize() 호출");
}
}

예외처리
예외 처리 코드(try-catch-finally)
예외 처리 코드
예외 발생시 프로그램 종료 막고, 정상 실행 유지할 수 있도록 처리
일반 예외: 반드시 작성해야 컴파일 가능
실행 예외: 컴파일러가 체크해주지 않으며 개발자 경험 의해 작성
try – catch – finally 블록 이용해 예외 처리 코드 작성
catch 순서 – 상위 클래스가 밑에 위치해야함
package test1_try_catch;
import java.util.InputMismatchException;
import java.util.Scanner;
public class TryCatchExample {
public static void main(String[] args) {
System.out.println("MAIN START");
String str = null;
int[] scores = new int[4];
Scanner sc = new Scanner(System.in);
while(true) {
try {
System.out.println("배열에 삽입하려는 인덱스 번호를 입력 > ");
int index = sc.nextInt();
if(index < 0) break;
System.out.println("입력하려는 값을 작성하시오 > ");
scores[index] = sc.nextInt();
// System.out.println(str.equals("null"));
// }catch(Exception e) {
}catch(InputMismatchException e) {
System.out.println("정수가 입력되지 않음 : " + e.getMessage()); // 예외 관련 설명
sc.next();
continue;
}catch(ArrayIndexOutOfBoundsException e) {
e.printStackTrace(); //오류발생지점출력
System.out.println("잘못된 인덱스 번호입니다.");
continue;
}catch(Exception e) { // 예외 부모 클래스
System.out.println("Exception");
e.printStackTrace();
break;
}finally { // finally는 필수아님
// 오류가 발생하든 - try 오류 발생
// 오류가 발생하지 않든 - try 정상 실행
// 항상 마지막에 수행되는 블럭(return,break가 있어도 실행)
for(int i : scores) {
System.out.print(i+ " ");
}
System.out.println();
System.out.println("항상실행");
}
}
System.out.println("MAIN END");
}
}
'Java' 카테고리의 다른 글
05.10 Class복습,String클래스,정규표현식,Math클래스, (0) | 2023.05.10 |
---|---|
05.09 예외처리 (0) | 2023.05.09 |
generic (0) | 2023.05.04 |
05.04 Wrapper class, 제네릭 (0) | 2023.05.04 |
05.03 인터페이스 (0) | 2023.05.03 |