반응형

주방

냄비, 후라이팬

도마

수저

그릇

쟁반

국자, 집게, 뒤집개, 주방가위

반찬통

컵,소주잔, 맥주잔, 커피잔

냄비받침대

햇반

주방세제

수세미

키친타월

물티슈

아이스버킷

비닐장갑

비닐백

호일 

브리타정수기

에어프라이어(오븐)

전기포트

전자레인지

식용유

간장

소금

고춧가루

참기름

설탕

연두

부르스타

커피머신

다용도 슬라이딩 선반

주방수건

주방수건걸이

 

 

욕실

비누

치약

칫솔

샴푸

폼클렌징

샤워타월

화장실 솔

락스

화장실 쓰레기통

슬리퍼

드라이기

수건

세탁세제

섬유유연제

휴지

면도기

빨래건조대

 

 

가구/침구

거울

이불

침대

베개

베개커버

책상

거실 테이블

의자

선반

스탠드조명

선반

 

 

 

일반

쓰레기통

청소기

옷걸이

건전지

손톱깎이 세트

슬리퍼

멀티탭

분리수거함

무선랜카드

인터넷신청

와이파이기기

전동드릴

돌돌이

 

 

식품

만두

스팸

라면

두유

콜라

토닉워터

에이스과자

 

 

 

챙겨야 할 물건

의류

신발

화장품

컴퓨터

노트북

 

반응형
반응형

사경인 회계사님이 쓴 재무제표 모르면 주식투자 절대로 하지마라에 나오는 공식인 S-RIM을 계산하여 해당하는 종목을 매주 제공합니다.

 

