
public class StaticOuterClass {
private final String instanceName = "StaticOuterClassInstanceName";
private static final String staticName = "StaticOuterClassStaticName";
public final Integer sharedInstanceValue = 10;
public static final Integer sharedStaticValue = 90;
static class InnerClass {
private String innerName = "StaticInnerClassInstanceName";
private static String innerPrivateStaticName = "StaticInnerClassStaticName";
public final Integer innerValue = 10;
public static final Integer innerPublicStaticValue = 90;
public static int a = 10;
public int b = 20;
public void test() {
// 인스턴스 변수는 직접 참조할 수 없다.
//System.out.println("instanceName = " + instanceName);
//static인 곳에서 non-static을 부를 수 없다
System.out.println("staticName = " + staticName);
// 정적 영역에 있기 때문에 가능하다.
System.out.println("sharedStaticValue = " + sharedStaticValue);
// 인스턴스 변수 사용하는 법
StaticOuterClass outerCls = new StaticOuterClass();
// 인스턴스를 생성하면 접근이 가능하다.
Integer privateValue = outerCls.sharedInstanceValue;
System.out.println("privateValue = " + privateValue);
}
}
static이라고 해서 외부 클래스의 다른 정적변수와 완전히 동일하게 동작하지는 않는다.static 변수만 가능해야 한다.public int a = 10; 처럼 인스턴스 변수도 생성이 가능하다.Outer Class의 static 변수는 가능하다. Outer Class의 instance변수는 직접 참조할 수 없다.static인 곳에서 non-static를 부를 수 없다.instance 를 생성해야 한다.public void accessToInnerClass() {
Integer innerPublicStaticValue = InnerClass.innerPublicStaticValue;
// static 변수이기 때문에 직접 참조가 가능하다.
String innerPrivateStaticName = InnerClass.innerPrivateStaticName;
// 접근 제어자가 private이더라도 가능하다.
// 인스턴스 변수는 new로 인스턴스를 만들어준 후 사용가능함.
String innerName = new InnerClass().innerName;
// private이지만 사용 가능하다.
}
InnerClass의 static 변수들은 정적 변수이기 때문에 직접 참조가 가능하다.private이더라도 가능하다.InnerClass의 instance 변수들은 new 로 인스턴스를 만들어준 후 사용 가능하다.private 이지만 사용 가능하다.static이기 때문에StaticOuterClass.InnerClass innerclass = new StaticOuterClass.InnerClass(); 와 같이 사용할 수 있다.static 내부 클래스의 생성자를 호출하고 new 붙여주기private static void test3() {
StaticOuterClass.InnerClass innerClass1 = new StaticOuterClass.InnerClass();
innerClass1.a = 50;
StaticOuterClass.InnerClass innerClass2 = new StaticOuterClass.InnerClass();
innerClass2.a = 0;
System.out.println("innerClass1 = " + innerClass1.a);
}
정적변수이기 때문에 다른 instance에서a를 값을 바꿔주어도 다른 정적변수처럼 값이 같아진다.동등성 Equality : 객체 안에 있는 내용 즉, 값들이 같은지 비교 (
equals를 사용한다)
equals는 Objects에 있는 함수이기 때문에, 사용할 때 우리가 오버라이딩 할 수 있다.== 비교랑 똑같이 리턴할 것이다. (Object에서 동일성을 비교하고 있기 때문에)동일성 Identity : 객체가 메모리 주소(참조) 값이 같은지를 비교, 두 객체가 물리적으로 같은 객체인지 비교하는 것 (
==를 사용한다)
== 연산자는 int, boolean과 같은 primitive type에 대해서는 값을 비교한다. reference type에 대해서는 주소값을 비교한다.primitive type 역시 Constant Pool에 있는 특정 상수를 참조하는 것이기 때문에 결국 주소값을 비교하는 것으로 볼 수 있다. 같은 상수를 참조하면 주소값이 같으니 결국 같은 값이면 동일하다고 판단할 수 있기 때문이다.MemberV1 member1 = new MemberV1(1, "John", "admin@example.com");
MemberV1 member2 = new MemberV1(1, "John", "admin@example.com");
String name1 = member1.getName();
String name2 = new String("John"); // 이건 객체를 또 만들게 되는 것임. 그럼 다른 곳에
String name3 = "John";
MemberV1 member3 = member1;
boolean result1 = name1 == name3; // true
boolean result2 = name1 == name2; // false
boolean result3 = member3 == member1; // true
result1은 true가 나온다.name2는 new라는 키워드로 새로운 객체를 만들었다. 그렇게 되면 다른 곳에 저장되기 때문에, result2는 false가 나온다.member3는 member1을 참조하고 있다. 포인터로 가리키고 있다는 의미. 그래서 result3의 결과는 true 가 나온다.
equals는non-nullobject reference에 동등성 체크를 하는 것
@Override
public boolean equals(Object o) {
if (this == o) { // reflexive 규칙 : 자기 자신이랑 같으면 true
return true;
}
// null이거나 클래스가 다르다면 false
if (o == null || getClass() != o.getClass()) {
return false;
}
MemberV2 memberV2 = (MemberV2) o;
// 멤버들 하나 하나 동등성 비교까지
return memberId == memberV2.memberId
&& Objects.equals(name, memberV2.name)
&& Objects.equals(email, memberV2.email);
// return Objects.equals(email, memberV2.email);
}
email만 unique해야 한다면 email만 비교하는 것도 가능하다는 이야기
Object에 있는 함수이며, 원하는 방식으로 출력하기 위해 클래스에 오버라이딩 해주는 함수이다.
@Override
public String toString() {
return "Team{" +
"teamName='" + teamName + '\'' +
", rank=" + rank +
'}';
}
Comparable<T>은interface이다.- 사용하기 위해서는
implements사용 ->compareTo를 반드시 구현해야 한다.<T>에는 비교하고 싶은 대상을 넣는다.- 자기 자신과 매개변수 객체를 비교
- lang 패키지에 있기 때문에 import를 해줄 필요가 없다.
@Override
public int compareTo(CharacterCompare o) {
return Integer.compare(this.level, o.level);
}
compare 함수Integer.java에 있는 함수이다. 두 값을 비교해준다.compareTo 함수int를 반환한다.o1.compareTo(o2)int isUser1HigherThanUser2 = user1.compareTo(user2);
// user1이 더 크다면 1,
// user2가 더 크다면 -1,
// 같다면 0
List<CharacterCompare> raidParty = makeParty(PARTY_SIZE);
raidParty.sort(null); // 오름차순으로 정렬
null 자리에 Comparator이 들어가야 한다. sort 즉, 정렬을 하기 위해서는 객체를 비교할 수 있어야 한다.CharacterCompare 클래스에 compareTo라는 함수를 정의해놨기 때문에 이제 객체를 비교할 수 있게 된다.
Comparable<T>은interface이다.- 사용하기 위해서는
implements사용 ->compare를 반드시 구현해야 한다.<T>에는 비교하고 싶은 대상을 넣는다.- 두 매개변수 객체를 비교
- util 패키지에 있다.
@Override
public int compare(Character o1, Character o2) {
return Integer.compare(o1.gold, o2.gold); // 오름차순
// return Integer.compare(o2.gold, o1.gold); // 내림차순
}
마찬가지로, o1이 o2보다 더 크다면 1,
o1이 o2보다 더 작다면 -1,
o1이 o2와 같다면 0
양수면 +니까 쭉쭉 올라간다고 생각하자 -> 오름차순
=> 앞이 더 클 때 양수가 나온다.
음수면 -니까 쭉쭉 내려간다고 생각하자. -> 내림차순
=> 앞이 더 작을 때 음수가 나온다.
List<Character> userGuild = makeGuild(3);
CharacterGoldComparator comparator = new CharacterGoldComparator();
userGuild.sort(comparator);
Comparator를 구현한 CharacterGoldComparator의 인스턴스를 sort의 매개변수에 넣어준 것이다.userGuild를 정렬하기 위해 객체를 비교할 기준이 CharacterGoldComparator에 저장된 compare함수가 된 것이다.compare에서 설정해둔 정렬 방식으로 정렬된다.
List<Character> userGuild = makeGuild(10);
userGuild.sort((o1, o2) -> {
int result = Integer.compare(o1.getGold(), o2.getGold());
if(result == 0){
result = Integer.compare(o1.getLevel(), o2.getLevel());
}
return result;
});
userGuild.sort(
Comparator.comparing(
(Character c) -> c.getGold(), Comparator.reverseOrder()
).thenComparing(
(Character c) -> c.getLevel()
)
);
userGuild.sort(
Comparator.comparing(Character::getGold, Comparator.reverseOrder()).thenComparing(Character::getLevel)
);
어노테이션(Annotation)은 컴퓨터가 이해할 수 있는 (읽을 수 있는) 특별한 주석
@Retention() : 어노테이션 안의 정보를 어느 시점까지 살릴 건지 설정한다. 어노테이션이 유지되는 기간을 정하기 위해 사용한다.@Target() : 이 어노테이션을 어디에 적용시킬 건지 제한을 둘 수 있다.ElementType.TYPE : 클래스, 인터페이스 등ElementType.METHOD : 메소드@Documented : 어노테이션 정보를 javadoc으로 작성된 문서에 포함시킨다.
@Deprecated : 앞으로 사용하지 않을 대상임을 알린다.
@SuppressWarning() : 컴파일러가 경고 메세지를 나타내지 않는다.
"deprecation"을 두면 컴파일러에게 deprecation 관련 경고 메세지는 알려주지 말라고 하는 것이다. "all" : 모든 경고 메세지를 나타내지 않는다.등...이 있다.
public @interface Apple {
String value() default ""; // 꼭 안 받아도 될 때 default로 둔다
int range();
}
@Apple(value = "yummy")와 같이 value값을 주어야 한다.람다... 어렵다 ! 람다 예시들은 이후 강의를 들은 후, 다시 한 번 더 봐야 할 것 같다.
개념이 이제 익숙하지 않은 게 나오니까 어떤 게 뽀인트인지 초점을 못 잡으니까 조금 어려웠던 것 같다. TIL을 적으면서 Comparable, Comparator를 다시 보니까 이제는 이해가 확실히 되는 것 같다.
어노테이션도 Spring 들어가서는 활용만 하고 저런 식으로 작성할 일은 잘 없다고 하니 좀 안심이 되었다.
Request 예시도 다시 한 번 보니 이해가 된다. 하지만, 이 코드를 다시 혼자 짜봐라... 하면 못 짤 것 같긴 하다.
오늘도 복습을 차근차근 잘 해서 오늘 배운 내용을 이해하고 넘어갈 수 있었다. 정말 할 건 많은데 시간은 너무 없다.. ㅎ 시간을 쪼개서 할 건 하고 넘어가야 한다는 걸 더 느낀다. 오늘 배운 내용을 이해 못 하면 점점 쌓이고~ 내 업보가 될 것이야 ~ TIL만큼은 하루하루 잘 써야겠다고 다짐한다. TIL을 쓰는 건 사실 부가적인 것이고, 오늘 배운 내용을 다 이해하고 넘어가자고 다짐한다 ! 오늘도 잘 살아남았다.
아직 팀원들이랑 너무 어색하다. I들에게는 정적이 별로 불편하지 않다고 들었는데,, 난 너무 불편하다 !! 흑 ㅠㅠ 아직 2일차니 어색한 게 당연하긴 해? ㅎ
오늘 스크럼 남길 때 수업 때 들은 거 완전히 이해는 못 하겠다고 얘기했더니 팀원 분들이 다 도와주시고 격려(?)해주셔서 너무 감사했다.. ! 나도 팀원들에게 그럴 수 있는 사람이 되어야겠다.
오늘도 무사히 끝냈다. 오늘은 수업 중에 위기감을 느꼈다. 코드가 이해는 되는데 이걸 왜 하는거지? 뭘 보여주려고 그러는 거지? 하면서 뽀인트를 못 찾았다. 이게 개념이 익숙하지 않아서 그렇겠지.. 후.. 수업 들으면서도 '이따가 복습할 때 완전히 새로 공부해야 하고 너무 어려우면 어떡하지?' 하고 걱정했는데, 다행히 ! 복습하면서 다 이해할 수 있었다. 차근차근 .. 꼭 잘 따라가야지.
어제 오랜만에 러닝도 하고, 상체도 했더니 아침에 피곤했다. 그래도 6시 이후를 의미 없이 보내는 것보다 훨씬 보람되고 개운했다. 지금처럼 스트레스 받지 않고 열심히 노력하자 ! 빠이팅 :)
아 맞다! 오늘 소회의실에서 자율학습하고 있을 때 강사님이 들어오셨다. 블로그 보고 있다고 하셔서 어머 !!! 했다. 세상에... 너무 감사하잖아요.. 누군가 읽는다는 게 뭔가 뿌듯(?), 기분 좋았다! 뭔가 쑥스럽기도 했다 ㅎㅋㅎ 앞으로도 열심히 해야겠다 .. ! !