게시글
블로그
전체 42024. 02. 23.
0
5일차 미션(클린코드)
public class Main { private static final int MAX_NUMBER = 6; public static void main(String[] args) { System.out.print("숫자를 입력하세요: "); Scanner scanner = new Scanner(System.in); int totalRolls = scanner.nextInt(); int[] counts = new int[MAX_NUMBER]; for (int i = 0; i 변수명 개선, if문 대신 배열을 사용하여 반복을 줄임, 함수를 추출해서 가독성을 향상시킴, 상수를 사용함
과제
2024. 02. 21.
0
질문
DTO에 어떤 생성자를 추가해야되는지 궁금합니다. 1번RequestDTO에 기본 생성자가 없을 때(매개변수가 있는 생성자만 있었을 때) 오류 안남 3번RequestDTO에 기본 생성자가 없을 때(매개변수가 있는 생성자만 있었을 때) 오류남기본생성자를 추가하니까 API가 잘 작동함 1번은 GET이고 3번은 POST라서 이런 차이가 있는건가 싶은 생각이드는데정확한 이유를 모르겠습니다.원인이 무엇이고 생성자에 어떤식으로 맵핑?이 되는건가요? 1번 코드 @GetMapping("/api/v1/calc") public CalcResponse calc(CalcRequest request){ // @RequestParam // return new CalcResponse(request.getNum1() + request.getNum2(), // request.getNum1() - request.getNum2(), // request.getNum1() * request.getNum2()); return new CalcResponse(request.getNum1(), request.getNum2()); } package com.group.libraryapp.assignment.dto.request; public class CalcRequest { private int num1; private int num2; public CalcRequest(int num1, int num2) { this.num1 = num1; this.num2 = num2; } public int getNum1() { return num1; } public int getNum2() { return num2; } } package com.group.libraryapp.assignment.dto.response; public class CalcResponse { private int add; private int minus; private int multiply; // public CalcResponse(int add, int minus, int multiply) { // this.add = add; // this.minus = minus; // this.multiply = multiply; // } public CalcResponse(int num1, int num2){ this.add = num1 + num2; this.minus = num1 - num2; this.multiply = num1 * num2; } public int getAdd() { return add; } public int getMinus() { return minus; } public int getMultiply() { return multiply; } } ======================3번 @PostMapping("/api/v1/nums-sum") public Integer sum(@RequestBody SumRequest nums){ Integer result = 0; for(Integer num : nums.getNums()){ result += num; } return result; }package com.group.libraryapp.assignment.dto.request; import java.util.List; public class SumRequest { private List nums; public SumRequest(List nums) { this.nums = nums; } public List getNums() { return nums; } } 위의 코드는 기본생성자가 없어서 500에러 뜸 아래 코드와 같이 기본 생성자 추가하니까 성공package com.group.libraryapp.assignment.dto.request; import java.util.List; public class SumRequest { private List nums; // *********** 추가 ***************** public SumRequest() { } public SumRequest(List nums) { this.nums = nums; } public List getNums() { return nums; } }
2024. 02. 20.
0
2일차 미션(API 만들기)
과제문제1 : 생성자 없어서 틀렸었음 AssignmentApplication.java@RestController public class AssignmentApplication { @GetMapping("/api/v1/calc") public CalcResponse calc(CalcRequest request){ // @RequestParam System.out.println(request.getNum1() + " // " + request.getNum2()); // return new CalcResponse(request.getNum1() + request.getNum2(), // request.getNum1() - request.getNum2(), // request.getNum1() * request.getNum2()); return new CalcResponse(request.getNum1(), request.getNum2()); } } CalcRequest.javapackage com.group.libraryapp.assignment.dto.request; public class CalcRequest { private int num1; private int num2; // 생성자가 없으면 객체를 생성할때 값을 주입하지 못한다. public CalcRequest(int num1, int num2) { this.num1 = num1; this.num2 = num2; } public int getNum1() { return num1; } public int getNum2() { return num2; } } CalcResponse.javapackage com.group.libraryapp.assignment.dto.response; public class CalcResponse { private int add; private int minus; private int multiply; // public CalcResponse(int add, int minus, int multiply) { // this.add = add; // this.minus = minus; // this.multiply = multiply; // } public CalcResponse(int num1, int num2){ this.add = num1 + num2; this.minus = num1 - num2; this.multiply = num1 * num2; } public int getAdd() { return add; } public int getMinus() { return minus; } public int getMultiply() { return multiply; } } 쿼리에 2023-01-01 String으로 입력받음 → DayResponse 응답 객체를 생성해서 return함객체를 생성하고 초기화 할 때 입력받은 날짜를 요일로 변경해야함 입력받은 String을 LocalDateTime 으로 변경함. 이 때 변경은 String을 잘라서 년,월,일,시간,분으로 나눔(0시 0분으로 임의설정) 변경된 LocalDateTime에서 getDayOfWeek함수로 요일을 얻고 String으로 변경해서 반환 @GetMapping("/api/v1/day-of-the-week") public DayResponse day(String date){ return new DayResponse(date); } package com.group.libraryapp.assignment.dto.response; import java.time.LocalDateTime; public class DayResponse { String dayOfTheWeek; public DayResponse(String dayOfTheWeek) { LocalDateTime localDateTime = LocalDateTime.of(Integer.parseInt(dayOfTheWeek.substring(0,4)), Integer.parseInt(dayOfTheWeek.substring(5,7)), Integer.parseInt(dayOfTheWeek.substring(8)),0,0); this.dayOfTheWeek = localDateTime.getDayOfWeek().toString(); } public String getDayOfTheWeek() { return dayOfTheWeek; } } API에서 받는 Body라고 해서 POST 설정함, 처음에 @ReqeustBody를 안해서 입력받은 배열이 null로 떴었음. RequestDto에 모든 인자가 있는 생성자 한개만 있는 상태에서는 결과가 안나왔음. 기본 생성자를 만들어주니까 답이 바르게 나옴 언제 기본생성자를 써주고 언제 매개변수가 있는 생성자를 써줘야할까? @PostMapping("/api/v1/nums-sum") public Integer sum(@RequestBody SumRequest nums){ Integer result = 0; for(Integer num : nums.getNums()){ result += num; } return result; } package com.group.libraryapp.assignment.dto.request; import java.util.List; public class SumRequest { private List nums; public SumRequest() { } public SumRequest(List nums) { this.nums = nums; } public List getNums() { return nums; } }
백엔드
・
과제
2024. 02. 19.
0
1일차 미션(어노테이션)
맨 아래에 미션 내용이 있습니다.(미션을 하면서 학습한 내용을 함께 작성하였습니다.) Annotations어노테이션은 메타데이터의 형태로 프로그램에 대한 데이터를 제공한다. 어노테이션은 코드의 작동에 직접적인 영향을 미치지 않는다.어노테이션은 다음과 같은 사용을 한다.컴파일러에게 정보 제공 - 어노테이션은 컴파일러가 에러나 경고를 막기위해 사용된다.컴파일 시 및 배포 시 처리 - 소프트웨어 도구는 어노테이션 정보를 가지고 코드, XML 파일 등을 생성할 수 있다.런타임 처리 - 일부 어노테이션은 런타임 시(실행 시) 확인될 수 있고, 이를 기반으로 추가적인 동작이나 처리를 수행할 수 있다.Annotation 기본사항@Annotation 형태@는 뒤에 오는 내용이 어노테이션임을 컴파일러에게 나타낸다.element가 한개인 경우 name을 생략할 수 있다. element가 없는 경우 @Override처럼 괄호를 생략할 수 있다.@Author( name = "Benjamin Franklin", date = "3/27/2003" ) class MyClass { ... } or @SuppressWarnings(value = "unchecked") void myMethod() { ... } @SuppressWarnings("unchecked") void myMethod() { ... } 여러개의 어노테이션을 사용할 수 있다.@Author(name = "Jane Doe") @EBook class MyClass { ... } 같은 타입을 가지는 어노테이션들을 repeating 어노테이션이라 한다. 자바 8버전부터 지원@Author(name = "Jane Doe") @Author(name = "John Smith") class MyClass { ... } 어디서 어노테이션이 사용되는가?어노테이션은 클래스, 필드, 메소드, 다른 프로그램의 요소 선언에 적용될 수 있다.클래스 객체 생성 표현식 (new @Interned MyObject(); ) , 형변환, implements 절, 발생한 예외 선언 절에서도 사용된다. 이러한 형태의 어노테이션은 “타입 어노테이션”이라 한다. 자바 8에서 생겨남어노테이션 타입 선언어노테이션으로 코드 내의 주석들을 대체할 수 있다.예를들어서 ‘모든 클래스 시작에 아래와 같이 중요한 주석들을 단다’ 라는 규칙이 있다고 생각해보자.public class Generation3List extends Generation2List { // Author: John Doe // Date: 3/17/2002 // Current revision: 6 // Last modified: 4/12/2004 // By: Jane Doe // Reviewers: Alice, Bill, Cindy // class code goes here } To add t 어노테이션으로 동일한 내용의 메타데이터를 추가하기 위해서는, 사전에 아래와 같은 문법을 사용해서 어노테이션 타입을 정의해야한다.@interface ClassPreamble { String author(); String date(); int currentRevision() default 1; String lastModified() default "N/A"; String lastModifiedBy() default "N/A"; // Note use of array String[] reviewers(); } 어노테이션 선언 시 interface 키워드 앞에 @를 붙여야한다.어노테이션 타입은 인터페이스 형태이다.메소드와 비슷하게 어노테이션 타입 요소 선언이 포함되어있다. 이 때 기본값을 정의할 수 있다.어노테이션을 정의하면 아래와 같이 사용가능하다.@Documented : // 만약에 javadoc에 포함시키고싶으면 해당 어노테이션 추가 @ClassPreamble ( author = "John Doe", date = "3/17/2002", currentRevision = 6, lastModified = "4/12/2004", lastModifiedBy = "Jane Doe", // Note array notation reviewers = {"Alice", "Bob", "Cindy"} ) public class Generation3List extends Generation2List { // class code goes here } 미리 선언된 어노테이션 타입들자바 언어에서 사용되는 어노테이션@Deprecated@Override@SuppressWarnings (컴파일러가 생성할 특정 경고 억제)@SafeVarargs@FunctionalInterface다른 어노테이션에 적용되는 어노테이션 : 메타 어노테이션@Retention@Documented@Target@Inherited@RepeatableType Annotations and Pluggable Type Systems자바 8 이전에는 어노테이션을 선언에만 적용 가능이후에는 어떤 타입 사용에도 적용 가능반복 어노테이션동일한 어노테이션을 한 선언 또는 타입에서 여러번 사용ex) 타이머 서비스를 사용하는 코드에서 특정 메소드를 매월 마지막 날, 매주 금요일 오후 11시에 실행하도록 타이머를 설정하기 위해 @Schedule 어노테이션 두번 사용@Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri", hour="23") public void doPeriodicCleanup() { ... } 사용법반복 가능한 어노테이션 타입 선언import java.lang.annotation.Repeatable; @Repeatable(Schedules.class) public @interface Schedule { String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default 12; } 컨테이닝 어노테이션 타입 선언 : @Schedules어노테이션은 Schedule 어노테이션을 array로 저장할 수 있는 value 요소를 가져야함public @interface Schedules { Schedule[] value(); } Lesson: Annotations (The Java™ Tutorials > Learning the Java Language)어노테이션을 직접 만들어 쓸 수 있다.@interface 어노테이션이름{ 타입 요소이름(); // 어노테이션의 요소를 선언한다. ... } @interface DateTime{ String yymmdd(); String hhmmss(); } 어노테이션의 메서드는 추상 메서드이며, 어노테이션을 적용할 때 지정(순서 X) 추상 메서드는 구현할 필요가 없음@interface TestInfo{ int count(); String testedBy(); String[] testTools(); TestType testType(); // enum TestType { FIRST, FINAL } DateTime testDate(); //자신이 아닌 다른 어노테이션 포함 가능 적용시 값을 지정하지 않으면, 사용될 수 있는 기본값 지정 가능(null제외)@interface TestInfo{ int count() default 1; } @TestInfo public class newClass{ ... } 요소가 하나이고 이름이 value일 때는 요소의 이름 생략가능@interface TestInfo{ String value(); } @TestInfo("passed") // @TestInfo(value="passed")와 동일 class newClass{ ... } 요소의 타입이 배열인 경우, 괄호{}를 사용해야 한다@interface TestInfo{ String[] testTools(); } @Test(testTools={"JUnit", "AutoTester"}) @Test(testTools="JUnit") @Test(testTools={}) // 값이 없을 때는 괄호{}가 반드시 필요 모든 어노테이션의 조상Annotation은 모든 어노테이션의 조상이지만 상속은 불가사실 Annotation은 인터페이스다.마커 어노테이션요소가 하나도 정의되지 않은 어노테이션@Test, @Deprecated어노테이션 요소의 규칙요소의 타입은 기본형, String, enum, 어노테이션, Class만 허용추상메서드의 괄호 ()안에 매개변수를 선언할 수 없다예외를 선언할 수 없다요소를 타입 매개변수로 정의할 수 없다. [자바의 정석 - 기초편] ch12-23,24 애너테이션실제로 직접 만들어서 사용할만한 어노테이션에는 뭐가 있을까?프로젝트를 하지 않아서 실제로 어떨 때 필요할 지 와닿지 않음지피티에게 물어본 결과@JsonField:해당 필드가 JSON 직렬화/역직렬화 대상임을 나타내는 어노테이션.javaCopy code public class MyObject { @JsonField private String name; @JsonField private int age; // ... } @NotNull:매개변수나 필드가 null이 아니어야 함을 나타내는 어노테이션.javaCopy code public void someMethod(@NotNull String parameter) { // 메서드 로직 } @RetryOnFailure:메서드나 함수가 실패할 경우 지정된 횟수만큼 자동으로 재시도하도록 하는 어노테이션.javaCopy code @RetryOnFailure(maxAttempts = 3) public void someOperation() { // 작업 로직 } @LogPerformance:메서드의 실행 시간을 로그에 기록하는 어노테이션.javaCopy code @LogPerformance public void performanceCriticalMethod() { // 성능 중요한 작업 로직 } @SecureAccess(role = "ADMIN"):특정 역할이나 권한을 요구하는 보안 접근을 나타내는 어노테이션.javaCopy code @SecureAccess(role = "ADMIN") public void adminOnlyOperation() { // 관리자 권한이 필요한 작업 로직 } 이러한 예시처럼 프로젝트의 특정 요구사항에 맞게 어노테이션을 설계하고 사용할 수 있습니다. 직접 만든 어노테이션을 사용하면 코드의 가독성을 높이고 개발자들 간의 일관성을 유지할 수 있습니다.어노테이션을 사용하는 이유 (효과) 는 무엇일까?개발자 관점에서 @Override와 같은 어노테이션을 사용하면 해당 메서드가 상위 클래스에서 오버라이드 된 것임을 확실하게 알 수 있다. 즉 코드를 읽을때 유용하고 의도를 명확하게 전달할 수 있다.컴파일러 관점에서 컴파일러가 @Override어노테이션 정보를 통해 상위 클래스에 해당 메서드가 존재하는지 확인하고, 아니면 오류를 발생시킬 수 있다. 즉즉 어노테이션은 개발자에게 코드 작성 시 명확한 정보를 제공하고, 컴파일러에게는 코드의 일관성과 정확성을 검증할 수 있는 수단으로 활용된다. 자바에서 어노테이션(Annotation)은 코드에 메타데이터를 추가하는 방법으로 사용됩니다. 어노테이션은 주석과는 다르게 컴파일러나 런타임 시에 코드에 대한 정보를 제공하며, 다양한 목적으로 활용됩니다. 몇 가지 주된 이유는 다음과 같습니다:코드 문서화 및 가독성 향상: 어노테이션을 사용하면 코드에 추가적인 정보를 주석으로 달지 않고도 문서화할 수 있습니다. 예를 들어, @Deprecated 어노테이션은 해당 메서드나 클래스가 더 이상 권장되지 않음을 나타냅니다.컴파일 타임 체크: 일부 어노테이션은 컴파일러에게 특정 경고나 오류를 생성하도록 알려줄 수 있습니다. 예를 들어, 널 포인터 예외를 방지하기 위해 사용되는 @NonNull 어노테이션 등이 있습니다.런타임 처리와 리플렉션: 몇몇 어노테이션은 런타임에 정보를 검색하거나 특정 동작을 수행할 수 있도록 해줍니다. 예를 들어, 스프링 프레임워크에서는 @Autowired 어노테이션을 사용하여 의존성 주입을 수행합니다.프레임워크와 라이브러리 통합: 어노테이션은 프레임워크나 라이브러리에서 특정 기능을 활성화하기 위한 힌트로 사용됩니다. 예를 들어, JUnit에서는 @Test 어노테이션을 사용하여 테스트 메서드를 식별하고 실행합니다.커스텀 마커 어노테이션: 프로그래머가 자신만의 어노테이션을 정의하여 특정 상황에 대한 힌트를 추가하거나, 프레임워크에서 사용할 수 있는 커스텀 마커로 활용할 수 있습니다.이러한 이유로 어노테이션은 자바의 다양한 분야에서 사용되며, 코드의 가독성과 유지보수성을 향상시키고 추가적인 기능을 제공합니다. 나만의 어노테이션은 어떻게 만들 수 있을까?@interface키워드를 사용하여 어노테이션을 정의한다요소를 정의한다 : 필요한 속성이나 요소 정의하고 기본값 설정적용한 어노테이션을 다른 코드에서 적용하여 사용하며, 필요한 경우 리플렉션을 활용하여 어노테이션의 정보를 읽을 수 있다.MyAnnotation.interfacepackage com.group.libraryapp.annotationTest; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation { String name(); String value() default "value의 기본 값"; } Class.javapackage com.group.libraryapp.annotationTest; public class Class { @MyAnnotation(name = "비둘기",value = "pigeon") public void doThis(){ } @MyAnnotation(name = "pigeon") public void doThat(){ } } MethodAnnotationExecutor.javapackage com.group.libraryapp.annotationTest; import java.lang.annotation.Annotation; import java.lang.reflect.Method; public class MethodAnnotationExecutor { public static void main(String[] args) throws NoSuchMethodException { Method method = Class.class.getMethod("doThis"); Annotation[] annotations = method.getDeclaredAnnotations(); for(Annotation annotation : annotations){ System.out.println(annotation); if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name : " + myAnnotation.name()); System.out.println("value : " + myAnnotation.value()); } } } }
백엔드
・
어노테이션