재무제표 정보를 제공하는 사이트(http://comp.fnguide.com)를 크롤링하여 필요한 정보를 구했습니다.

 

특히, ROE 같은 경우는  당해에 컨센서스가 추측하는 ROE를 기준으로 하였고, 컨센서스가 존재하지 않을 경우 대상에서 제외합니다.

 

목표 수익률은 9%로 하였습니다.

 

당기순이익이 어떠한 이유로 인해(투자, 매각 등) 너무 높아 ROE가 비정상적으로 다른 해보다 높은 기업이 존재합니다.

따라서 아래 종목 리스트는 투자에 참고만 해주시고, 반드시 해당 기업의 재무제표를 다시 확인해주시기 바랍니다.

 

종목명 시가총액 현재가격 매수가격 중간가격 매도가격 지난주 대비 최초 대비
NAVER 663624 404000 533853 813064 1712745 -1.22 0.00
기아 339694 83800 97037 106863 138523 -3.46 0.00
POSCO 242379 278000 645036 703162 890459 -2.46 0.00
KB금융 235763 56700 110688 112756 119422 0.53 0.00
신한지주 192950 37350 90367 91004 93057 -0.53 0.00
LG 135751 86300 153023 165689 206501 -4.11 0.00
하나금융지주 127603 42500 111576 114243 122837 -2.41 0.00
HMM 125194 25600 48992 72798 149503 -6.23 0.00
우리금융지주 95376 13100 35026 35953 38942 -0.38 0.00
LG디스플레이 80866 22600 37085 39105 45615 12.16 0.00
롯데케미칼 71807 209500 431046 449714 509867 -3.01 0.00
한화솔루션 68095 35600 47703 50934 61342 -3.00 0.00
LG유플러스 60471 13850 17822 18085 18930 -3.15 0.00
현대글로비스 59438 158500 162430 176598 222251 0.96 0.00
미래에셋증권 57496 9050 16791 17492 19750 -1.74 0.00
CJ제일제당 54948 365000 428330 446806 506338 -0.95 0.00
현대제철 53912 40400 130261 132154 138255 -2.88 0.00
금호석유 49510 162500 287986 396962 748107 -3.56 0.00
한국금융지주 47256 84800 163812 201178 321583 -3.20 0.00
이마트 44323 159000 399348 444694 590810 -2.15 0.00
삼성증권 42418 47500 79539 90924 127609 -1.14 0.00
DB손해보험 39931 56400 95016 98714 110628 -1.91 0.00
NH투자증권 38614 13000 23902 26234 33750 -0.38 0.00
GS 37120 39950 112248 123400 159334 -6.11 0.00
메리츠증권 35109 5150 8362 9255 12131 11.35 0.00
GS건설 34318 40100 54443 56281 62200 -2.43 0.00
팬오션 29562 5530 7468 8307 11009 -2.64 0.00
OCI 28262 118500 151819 177358 259652 -1.66 0.00
키움증권 27662 105500 207048 251358 394134 -3.65 0.00
BNK금융지주 27607 8470 27969 28117 28595 -1.17 0.00
SK케미칼 25638 145500 150093 176592 261980 new 0.00
대우건설 25020 6020 9297 10594 14771 -1.15 0.00
포스코인터내셔널 24983 20250 29604 31091 35882 -1.22 0.00
한화 24324 32450 76104 84714 112456 1.56 0.00
효성티앤씨 23413 541000 879830 1302424 2664115 -3.74 0.00
현대해상 22305 24950 51675 51686 51718 -2.16 0.00
한화에어로스페이스 22176 43800 56787 57209 58571 6.70 0.00
두산 21977 133000 157249 183078 266304 -3.97 0.00
코오롱인더 21300 77400 88018 90138 96969 -3.97 0.00
롯데정밀화학 20537 79600 105426 126238 193300 -1.61 0.00
효성 20312 96400 145470 168831 244103 -2.63 0.00
영원무역 19497 44000 53291 56328 66115 -1.12 0.00
JB금융지주 16566 8410 21828 23126 27311 -1.06 0.00
DGB금융지주 16086 9510 31231 31433 32084 -2.96 0.00
현대두산인프라코어 15676 7940 11485 12307 14956 -2.34 0.00
에스엘 15642 32450 32482 33514 36838 2.04 0.00
동국제강 15412 16150 32276 38277 57616 -5.56 0.00
HDC현대산업개발 15258 23150 46027 47850 53727 -2.94 0.00
DL 12867 61400 308900 392940 663734 -4.51 0.00
대한유화 11668 179500 323020 329962 352332 -1.64 0.00
SK가스 11399 123500 236615 248418 286448 -1.98 0.00
GS홈쇼핑 10165 154900 198218 205333 228258 0.00 0.00
LX인터내셔널 9864 25450 60586 73115 113486 -5.39 0.00
유니드 9468 106500 162934 199633 317886 -6.58 0.00
한섬 9433 38300 49156 49815 51936 -4.96 0.00
하림지주 9280 10050 22288 23833 28812 new 0.00
풍산 8786 31350 68105 75218 98139 -3.24 0.00
SBS 8761 48000 55779 70006 115847 new 0.00
대한해운 8299 2600 4093 4635 6380 -4.41 0.00
대상 8177 23600 35347 36387 39736 -1.05 0.00
동원산업 8017 218000 381471 393173 430880 -5.63 0.00
효성화학 7896 247500 267178 339006 570450 0.00 0.00
현대건설기계 7752 39350 71864 74673 83725 -2.84 0.00
동원F&B 7564 196000 216306 226276 258402 -2.97 0.00
세아베스틸 7262 20250 53704 56584 65864 -4.26 0.00
SNT모티브 6771 46300 59077 60214 63879 -7.40 0.00
SK디앤디 6690 30150 33283 38268 54331 0.84 0.00
한국토지신탁 6565 2600 4177 4479 5451 11.35 0.00
코오롱글로벌 6240 24750 33174 41487 68272 -1.59 0.00
매일유업 5483 69900 70422 77787 101521 2.19 0.00
한국자산신탁 5356 4320 7216 7781 9600 -1.59 0.00
국도화학 5163 57300 136537 173558 292848 -2.55 0.00
한라홀딩스 5110 48800 99895 106366 127218 1.24 0.00
한진 4723 31600 104108 117894 162315 -1.71 0.00
이수화학 4236 15150 16173 21128 37095 new 0.00
송원산업 4176 17400 24787 27365 35673 -0.57 0.00
원익머트리얼즈 4142 32850 34529 38200 50030 4.62 0.00
태영건설 4123 10600 21827 24885 34736 -0.93 0.00
금호건설 4085 11150 31054 38999 64602 -1.33 0.00
인탑스 4042 23500 35239 38463 48849 4.68 0.00
대한제강 4005 16250 33577 41438 66766 -1.52 0.00
동부건설 3229 14200 28751 32301 43740 -2.41 0.00
계룡건설 3224 36100 86231 98726 138988 -6.11 0.00
한세예스24홀딩스 3092 7730 12572 13819 17838 -1.78 0.00
풍산홀딩스 2925 28100 107173 126119 187167 -1.23 0.00
KSS해운 2713 11700 15851 18081 25269 2.18 0.00
랩지노믹스 2708 23650 34235 51552 107351 0.21 0.00
KPX케미칼 2662 55000 115141 116308 120071 -3.34 0.00
현대코퍼레이션 2328 17600 26782 28272 33075 -2.22 0.00
도이치모터스 2165 7310 11274 11887 13860 0.97 0.00
금화피에스시 2091 34850 47285 48398 51984 1.60 0.00
한라 2048 5410 13335 15345 21823 -0.18 0.00
와이엔텍 1993 10950 11468 12923 17610 new 0.00
태웅로직스 1455 7450 10343 14853 29386 -7.91 0.00
디와이파워 1413 12800 23285 25727 33596 0.79 0.00
SGC이테크건설 1413 69800 149397 196235 347160 1.31 0.00
한미글로벌 1282 11700 12649 13193 14943 new 0.00
현대코퍼레이션홀딩스 1115 12250 22353 23333 26490 -1.21 0.00
휴비츠 1083 9110 9384 10749 15146 -2.04 0.00
이노인스트루먼트 796 1975 2280 2418 2862 -3.42 0.00
반응형

'주식' 카테고리의 다른 글

[21년 11월 5주차] S-RIM 종목  (0) 2021.11.28
[21년 11월 3주차] S-RIM 종목  (0) 2021.11.14
[21년 11월 2주차] S-RIM 종목  (0) 2021.11.07
[21년 11월 1주차] S-RIM 종목  (0) 2021.11.01
[21년 10월 5주차] S-RIM 종목  (0) 2021.10.24
반응형

이슈

POI는 아파치에서 만든 라이브러리로서 마이크로소프트 오피스 파일 포맷을 순수 자바 언어로서 읽고 쓰는 기능을 제공한다.

 

회사 제품에 데이터를 엑셀로 다운받을 수 있는 기능이 있는데 톰캣이나 Jetty was를 사용하였을 때는 아무런 에러가 발생하지 않았지만, weblogic을 사용하는 사이트에서 아래와 같은 에러가 발생하였다.

 

java.lang.NoClassDefFoundError: Could not initialize class org.apache.poi.POIXMLTypeLoader

 

 

원인

제품에서 사용하는 POI 라이브러리와 Weblogic에서 자체적으로 지원하는 POI 라이브러리와 충돌해서 발생하는 에러이다.

 

 

해결

WEB-INF 아래에 weblogic.xml 파일 생성 후 아래와 같은 옵션 추가하여 어플리케이션 내에 라이브러리를 우선적으로 사용하도록 설정한다.

<container-descriptor>
	<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
반응형
반응형

자바의 최상위 클래스인 Object 클래스에는 finalize 메서드가 존재한다.

   /**
     * Called by the garbage collector on an object when garbage collection
     * determines that there are no more references to the object.
     * A subclass overrides the {@code finalize} method to dispose of
     * system resources or to perform other cleanup.
     * <p>
     * The general contract of {@code finalize} is that it is invoked
     * if and when the Java&trade; virtual
     * machine has determined that there is no longer any
     * means by which this object can be accessed by any thread that has
     * not yet died, except as a result of an action taken by the
     * finalization of some other object or class which is ready to be
     * finalized. The {@code finalize} method may take any action, including
     * making this object available again to other threads; the usual purpose
     * of {@code finalize}, however, is to perform cleanup actions before
     * the object is irrevocably discarded. For example, the finalize method
     * for an object that represents an input/output connection might perform
     * explicit I/O transactions to break the connection before the object is
     * permanently discarded.
     * <p>
     * The {@code finalize} method of class {@code Object} performs no
     * special action; it simply returns normally. Subclasses of
     * {@code Object} may override this definition.
     * <p>
     * The Java programming language does not guarantee which thread will
     * invoke the {@code finalize} method for any given object. It is
     * guaranteed, however, that the thread that invokes finalize will not
     * be holding any user-visible synchronization locks when finalize is
     * invoked. If an uncaught exception is thrown by the finalize method,
     * the exception is ignored and finalization of that object terminates.
     * <p>
     * After the {@code finalize} method has been invoked for an object, no
     * further action is taken until the Java virtual machine has again
     * determined that there is no longer any means by which this object can
     * be accessed by any thread that has not yet died, including possible
     * actions by other objects or classes which are ready to be finalized,
     * at which point the object may be discarded.
     * <p>
     * The {@code finalize} method is never invoked more than once by a Java
     * virtual machine for any given object.
     * <p>
     * Any exception thrown by the {@code finalize} method causes
     * the finalization of this object to be halted, but is otherwise
     * ignored.
     *
     * @throws Throwable the {@code Exception} raised by this method
     * @see java.lang.ref.WeakReference
     * @see java.lang.ref.PhantomReference
     * @jls 12.6 Finalization of Class Instances
     */
    protected void finalize() throws Throwable { }

 

특정 객체에 대한 참조가 더 이상 없다고 판단할 때 가비지 컬렉션이 객체의 finalize를 호출한다. 문서에서도 나와 있듯이 하위 클래스에서 시스템 리소스를 삭제하거나 다른 정리를 수행하기 위해 finalize 메서드를 오버 라이딩하여 작성할 수 있다.

	@Override
	protected void finalize() throws Throwable {
		// do something
		super.finalize();
	}

 

하지만 이펙티브 자바에서는 finalize 사용을 피하라고 권고한다.

finalize는 예측 불가능하며, 대체로 위험하고, 일반적으로 불필요하다.

 

finalize는 언제 수행되는지도 알 수 없으며 수행을 반드시 보장하지 않는다.

1. finalize 메서드는 호출되더라도 즉시 실행된다는 보장이 없으며, 언제 수행되는지도 알 수 없다.

 

finalize는 GC가 호출하게 되는데, GC는 JVM 구현마다 크게 다르기 때문에 finalize가 언제 수행되는지는 알 수 없다. 따라서 중요한 리소스의 해제를 finalize에서 하게 된다면 finalize가 언제 호출될지 모르기 때문에 애플리케이션 실행 중에 리소스 문제가 발생할 수 있으며, 발생하여도 재현하기가 쉽지 않아 디버깅하기 어렵다.

 

2. finalize 수행을 반드시 보장하지 않는다.

 

finalize가 호출되지 않은 상태로 애플리케이션이 종료될 수 있다. 그러므로 지속성이 보장되어야 하는 중요한 상태 정보를 finalize에 작성하면 안 된다. finalize를 반드시 수행하도록 하는 System.runFinalizersOnExit(), Runtime.runFinalizersOnExit() 메서드가 존재하지만, Deprecated 되었다.

     * @deprecated  This method is inherently unsafe.  It may result in
     *      finalizers being called on live objects while other threads are
     *      concurrently manipulating those objects, resulting in erratic
     *      behavior or deadlock.
     * @param value indicating enabling or disabling of finalization
     * @throws  SecurityException
     *        if a security manager exists and its <code>checkExit</code>
     *        method doesn't allow the exit.
     *
     * @see     java.lang.Runtime#exit(int)
     * @see     java.lang.Runtime#gc()
     * @see     java.lang.SecurityManager#checkExit(int)
     * @since   JDK1.1
     */
    @Deprecated
    public static void runFinalizersOnExit(boolean value) {
        Runtime.runFinalizersOnExit(value);
    }

 

 

finalize에서 발생하는 예외는 무시된다.

finalize 메서드 안에서 예외가 발생한다고 하더라도, 해당 예외는 무시되며 스택 트레이스도 표시되지 않는다. 또한 해당 finalize 메서드도 중단된다.

 

아래 예제를 보자.

public class ExceptionInFinalizeTest {

	public static void main(String[] args) throws Throwable {
		ExceptionInFinalizeTest exceptionInFinalizeTest = new ExceptionInFinalizeTest();
		exceptionInFinalizeTest = null;

		// System.gc does not guarantee finalize, but generally works fine.
		System.gc();
	}

	@Override
	protected void finalize() throws Throwable {
		System.out.println("The finalize method start");

		// Exceptions are ignored.
		System.out.println(2 / 0);

		super.finalize();

		System.out.println("The finalize method end"); // not printed
	}
}

 

ExceptionInFinalizeTest 객체를 생성하고, GC를 발생하도록 하기 위해 null로 하여 레퍼런스를 제거하였다. 이후 gc를 발생시켜 finalize()를 호출되게 하였다. finalize의 수행은 항상 보장하지는 않지만 테스트에서는 항상 호출되었다.

 

finalize에 예외를 발생시키도록 divde by zero를 수행하였지만, 어떠한 스택트레이스도 남지 않았으며 이후 코드도 수행되지 않고 종료된다.

 

 

finalize를 재정의할 경우 성능 저하가 발생한다.

finalize를 재정의 하는 것만으로도 성능 저하가 발생한다.

 

아래 에제를 보자.

public class FinalizePerformanceTest {

	/**
	 * TODO Implement performance test case for finalize
	 */
	public static void main(String[] args) {
		long start = System.nanoTime();
		for (int i = 0; i < 1000000; i++) {
			new FinalizePerformanceTest();
		}
		long end = System.nanoTime();
		System.out.println("time: " + (end - start));

	}

	@Override
	protected void finalize() throws Throwable {
		super.finalize();
	}

}

필자의 컴퓨터에서는 finalize를 재정의하여 테스트를 할 경우 위 결과는 152730300ns가 발생하였다. finalize 재정의를 하지 않을 경우 3501900ns 소요되었다. 약 43배 느리다.

 

finalize 사용방법 및 구현 방법

그럼 도대체 이렇게 단점이 많은 finalize는 어디에 사용할까?

 

1. 명시적 종료 메서드 패턴에서 호출되지 않을 것을 대비하기 위한 방어 역할

 

명시적 종료 메서드란 자원을 사용하고 나서 사용을 마쳤으면 메모리 해제를 명시적으로 하도록 만든 메서드를 의미한다. 대표적으로 FileInputStream, FileOutputSteam, Timer, Connection이 있다. 하지만 API 개발자는 항상 클라이언트가 API를 올바르게 사용하지 않을 수도 있다는 것을 고려해야 한다. 따라서 명시적으로 종료 메서드를 호출하지 않았을 경우를 대비하여 finalize 메서드에 메모리 해제를 하도록 작성한다.

 

아래는 java.io.FileInputStream 클래스의 코드이다.

public class FileInputStream extends InputStream
{
    ...

    /**
     * Ensures that the <code>close</code> method of this file input stream is
     * called when there are no more references to it.
     *
     * @exception  IOException  if an I/O error occurs.
     * @see        java.io.FileInputStream#close()
     */
    protected void finalize() throws IOException {
        if ((fd != null) &&  (fd != FileDescriptor.in)) {
            /* if fd is shared, the references in FileDescriptor
             * will ensure that finalizer is only called when
             * safe to do so. All references using the fd have
             * become unreachable. We can call close()
             */
            close();
        }
    }
}

 

2. 네이티브 피어(native peer) 리소스를 해제할 때

먼저 네이티브(native)란 자바 외의 C나 C++ 등 다른 언어로 작성된 프로그램을 나타낸다. 이런 프로그램을 자바에서 다루기 위해 만들어놓은 객체를 네이티브 피어라고 한다. 그리고 일반적인 클래스들이 이러한 네이티브 피어를 이용해 네이티브 프로그램을 사용한다.

 

이 네이티브 피어(객체)는 일반 객체가 아니기 때문에 GC가 관리하지 않는다. 그렇기 때문에 해당 네이티브 피어를 사용하는 일반적인 클래스의 finalize 메서드에서 해당 네이티브 객체의 리소스를 해제하는 코드를 작성할 수 있다.

 

 

finalize를 사용한다면 반드시 부모의 finalize를 호출해야 한다. 그렇지 않으면, 부모 클래스는 절대 종료되지 않는다.

	@Override
	protected void finalize() throws Throwable {
		try {
			// do something
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			super.finalize();
		}
	}

 

하지만 개발자는 항상 실수를 한다. 아래 예를 들어보자.

 

AClass는 finalize를 재정의하여 반드시 유한한 자원의 메모리를 해제해야 하는 클래스를 구현했다고 가정하자. AClass는 부모의 finalize를 반드시 호출해야 한다는 것을 알고 아래와 같이 구현하였다.

public class AClass {

	private void myClose() {
		System.out.println("Do Something");
	}

	@Override
	protected void finalize() throws Throwable {
		try {
			myClose();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			super.finalize();
		}
	}

}

 

BClass는 AClass를 상속받고 마찬가지로 finalize를 재정의했다. 하지만 BClass는 실수로 super.finliaze()를 호출하지 않았다. 그럼 AClass의 finalize는 호출되지 않아 myClose는 호출되지 않는다.

 

이렇게 하위 클래스에서 잘못 코딩하여 발생할 수 있는 finalize 문제를 부모 클래스에서 막을 수 있는데 이를 Finalizer Guardian 패턴이라고 한다.

 

이는 GC의 기본원리를 이용하여 finalize를 호출하는 방식이다. 먼저 코드는 아래와 같다.

public class AClass {

	private final Object guardian = new Object() {
		@Override
		protected void finalize() throws Throwable {
			myClose();
		}
	};

	private void myClose() {
		System.out.println("Do Something");
	}

}

 

기존에 finalize에서 호출되었던 myClose() 메서드가 guardian이라는 변수에 선언된 익명 클래스의 finalize에 선언되어 있다. 즉, AClass의 자원 해제 역할을 익명 클래스가 대신한다.

 

A 클래스를 재정의한 B 클래스의 객체가 더 이상 레퍼런스가 없어 gc가 발생하게 된다면, B 객체에 존재하는 guaridan에 참조되어 있는 익명 클래스의 객체도 누구도 사용할 수 없다. 그러므로 익명 클래스의 객체도 gc 대상이 되므로 해당 finalize가 반드시 호출된다. 따라서 멍청한 하위 클래스가 부모의 finalize를 호출하지 않아도 문제가 발생하지 않는다.

 

 

요약

자원 반환에 대한 최종적 방어 로직 또는 네이티브 자원을 종료시키려는 것이 아니라면 finalize를 사용하지 말자.

 

 

반응형
반응형

자바는 가비지 컬렉션이 알아서 메모리를 관리해주기 때문에 C와 같은 언어보다 메모리에 대해 생각하지 않고 일반적으로 코딩을 한다.

 

하지만 자바 애플리케이션을 만들어 실행하다 보면 OOM이 떨어지는 경우가 있다.

즉 어디선가 가비지 컬렉션이 청소할 수 없는 객체들이 쌓여서 메모리 누수 (leak)가 발생한 것이다.

 

아래 Stack을 구현한 pop 메서드 예제를 보자.

	/**
	 * This method only decreases the size of the stack.
	 * The object at the corresponding array index becomes an obsolete reference.
	 */
	public Object pop() {
		if (size == 0) {
			throw new EmptyStackException();
		}

		return elements[--size];
	}

 

Stack의 데이터를 꺼내오면서 Stack의 허용치를 1 증가시키기 위해 인덱스를 감소시켰다.

 

위 코드의 문제점은 무엇일까?

pop을 통해 꺼내온 객체는 아직까지도 Stack의 array가 참조하고 있다. 결국 해당 array 위치에 새로운 객체가 할당되지 않는다면 프로그램이 종료될 때까지 가비지 컬렉션은 해당 객체가 가비지인지 알 수 없다.

 

따라서 위 코드는 아래와 같이 명시적으로 null로 만들어 참조를 제거해야 한다.

	public Object popDoThis() {
		if (size == 0) {
			throw new EmptyStackException();
		}
		Object result = elements[--size];
		elements[size] = null; /* to let gc do its work */

		return result;
	}

 

Stack 예시처럼 자체적으로 관리하는 메모리가 있는 클래스를 만들 때는 메모리 누수가 발생하지 않도록 주의해야 한다.

 

java.util.WeakHashMap : key에 대한 메모리 참조가 없으면 자동으로 데이터를 삭제하는 Map

자바에서는 메모리 누수가 발생할 수 있는 자료구조에 대한 몇 가지 해결책을 제공한다. 첫 번째로 java.util.WeakHashMap이다.

 

WeakHashMap은 Map이므로 Key와 Value를 한쌍의 데이터로 관리한다. 이때 Key에 대한 참조가 더 이상 존재하지 않게 되면, Value를 가져올 수 있는 방법이 없다고 판단하여, 해당 Key-Value 쌍은 자동으로 삭제되는 Map이다.

 

아래 예제를 보자.

	/**
	 * We put object reference into a cache and forget that we put it there.
	 * To solve this problem we often implement caches using WeakHaspMap.
	 * A WeakHashMap will automatically remove value when its key is no longer referenced.
	 */
	public static void main(String[] args) {
		WeakHashMap<Integer, String> weakHashMap = new WeakHashMap<Integer, String>();

		Integer key = new Integer(1);
		weakHashMap.put(key, "1");
		key = null;

		// If GC is generated, the output changes to {}.
		while (true) {
			System.out.println(weakHashMap);
			System.gc();
			if (weakHashMap.size() == 0) {
				break;
			}
		}

		System.out.println("End");
	}

Key가 1의 값을 가진 Integer 객체이고, Value를 "1" 로하여 WeakHashMap에 put 하였다. 이후, Key값인 Integer의 참조를 null로 만들어 더 이상 참조가 일어나지 않도록 하였다. 이후 GC를 발생시키면 Key의 대한 참조가 없다고 판단하여, 쌍이 사라진 예제이다.

 

참고로, String 클래스를 Key로 하는 WeakHashMap을 사용하면 의미가 없다. 왜냐하면 규칙 5에서 설명했듯이 String은 내부적으로 한 번 생성된 String에 대해 Constant Pool에 항상 참조가 존재하기 때문이다.

 

java.util.LinkedHashMap : 가장 오래된 데이터를 처리할 수 있는 Map

java.util.LinkedHashMap은 HashMap가 다르게 데이터를 넣은 순서를 알 수 있다. 순서를 알 수 있으므로 LinkedHashMap은 아래와 같은 특별한 메서드를 제공한다.

 

    /**
     * Returns <tt>true</tt> if this map should remove its eldest entry.
     * This method is invoked by <tt>put</tt> and <tt>putAll</tt> after
     * inserting a new entry into the map.  It provides the implementor
     * with the opportunity to remove the eldest entry each time a new one
     * is added.  This is useful if the map represents a cache: it allows
     * the map to reduce memory consumption by deleting stale entries.
     *
	 * ....
     *
     * @param    eldest The least recently inserted entry in the map, or if
     *           this is an access-ordered map, the least recently accessed
     *           entry.  This is the entry that will be removed it this
     *           method returns <tt>true</tt>.  If the map was empty prior
     *           to the <tt>put</tt> or <tt>putAll</tt> invocation resulting
     *           in this invocation, this will be the entry that was just
     *           inserted; in other words, if the map contains a single
     *           entry, the eldest entry is also the newest.
     * @return   <tt>true</tt> if the eldest entry should be removed
     *           from the map; <tt>false</tt> if it should be retained.
     */
    protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
        return false;
    }

 

put() 또는 putAll() 메서드를 호출하고 나서 자동으로 호출되는 removeEldestEntry 메서드는 가장 오래된 데이터를 삭제할지를 검사하는 메서드이다.

 

true를 리턴하게 되면 가자 오래된 데이터를 삭제하고, false를 리턴하면 삭제하지 않는다. 디폴트로는 false를 리턴하도록 되어있어 항상 삭제하지 않는다.

 

아래는 Map의 크기가 5인 LinkedHashMap의 예제이다.

	public static void main(String[] args) {
		final int MAX_ENTRIES = 5;
		LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<String, String>() {
			@Override
			public boolean removeEldestEntry(Map.Entry eldest) {
				return size() > MAX_ENTRIES;
			}
		};

		linkedHashMap.put("1", "a");
		linkedHashMap.put("2", "b");
		linkedHashMap.put("3", "c");
		linkedHashMap.put("4", "d");
		linkedHashMap.put("5", "e");
		linkedHashMap.put("6", "f"); /* {1=a} disappear and this item will be added. */

		for (Iterator<String> hashitr = linkedHashMap.values().iterator(); hashitr.hasNext();) {
			System.out.print(hashitr.next() + " ");
		}
	}

 

반응형
반응형

사경인 회계사님이 쓴 재무제표 모르면 주식투자 절대로 하지마라에 나오는 공식인 S-RIM을 계산하여 해당하는 종목을 매주 제공합니다.

 

재무제표 정보를 제공하는 사이트(http://comp.fnguide.com)를 크롤링하여 필요한 정보를 구했습니다.

 

특히, ROE 같은 경우는  당해에 컨센서스가 추측하는 ROE를 기준으로 하였고, 컨센서스가 존재하지 않을 경우 대상에서 제외합니다.

 

목표 수익률은 9%로 하였습니다.

 

당기순이익이 어떠한 이유로 인해(투자, 매각 등) 너무 높아 ROE가 비정상적으로 다른 해보다 높은 기업이 존재합니다.

따라서 아래 종목 리스트는 투자에 참고만 해주시고, 반드시 해당 기업의 재무제표를 다시 확인해주시기 바랍니다.

 

종목명 시가총액 현재가격 매수가격 중간가격 매도가격 지난주 대비 최초 대비
NAVER 671837 409000 513237 781666 1646602 -0.37 0.49
기아 351855 86800 92825 102224 132510 -1.36 2.00
POSCO 248482 285000 613356 668627 846726 0.00 -3.72
KB금융 234516 56400 110688 112756 119422 2.36 -0.35
신한지주 193983 37550 90367 91004 93057 -0.13 -1.83
LG 141571 90000 146856 158920 197793 -3.74 -1.32
하나금융지주 130755 43550 111576 114243 122837 -0.57 -3.22
HMM 110672 27300 33286 49566 102024 2.25 2.44
우리금융지주 95740 13150 35007 35921 38867 -1.13 -0.75
롯데케미칼 74035 216000 431828 451057 513017 -1.60 -3.79
LG디스플레이 72100 20150 37085 39105 45615 -0.98 2.28
한화솔루션 70199 36700 46390 49554 59749 -0.41 -10.16
LG유플러스 62435 14300 17726 18004 18899 1.06 -0.35
현대글로비스 58875 157000 162430 176598 222251 new new
미래에셋증권 58513 9210 16712 17357 19433 4.30 6.11
현대제철 55513 41600 130190 132033 137972 -0.95 -6.41
CJ제일제당 55475 368500 405274 422116 476386 -3.41 -3.03
금호석유 51338 168500 287011 395287 744178 -1.46 -2.03
한국금융지주 48816 87600 163842 201231 321707 0.92 0.69
이마트 45298 162500 396195 439281 578113 new new
삼성증권 42909 48050 79539 90924 127609 2.34 1.48
DB손해보험 40710 57500 95016 98714 110628 -1.03 -2.87
GS 39535 42550 112248 123400 159334 0.95 0.71
NH투자증권 38763 13050 23902 26234 33750 0.77 -0.76
GS건설 35174 41100 54443 56281 62200 -1.44 -0.60
메리츠증권 31530 4625 8362 9255 12131 0.32 -0.75
팬오션 30364 5680 6736 7493 9930 -1.39 -5.65
OCI 28738 120500 139554 163030 238675 0.00 -6.95
키움증권 28710 109500 207048 251358 394134 3.30 4.29
BNK금융지주 27933 8570 27969 28117 28595 1.54 -2.61
대우건설 25311 6090 8936 10182 14197 0.66 -2.56
포스코인터내셔널 25292 20500 28671 30111 34751 -0.48 -5.53
효성티앤씨 24322 562000 684106 1012410 2070278 -0.71 -5.86
한화 23949 31950 71859 78861 101423 -1.54 -4.63
두산 22886 138500 151558 182579 282538 3.75 34.47
현대해상 22797 25500 51675 51686 51718 0.99 -2.86
코오롱인더 22180 80600 88018 90138 96969 -1.59 -1.59
롯데정밀화학 20872 80900 94400 113006 172959 -0.49 -4.94
효성 20860 99000 145470 168831 244103 -0.20 -3.88
한화에어로스페이스 20784 41050 55220 55631 56955 new new
영원무역 19719 44500 46334 47806 52548 2.18 -0.33
JB금융지주 16744 8500 21828 23126 27311 1.19 -4.17
DGB금융지주 16576 9800 31231 31433 32084 0.30 -5.32
동국제강 16319 17100 31768 37405 55570 6.88 0.30
현대두산인프라코어 16051 8130 13525 14493 17613 1.81 92.23
HDC현대산업개발 15719 23850 46027 47850 53727 -3.64 -6.65
에스엘 15329 31800 32893 34220 38494 new -2.90
DL 13475 64300 301465 383482 647758 0.63 0.63
대한유화 11863 182500 317188 323413 343472 0.83 -1.35
SK가스 11630 126000 236615 248418 286448 -2.33 -8.37
LX인터내셔널 10426 26900 54212 65423 101547 1.89 -0.92
GS홈쇼핑 10165 154900 198218 205333 228258 0.00 0.00
유니드 10134 114000 153307 187838 299104 -1.31 -2.15
한섬 9926 40300 48129 48755 50773 -6.28 -4.39
풍산 9080 32400 65135 71938 93860 0.93 -2.11
대한해운 8682 2720 4093 4635 6380 0.18 -3.54
동원산업 8495 231000 381471 393173 430880 -1.70 1.53
대상 8264 23850 34478 35679 39547 0.22 0.00
현대건설기계 7979 40500 71864 74673 83725 -0.49 0.62
효성화학 7896 247500 253212 321656 542196 new new
동원F&B 7795 202000 217479 228290 263124 -0.50 -1.47
세아베스틸 7585 21150 52082 54875 63875 1.44 -2.31
SNT모티브 7312 50000 59378 60732 65093 -0.19 -0.58
SK디앤디 6635 29900 31690 35671 48500 -0.17 -5.23
코오롱글로벌 6340 25150 33174 41487 68272 2.64 -3.28
한국토지신탁 5896 2335 3994 4164 4712 2.86 -0.20
한국자산신탁 5443 4390 7464 8207 10600 0.57 -0.44
매일유업 5365 68400 70571 78044 102122 -1.87 -2.98
국도화학 5298 58800 110750 140779 237540 -3.76 -12.11
한라홀딩스 5048 48200 99092 104989 123987 -3.50 -5.29
SIMPAC 4894 7480 7782 8040 8873 6.69 6.69
한진 4806 32150 104108 117894 162315 -3.16 -7.20
송원산업 4200 17500 23442 25880 33737 0.57 0.57
태영건설 4162 10700 21827 24885 34736 -0.93 -3.61
금호건설 4140 11300 19918 24662 39950 0.00 -6.21
대한제강 4067 16500 33895 41984 68048 0.00 -11.05
원익머트리얼즈 3959 31400 34529 38200 50030 -0.63 -3.53
인탑스 3861 22450 34160 37284 47353 3.21 -3.67
계룡건설 3434 38450 86231 98726 138988 4.47 7.72
동부건설 3309 14550 26456 29723 40249 0.36 -3.27
한세예스24홀딩스 3148 7870 13459 15343 21412 -0.51 -1.25
풍산홀딩스 2962 28450 106661 125239 185104 2.74 -0.17
유니퀘스트 2870 10500 11776 13494 19030 0.46 1.92
KPX케미칼 2754 56900 115141 116308 120071 -2.72 -1.40
랩지노믹스 2702 23600 34235 51552 107351 -11.61 -9.05
KSS해운 2655 11450 15851 18081 25269 -2.96 -3.77
현대코퍼레이션 2381 18000 26782 28272 33075 0.85 -2.18
도이치모터스 2145 7240 11274 11887 13860 -5.96 -4.71
금화피에스시 2058 34300 46145 47469 51733 1.03 4.73
한라 2052 5420 12502 14387 20460 3.06 -3.89
태웅로직스 1581 8090 10343 14853 29386 new new
디와이파워 1402 12700 22156 24406 31656 0.36 0.00
SGC이테크건설 1395 68900 149397 196235 347160 -0.57 -0.57
현대코퍼레이션홀딩스 1129 12400 22817 24129 28356 -1.57 -4.24
휴비츠 1105 9300 9384 10749 15146 new new
코메론 1054 11650 19743 20388 22466 0.00 -4.09
이노인스트루먼트 824 2045 2280 2418 2862 -3.06 -5.07
반응형

'주식' 카테고리의 다른 글

[21년 11월 5주차] S-RIM 종목  (0) 2021.11.28
[21년 11월 4주차] S-RIM 종목  (0) 2021.11.21
[21년 11월 2주차] S-RIM 종목  (0) 2021.11.07
[21년 11월 1주차] S-RIM 종목  (0) 2021.11.01
[21년 10월 5주차] S-RIM 종목  (0) 2021.10.24
반응형

사경인 회계사님이 쓴 재무제표 모르면 주식투자 절대로 하지마라에 나오는 공식인 S-RIM을 계산하여 해당하는 종목을 매주 제공합니다.

 

재무제표 정보를 제공하는 사이트(http://comp.fnguide.com)를 크롤링하여 필요한 정보를 구했습니다.

 

특히, ROE 같은 경우는  당해에 컨센서스가 추측하는 ROE를 기준으로 하였고, 컨센서스가 존재하지 않을 경우 대상에서 제외합니다.

 

목표 수익률은 9%로 하였습니다.

 

당기순이익이 어떠한 이유로 인해(투자, 매각 등) 너무 높아 ROE가 비정상적으로 다른 해보다 높은 기업이 존재합니다.

따라서 아래 종목 리스트는 투자에 참고만 해주시고, 반드시 해당 기업의 재무제표를 다시 확인해주시기 바랍니다.

 

종목명 시가총액 현재가격 매수가격 중간가격 매도가격 지난주 대비
NAVER 674301 410500 513160 781534 1646294 0.86
기아 356720 88000 92825 102224 132510 3.41
POSCO 248482 285000 614835 671168 852684 -3.72
KB금융 229110 55100 110688 112756 119422 -2.65
신한지주 194241 37600 90391 91046 93157 -1.70
LG 147076 93500 148111 161076 202850 2.52
하나금융지주 131506 43800 111576 114243 122837 -2.67
HMM 108240 26700 32903 48909 100483 0.19
우리금융지주 96832 13300 35007 35921 38867 0.38
롯데케미칼 75235 219500 438643 462760 540468 -2.23
LG디스플레이 72815 20350 36972 38911 45158 3.30
한화솔루션 70486 36850 46263 49335 59236 -9.79
LG유플러스 61781 14150 17631 17840 18514 -1.39
CJ제일제당 57432 381500 410540 431159 497596 0.40
미래에셋증권 56098 8830 16682 17304 19310 1.73
현대제철 56047 42000 130331 132275 138539 -5.51
금호석유 52100 171000 280444 384012 717730 -0.58
한국금융지주 48370 86800 163842 201231 321707 -0.23
삼성증권 41926 46950 75658 84260 111976 -0.85
DB손해보험 41135 58100 95016 98714 110628 -1.86
GS 39164 42150 105366 111583 131615 -0.24
NH투자증권 38466 12950 23885 26205 33681 -1.52
GS건설 35687 41700 54443 56281 62200 0.84
메리츠증권 31428 4610 8329 9197 11996 -1.07
팬오션 30791 5760 6711 7450 9829 -4.32
OCI 28738 120500 139554 163030 238675 -6.95
KCC 28037 315500 609006 614478 632112 -5.25
키움증권 27793 106000 206447 250326 391713 0.96
BNK금융지주 27509 8440 27969 28117 28595 -4.09
포스코인터내셔널 25415 20600 28671 30111 34751 -5.07
대우건설 25145 6050 8928 10169 14165 -3.20
효성티앤씨 24495 566000 692221 1026344 2102964 -5.19
한화 24324 32450 71859 78861 101423 -3.13
현대해상 22574 25250 51675 51686 51718 -3.81
코오롱인더 22538 81900 88018 90138 96969 new
두산 22059 133500 151558 182579 282538 29.61
롯데정밀화학 20975 81300 94400 113006 172959 -4.47
효성 20902 99200 145470 168831 244103 -3.69
영원무역 19298 43550 46334 47806 52548 -2.46
JB금융지주 16547 8400 21828 23126 27311 -5.29
DGB금융지주 16526 9770 31257 31477 32188 -5.60
HDC현대산업개발 16312 24750 46027 47850 53727 -3.13
현대두산인프라코어 15765 8100 14001 15004 18233 88.80
동국제강 15269 16000 31768 37405 55570 -6.16
DL 13391 63900 301465 383482 647758 new
SK가스 11907 129000 229510 236217 257828 -6.18
대한유화 11765 181000 317188 323413 343472 -2.16
한섬 10591 43000 48090 48688 50616 2.01
유니드 10268 115500 153307 187838 299104 -0.86
LX인터내셔널 10233 26400 50838 59630 87959 -2.76
GS홈쇼핑 10165 154900 198218 205333 228258 0.00
풍산 8996 32100 65135 71938 93860 -3.02
대한해운 8666 2715 4093 4635 6380 -3.72
동원산업 8642 235000 381471 393173 430880 3.29
대상 8246 23800 34478 35679 39547 -0.22
현대건설기계 8018 40700 71864 74673 83725 1.11
동원F&B 7834 203000 217479 228290 263124 -0.97
세아베스틸 7477 20850 52082 54875 63875 -3.70
SNT모티브 7326 50100 57690 59005 63242 -0.39
SK디앤디 6646 29950 31661 35622 48384 -5.07
코오롱글로벌 6177 24500 32615 40526 66018 -5.77
한국토지신탁 5732 2270 3994 4164 4712 -2.98
국도화학 5505 61100 110750 140779 237540 -8.68
매일유업 5467 69700 70571 78044 102122 -1.14
한국자산신탁 5412 4365 7464 8207 10600 -1.01
한라홀딩스 5231 49950 99092 104989 123987 -1.86
한진 4963 33200 104108 117894 162315 -4.17
SIMPAC 4587 7010 7782 8040 8873 new
태영건설 4201 10800 21827 24885 34736 -2.71
송원산업 4176 17400 23442 25880 33737 new
금호건설 4140 11300 19918 24662 39950 -6.21
대한제강 4067 16500 33895 41984 68048 -11.05
원익머트리얼즈 3984 31600 34042 37365 48069 -2.92
이수화학 3844 13750 18366 24893 45926 -9.55
인탑스 3741 21750 33691 36480 45465 -6.66
동부건설 3297 14500 26456 29723 40249 -3.62
계룡건설 3287 36800 86231 98726 138988 3.11
한세예스24홀딩스 3164 7910 13459 15343 21412 -0.75
랩지노믹스 3057 26700 34235 51552 107351 2.89
풍산홀딩스 2883 27700 106661 125239 185104 -2.83
유니퀘스트 2857 10450 11776 13494 19030 1.46
KPX케미칼 2831 58500 115141 116308 120071 1.36
KSS해운 2736 11800 15851 18081 25269 -0.83
현대코퍼레이션 2361 17850 26782 28272 33075 -3.00
도이치모터스 2281 7700 11274 11887 13860 1.33
금화피에스시 2037 33950 46145 47469 51733 3.66
한라 1991 5260 12502 14387 20460 -6.74
엑시콘 1409 13450 18816 23711 39484 -3.23
SGC이테크건설 1403 69300 149397 196235 347160 0.00
디와이파워 1397 12650 22156 24406 31656 -0.36
현대코퍼레이션홀딩스 1147 12600 22817 24129 28356 -2.71
코메론 1054 11650 19743 20388 22466 -4.09
이노인스트루먼트 850 2110 2280 2418 2862 -2.07
반응형

'주식' 카테고리의 다른 글

[21년 11월 4주차] S-RIM 종목  (0) 2021.11.21
[21년 11월 3주차] S-RIM 종목  (0) 2021.11.14
[21년 11월 1주차] S-RIM 종목  (0) 2021.11.01
[21년 10월 5주차] S-RIM 종목  (0) 2021.10.24
[21년 10월 4주차] S-RIM 종목  (0) 2021.10.19
반응형

자바에서는 new를 사용하여 새로운 객체를 생성한다.

동일한 클래스를 여러 개의 객체를 만들어 사용하는 경우가 많겠지만, 클래스의 용도, 특징에 따라 굳이 객체를 여러 개 만들 필요가 없는 클래스들이 있다.

 

가장 먼저 우리가 자주 사용하는 String이다.

 

String : new vs literal

String 클래스는 두 가지 생성 방식이 있다.

 

1. new

String str = new String("camel");

2. literal

String str = "camel";

 

이 두 가지 방식으로 생성된 String 객체는 기능상으로 다른 점이 있을까? 당연하게도 없다.

하지만 생성된 String 객체가 존재하는 JVM의 위치는 차이가 있다.

 

new를 사용하여 객체를 만들게 되면 어떤 클래스라도 Heap 영역에 객체가 할당된다. 하지만 literal를 사용할 경우 Heap 영역 안에 다른 영역인 String Constant Pool 영역에 String 객체가 할당된다.

 

따라서 아래와 같은 결과가 나타난다.

		String newStr1 = new String("camel");
		String literalStr1 = "camel";

		System.out.println(newStr1 == literalStr1); // false
		System.out.println(newStr1.equals(literalStr1)); // true

기능상으로는 동일하기 때문에 equals는 true를 반환하지만, 객체의 주소 값을 비교하는 ==은 false를 반환한다.

 

그럼 아래의 결과는 어떻게 나올까?

		String newStr1 = new String("camel");
		String newStr2 = new String("camel");

		String literalStr1 = "camel";
		String literalStr2 = "camel";

		System.out.println(newStr1 == newStr2); // false
		System.out.println(literalStr1 == literalStr2); // true

new를 사용하면 항상 객체를 생성하므로 newStr1과 newStr2는 서로 다른 객체이다. 따라서 false가 반환된다.

 

하지만 literal로 선언한 두 값의 비교는 true를 반환하였다. 이유는 무엇일까?

String을 literal로 선언하면 내부적으로 intern() 메서드를 호출하게 된다. intern() 메서드는 주어진 문자열이 String Constant Pool 영역에 존재하는지 먼저 확인하고, 존재한다면 해당 값을 반환하고 없다면 새롭게 생성하기 때문이다.

 

이처럼 String은 특별한 경우가 아니라면 new를 사용하여 객체를 생성하지 말자.

 

정적 팩토리 메서드를 제공하는 변경 불가능 클래스(Immutable Class)

잘 짜인 정적 팩토리 메서드(규칙 1)를 제공하는 변경 불가능 클래스는 정적 팩토리 메서드를 호출하면 이미 만들어진 객체를 반환한다.

// Boolean.java

    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);

    public static Boolean valueOf(boolean b){
        return b ? TRUE : FALSE;
    }

 

따라서 이런 클래스들은 문서를 잘 읽어보고, new를 사용하여 객체를 생성하지 않아도 되는지 확인하는 것이 좋다.

		Boolean newBool = new Boolean(true); // do not
		Boolean bool = Boolean.valueOf(true); // do it

 

변경 가능한 클래스라도 동일한 값을 가진 객체를 계속 사용할 경우

변경 불가능 클래스라면 동일한 값을 가진 객체를 생성할 필요 없이 재사용하면 된다. 하지만 변경 가능한 클래스라면 해당 객체를 다른 영역에서 변경할 수 있으므로, 필요할 때 객체를 자주 생성해서 사용한다.

 

하지만, 변경되지 않고 해당 영역에서만 사용하고 사라지는 변경 가능한 객체가 있을 수 있다.

아래 예를 보자.

 

	public boolean isBabyBoomer() {
		Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

		gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
		Date boomStart = gmtCal.getTime();

		gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
		Date boomEnd = gmtCal.getTime();

		return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0;
	}

위 코드는 1946년부터 1964년 사이에 태어난 사람인지 확인하는 메서드이다.

 

위 메서드는 어떠한 파라미터도 받지 않고, 항상 동일한 작업을 한다. 하지만 Date 클래스인 boomStart와 boomEnd에 Date 객체는 메서드가 호출될 때마다 새롭게 생성된다.

 

또한 Calendar 클래스는 객체를 생성하는데 비용이 꽤 소요되는 클래스인데, 마찬가지로 항상 새롭게 객체를 생성한다.

위 코드는 아래와 같이 변경하면 약 250배 개선된다.

	private static final Date BOOM_START;
	private static final Date BOOM_END;

	/**
	 * The static initializer block is called only once.
	 */
	static {
		Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

		gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
		BOOM_START = gmtCal.getTime();

		gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
		BOOM_END = gmtCal.getTime();
	}

	public boolean isBabyBoomerDoThis() {
		return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0;
	}

 

API가 객체를 새롭게 생성하는지, 생성하지 않는지 잘 확인하자

위에서 String의 literal 방식, Boolean의 정적 팩토리 메서드 방식, Calendar의 getInstance(), getTime() 등의 예를 들었다. 이렇게 각각의 API들이 객체를 재사용하는지, 아니면 새롭게 만드는지 분명하지 않을 수 있다. 그렇기 때문에 API의 객체를 생성할 때는 항상 문서를 잘 읽고 개발자가 원하는 방식에 맞게 잘 사용해야 한다.

 

아래 예를 들어보자.

	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();

		map.put("key1", "val1");
		Set<String> keyset1 = map.keySet();

		map.put("key2", "val2");
		Set<String> keyset2 = map.keySet();

		System.out.println(keyset1 == keyset2); // true

	}

Map의 keySet 메서드는 key값의 목록을 Set 클래스로 반환한다. 위처럼 keyset1을 구하고, 새로운 값을 넣은 후 keyset2를 구했을 때, 일반적으로 생각하기에는 두 값이 서로 다를 것으로 생각한다. 그러나 두 keySet의 값은 동일하다. 

 

그러므로 keySet을 여러 번 호출하여 변수를 여러 개 만들어도 큰일 날 것은 없지만, 쓸데없는 짓이다.

 

다음으로는 많이 알려진 AutoBoxing(자동 객체화)의 문제(?)이다.

AutoBoxing은 기본 자료형(Premitive Type)과 그에 대응하는 객체 클래스와 섞어 사용할 수 있도록 해주는 기능이다.

 

아래 예를 들어보자

	public static void main(String[] args) {
		long start = System.currentTimeMillis();

		Long sum = 0L;
		for (long i = 0; i < Integer.MAX_VALUE; i++) {
			sum += i;
		}
	}

Long 클래스인 sum에 기본 자료형인 i의 값을 더하고 있다. 이때 기본 자료형 i는 AutoBoxing이 되어 자동 객체화된다. 즉 loop를 돌 때마다 객체가 계속 생성된다. 그래서 위의 수행 결과는 글쓴이는 9.988초 소요되었다.

 

위와 같이 짠 개발자가 의도한 게 있는지는 모르겠지만(없을 것이다.) 루프는 기본자료형을 사용하고, 최종적인 결과에서만 Long으로 반환하는 것이 맞을 것이다.

	public static void main(String[] args) {
		long start = System.currentTimeMillis();

		long sum = 0L;
		for (long i = 0; i < Integer.MAX_VALUE; i++) {
			sum += i;
		}
	}

 

반응형

+ Recent posts