Java 패키지 이름 짓기

Posted by epicdev Archive : 2011. 9. 8. 23:43

Naming a Package

With programmers worldwide writing classes and interfaces using the Java programming language, it is likely that many programmers will use the same name for different types. In fact, the previous example does just that: It defines a Rectangle class when there is already a Rectangle class in the java.awt package. Still, the compiler allows both classes to have the same name if they are in different packages. The fully qualified name of each Rectangle class includes the package name. That is, the fully qualified name of the Rectangleclass in the graphics package is graphics.Rectangle, and the fully qualified name of the Rectangle class in the java.awt package is java.awt.Rectangle.

This works well unless two independent programmers use the same name for their packages. What prevents this problem? Convention.

Naming Conventions

Package names are written in all lower case to avoid conflict with the names of classes or interfaces.

Companies use their reversed Internet domain name to begin their package names—for example, com.example.mypackage for a package named mypackage created by a programmer at example.com.

Name collisions that occur within a single company need to be handled by convention within that company, perhaps by including the region or the project name after the company name (for example, com.example.region.mypackage).

Packages in the Java language itself begin with java. or javax.

In some cases, the internet domain name may not be a valid package name. This can occur if the domain name contains a hyphen or other special character, if the package name begins with a digit or other character that is illegal to use as the beginning of a Java name, or if the package name contains a reserved Java keyword, such as "int". In this event, the suggested convention is to add an underscore. For example:

Legalizing Package Names
Domain NamePackage Name Prefix
hyphenated-name.example.org org.example.hyphenated_name
example.int int_.example
123name.example.com com.example._123name

출처: http://download.oracle.com/javase/tutorial/java/package/namingpkgs.html
  

Because와 Since의 용법차이

Posted by epicdev Archive : 2011. 9. 8. 01:57
출처 : http://holycall.tistory.com/entry/Since%EC%99%80-Because%EC%9D%98-%EC%B0%A8%EC%9D%B4 
 
be cause conj
ME (···이유로 (by cause (that))」라는 어원에서 유래한 말로 if, though, as 더불어 「원인이유」를 나타내는 종위접속사의 하나이다그러나 because 이들과 달리 주절 뒤에 오는 일이 많아종위접속사이면서도 등위접속사 for 자리가 같아서 얼핏 보면 for 같은 구문을 쓰는 경우가 많다

as, for, since, now that 
등과의 용법의 차이를 살피면 다음과 같다

because
 가장 강한 뜻의 원인 이유를 직접적으로 나타낸다
I couldn't feel anger against him because I like him too much. 나는 그를 너무 좋아해서 그에게 화를  수가 없었다 

as
 원인 이유를 부수적우연적으로 나타내는 말로 구어체에 쓴다
As it was getting dark, we had to go home. 점점 어두워졌으므로 우리는 집으로 가야만 했다 
for 이유 설명을 곁들일  쓰여 because 비슷하나 구어체에는  쓰지 않는다

since
 상대가  만한 뻔한 원인 이유를 나타낸다
I didn't know that she had been married, since she seldom talked about herself. 그녀가 그녀 자신에 대해 얘기하는 경우가 드물어 그녀가 결혼했었다는 것을 나는 알지 못했다 

now that
 ··· 이상, (이제) ···이니까」의 뜻으로 가벼운 원인을 나타낸다
Now that we have eaten, let's go. 이제 먹었으니까 출발하자
  

변수이름 첫글자에 숫자가 올 수 없는 이유를 써 놓은 것을 보았는데, 핵심을 놓치고 있는것 같아서 적어봅니다.

궁극적인 이유는 lexical analysis의 편의를 위해서입니다.
컴파일 과정은 크게 3단계로 나뉘는데, 첫번째 단계가 lexical analysis, 두번째가 syntax analysis, 세번째가 code generation입니다. 간략히 설명드리자면,

lexical analyzer : 소스코드를 의미를 가지는 최소한의 심볼 단위로 자릅니다. 이렇게 자른 심볼을 lexeme, 즉 어휘라고 부르며, 이 렉심을 종류에 따라 구분하여 이것이 상수인지, 변수인지, 연산자인지를 판단하여 token으로 분류하여, 이 토큰의 열을 구문 분석기로 전달합니다. 따라서 어휘 분석기는 해당 언어에서 허용하는 어휘의 종류를 어떻게 판단할 수 있는지를 알아야 합니다. 즉, 소스 코드의 문자열이 어떻게 구성되어 있느냐에 따라 종류를 구분할 수 있어야 합니다.
예를 들어, a = 10; 이라는 구문이 있을 때, 어휘분석기는 이 구문을 다음과 같이 해석하여 구문 분석기로 전달합니다.
{a, 식별자}
{=, 연산자}
{10, 상수}
{;, 세미콜론}


syntax analyzer : 어휘 분석기로부터 넘어오는 토큰의 열이 문법에 맞는지를 검사합니다. 구문 분석기는 실제 lexeme이 무엇인가는 고려하지 않으며, 토큰의 구성 관계가 문법에서 허용하는 구성 방식인가만을 고려합니다. 따라서 구문 분석기는 언어의 문법에 관한 정보가 필요하게 됩니다. 만약, 언어에서 허용하는 문법 중에 <구문> ::= <식별자> <연산자> <상수> <세미콜론> 이라는 문법이 있고, 위의 예에서와 같이 {a, 식별자}, {=, 연산자}, {10, 상수}, {;, 세미콜론}과 같은 토큰의 열이 들어온다면, 구문 분석기는 lexeme은 고려하지 않고, 토큰의 종류만 보고서 이 토큰의 열이 문법에 맞는 구문이라고 받아들이게 됩니다. 만약, 토큰의 열이 {a, 식별자}, {=, 연산자}, {;, 세미콜론}, {10, 상수} 과 같은 순서라면, 해당하는 문법이 존재하지 않으므로 에러를 내게 됩니다.

code generator : 구문 분석기가 분석한 정보를 바탕으로 실제 오브젝트 코드를 생성합니다. 즉, a=10; 이라는 구문이 문법에서 적절한 구문이라면, a에 해당하는 메모리 번지에 10이라는 값을 쓰는 기계어 코드를 생성합니다.


위 컴파일 과정에서, 어떤 토큰이 변수명인지 상수인지를 구분하는 것은 lexical analyzer의 역할입니다. 이러한 lexical analysis는 기본적으로 문자열의 '패턴'을 보는 것이며, 이러한 문자열의 패턴은 거의 항상 Finite State Machine의 일종인, Deterministic Finite State Automata(이하 DFA)로 해석합니다. 여기에서 DFA의 자세한 동작을 설명드릴 수는 없고, 일단 간략히 설명드리자면, 기본적으로 DFA는 자신의 상태에 따라 입력을 하나씩만 보면서 자신의 상태를 바꿔 나가는 해석기입니다. 즉, 상태0에서 첫 글자가 A이면 상태1로 변하고, 첫글자가 B이면 상태 0으로 그대로, 그 밖의 경우에는 상태2로 변한다, 라는 식입니다. 즉, 글자를 하나씩 보면서 상태가 바뀌되, 그 앞의 입력을 다시 보는 경우는 없다, 라는 것이 DFA의 특징입니다.

이론적으로 DFA는 정규식으로 표현되는 어떠한 패턴의 문자열이라도 그 종류를 구분해 낼 수 있는 능력이 있으므로, lexical analysis의 근간을 이루는 계산 모델을 이룹니다. 하지만, 실제 컴파일러에게 필요한 lexeme의 종류는 한정되어 있으며 일정한 규칙이 있으므로, lexer의 스테이트 전이를 간단하게 만들 수 있는 규칙의 집합을 적절히 설계하는 것이 효율적인 컴파일러 작성에 중요합니다.
따라서, C의 lexer는 이를테면, 다음과 같은 식으로 구성되어 있습니다.

초기상태 : 알파벳, 혹은 _가 들어오면 "식별자 해석 상태"로 전이
초기상태 : 숫자가 들어오면 "상수 해석 상태"로 전이
초기상태 : 그밖의 다른 문자가 들어오면 "연산자 해석 상태"로 전이
식별자 해석 상태 : 알파벳이나 숫자, _가 들어오면 상태를 바꾸지 않음
식별자 해석 상태 : 그밖의 다른 특수문자가 들어오면 지금까지 읽어들인 문자를 모두 식별자로 해석하여 구분문석기에 넘겨주고 "초기상태"로 전이
상수 해석 상태 : 숫자가 들어오면 상태를 바꾸지 않음
상수 해석 상태 : 다른 문자가 들어오면 "XXXXX상태"로 전이
........ (이하생략) .......

즉, 첫 글자를 기준으로 상태를 크게 세 갈래로 바꾸어 해석함으로써 어휘 분석을 쉽게 할 수 있는 장점이 있게 됩니다. 첫글자가 숫자이면 "상수 해석 상태"에서 "식별자 해석 상태"로 전이할 일이 없게 되는 구조가 되어 lexical analysis구현이 훨씬 효율적으로 가능해지는 장점이 있게 되는 것이죠. 자세한 것은 Automata 교재나 컴파일러 교재를 참조하시기 바랍니다.

'Archive' 카테고리의 다른 글

Java 패키지 이름 짓기  (0) 2011.09.08
Because와 Since의 용법차이  (0) 2011.09.08
Callback 함수 튜토리얼  (0) 2011.09.08
쓰레드에 대해 공부하면서 도움이 된 글  (0) 2011.09.08
Hello World!의 기원  (0) 2011.09.08
  

Callback 함수 튜토리얼

Posted by epicdev Archive : 2011. 9. 8. 01:15

출처: http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557

Callback Functions Tutorial



Introduction

If you are reading this article, you probably wonder what callback functions are. This article explains what callback functions are, what are they good for, why you should use them, and so forth. However, before learning what callback functions are, you must be familiar with function pointers. If you aren't, consult a C/C++ book or consider reading the following:

What Is a Callback Function?

The simple answer to this first question is that a callback function is a function that is called through a function pointer. If you pass the pointer (address) of a function as an argument to another, when that pointer is used to call the function it points to it is said that a call back is made.

Why Should You Use Callback Functions?

Because they uncouple the caller from the callee. The caller doesn't care who the callee is; all it knows is that there is a callee with a certain prototype and probably some restriction (for instance, the returned value can be int, but certain values have certain meanings).

If you are wondering how is that useful in practice, imagine that you want to write a library that provides implementation for sorting algorithms (yes, that is pretty classic), such as bubble sort, shell short, shake sort, quick sort, and others. The catch is that you don't want to embed the sorting logic (which of two elements goes first in an array) into your functions, making your library more general to use. You want the client to be responsible to that kind of logic. Or, you want it to be used for various data types (ints, floats, strings, and so on). So, how do you do it? You use function pointers and make callbacks.

A callback can be used for notifications. For instance, you need to set a timer in your application. Each time the timer expires, your application must be notified. But, the implementer of the time'rs mechanism doesn't know anything about your application. It only wants a pointer to a function with a given prototype, and in using that pointer it makes a callback, notifying your application about the event that has occurred. Indeed, the SetTimer() WinAPI uses a callback function to notify that the timer has expired (and, in case there is no callback function provided, it posts a message to the application's queue).

Another example from WinAPI functions that use callback mechanism is EnumWindow(), which enumerates all the top-level windows on the screen. EnumWindow() iterates over the top-level windows, calling an application-provided function for each window, passing the handler of the window. If the callee returns a value, the iteration continues; otherwise, it stops. EnumWindows() just doesn't care where the callee is and what it does with the handler it passes over. It is only interested in the return value, because based on that it continues its execution or not.

However, callback functions are inherited from C. Thus, in C++, they should be only used for interfacing C code and existing callback interfaces. Except for these situations, you should use virtual methods or functors, not callback functions.

A Simple Implementation Example

Now, follow the example that can be found in the attached files. I have created a dynamic linked library called sort.dll. It exports a type called CompareFunction:

typedef int (__stdcall *CompareFunction)(const byte*, const byte*);

which will be the type of your callback functions. It also exports two methods, called Bubblesort() and Quicksort(), which have the same prototype but provide different behavior by implementing the sorting algorithms with the same name.
 

void DLLDIR __stdcall Bubblesort(byte* array,
                                 int size,
                                 int elem_size,
                                 CompareFunction cmpFunc);

void DLLDIR __stdcall Quicksort(byte* array,
                                int size,
                                int elem_size,
                                CompareFunction cmpFunc);


These two functions take the following parameters:

  • byte* array: a pointer to an array of elements (doesn't matter of which type)
  • int size: the number of elements in the array
  • int elem_size: the size, in bytes, of an element of the array
  • CompareFunction cmpFunc: a pointer to a callback function with the prototype listed above

The implementation of these two functions performs a sorting of the array. But, each time there is a need to decide which of two elements goes first, a callback is made to the function whose address was passed as an argument. For the library writer, it doesn't matter where that function is implemented, or how it is implemented. All that matters it is that it takes the address of two elements (that are the two be compared) and it returns one of the following values (this is a contract between the library developers and its clients):

  • -1: if the first element is lesser and/or should go before the second element (in a sorted array)
  • 0: if the two elements are equal and/or their relative position doesn't matter (each one can go before the other in a sorted array)
  • 1: if the first element is greater and/or should go after the second element (in a sorted array)

With this contract explicitly stated, the implementation of the Bubblesort() function is this (for Quicksort(), which a little bit more complicated, see the attached files).

void DLLDIR __stdcall Bubblesort(byte* array,
                                 int size,
                                 int elem_size,
                                 CompareFunction cmpFunc)
{
   for(int i=0; i < size; i++)
   {
      for(int j=0; j < size-1; j++)
      {
         // make the callback to the comparison function
         if(1 == (*cmpFunc)(array+j*elem_size,
                  array+(j+1)*elem_size))
         {
            // the two compared elements must be interchanged
            byte* temp = new byte[elem_size];
            memcpy(temp, array+j*elem_size, elem_size);
            memcpy(array+j*elem_size,
                   array+(j+1)*elem_size,
                   elem_size);
            memcpy(array+(j+1)*elem_size, temp, elem_size);
            delete [] temp;
         }
      }
   }
}
Note: Because the implementation uses memcpy(), these library functions should not be used for types other than POD (Plain-Old-Data).

 

On the client side, there must be a callback function whose address is to be passed to the Bubblesort() function. As a simple example, I have written a function that compares two integer values and one that compares two strings:

To put all these to a test, I have written this short program. It passes an array with five elements to Bubblesort() or Quicksort() along with the pointer to the callback functions.

int main(int argc, char* argv[])
{
   int i;
   int array[] = {5432, 4321, 3210, 2109, 1098};

   cout << "Before sorting ints with Bubblesort\n";
   for(i=0; i < 5; i++)
      cout << array[i] << '\n';

   Bubblesort((byte*)array, 5, sizeof(array[0]), &CompareInts);

   cout << "After the sorting\n";
   for(i=0; i < 5; i++)
      cout << array[i] << '\n';

   const char str[5][10] = {"estella",
                            "danielle",
                            "crissy",
                            "bo",
                            "angie"};

   cout << "Before sorting strings with Quicksort\n";
   for(i=0; i < 5; i++)
      cout << str[i] << '\n';

   Quicksort((byte*)str, 5, 10, &CompareStrings);

   cout << "After the sorting\n";
   for(i=0; i < 5; i++)
      cout << str[i] << '\n';

   return 0; 



If I decide that I want the sorting to be done descending (with the biggest element first), all I have to do is to change the callback function code, or provide another that implements the desired logic.

Calling Conventions

In the above code, you can see the word __stdcall in the function's prototype. Because it starts with a double underscore, it is, of course, a compiler-specific extension, more exactly a Microsoft-specific one. Any compiler that supports development of Win32-based applications must support this or an equivalent one. A function that is marked with __stdcall uses the standard calling convention so named because all Win32 API functions (except the few that take variable arguments) use it. Functions that follow the standard calling convention remove the parameters from the stack before they return to the caller. This is the standard convention for Pascal. But in C/C++, the calling convention is that the caller cleans up the stack instead of the called function. To enforce that a function uses the C/C++ calling convention, __cdeclmust be used. Variable argument functions use the C/C++ calling convention.

Windows adopted the standard calling convention (Pascal convention) because it reduces the size of the code. This was very important in the early days of Windows, when it ran on systems with 640 KB RAM.

If you don't like the word __stdcall, you can use the CALLBACK macro, defined in windef.h, as

#define CALLBACK    __stdcall

or

#define CALLBACK    PASCAL

where PASCAL is #defined as __stdcall.

You can read more about calling convention here: Calling Convetions in Microsoft Visual C++.

C++ Methods as Callback Functions

Because you probably write in C++, you want your callback function a method of a class. But, if you try this:

class CCallbackTester
{
public:
   int CALLBACK CompareInts(const byte* velem1, const byte* velem2);
};

Bubblesort((byte*)array, 5, sizeof(array[0]),
           &CCallbackTester::CompareInts);


with a MS compiler, you get this compilation error:

error C2664: 'Bubblesort' : cannot convert parameter 4 from 'int (__stdcall CCallbackTester::*)(const unsigned char *,const unsigned char *)' to 'int (__stdcall *)(const unsigned char *,const unsigned char *)' There is no context in which this conversion is possible

That happens because non-static member functions have an additional parameter, pointer this (see thisFAQ for more).

That obliges you to make the member function static. If that's not acceptable, you can use several techniques to overcome that. Check the following links to learn more.

Notices

The attached files contain two projects. SortingDLL is a Win32 DLL project. The sort.dll output library exports the two sorting functions, Bubblesort() and Quicksort(). The second project, SortDemo, is a Win32 Console Application that demonstrates how to use the sort.dll library. The output directory for both projects is Shared directory, where the following files can be found: sort.h, sort.dll, sort.lib, and SortDemo.exe.

Further References

  

쓰레드에 대해 공부하면서 도움이 된 글

Posted by epicdev Archive : 2011. 9. 8. 01:12
  

Hello World!의 기원

Posted by epicdev Archive : 2011. 9. 8. 01:07
처음 프로그래밍을 접하게 되면 가장 먼저 화면에 출력해보는 "Hello World!" 문자열

누구나 한번쯤은 왜 이런 걸 테스트용으로 사용하는걸까? 하는 질문을 해보았을 것입니다.

이 Hello World 문자열은 Brian Kernighan이 1972년에

Tutorial Introduction to the Language B 라는 문서에서 처음 사용하였습니다.
main( ) {
  extrn a, b, c;
  putchar(a); putchar(b); putchar(c); putchar('!*n');
}
a 'hell';
b 'o, w';
c 'orld';

하지만 직접적인 영향은 1978년에 출판된 그의 책 "The C Programming Language"의 영향 때문입니다.
main() {
        printf("hello, world");
 }

이 예제는 그가 1974년 Bell Lab의 회보에 투고한 Programming in C: A Tutorial 이라는 제목의 글에서 예시로 처음 쓰였는데, 그 예시를 그의 책에 싣게 되어 "Hello World!"가 유명세를 타게 된 것입니다.
  
다른 개발자들에게 API를 제공한다는 마음으로 개발하라
남이 봐도 쉬운 코드를 만들어라
'역사적'인 이유를 만들지 말아라
자신의 코드만 보지 말아라
기존의 코드와 통일성 있는 코드를 작성하라
커뮤니케이션 하라
항상 '1년 뒤에 이 소스를 본다면?' 이라고 생각하라 
리팩토링 하라 


패턴그리고객체지향적코딩의법칙
카테고리 컴퓨터/IT > 프로그래밍/언어
지은이 문우식 (한빛미디어, 2007년)
상세보기

  

Tail recursion

Posted by epicdev Archive : 2011. 9. 8. 01:02
  

const identifiers are often better than #define because:

they obey the language’s scoping rules
you can see them in the debugger
you can take their address if you need to
you can pass them by const-reference if you need to
they don’t create new “keywords” in your program.
In short, const identifiers act like they’re part of the language because they are part of the language. The preprocessor can be thought of as a language layered on top of C++. You can imagine that the preprocessor runs as a separate pass through your code, which would mean your original source code would be seen only by the preprocessor, not by the C++ compiler itself. In other words, you can imagine the preprocessor sees your original source code and replaces all #define symbols with their values, then the C++ compiler proper sees the modified source code after the original symbols got replaced by the preprocessor.

There are cases where #define is needed, but you should generally avoid it when you have the choice. You should evaluate whether to use const vs. #define based on business value: time, money, risk. In other words, one size does not fit all. Most of the time you’ll use const rather than #define for constants, but sometimes you’ll use #define. But please remember to wash your hands afterwards.

  

Memory management is done automatically in Java. The programmer doesn't need to worry about reference objects that have been released. One downside to this approach is that the programmer cannot know when a particular object will be collected. Moreover, the programmer has no control over memory management. However, the java.lang.ref package defines classes that provide a limited degree of interaction with the garbage collector. The concrete classes SoftReference,WeakReferenceand PhantomReference are subclasses of Reference that interact with the garbage collector in different ways. In this article we will discuss the functionality and behavior of the PhantomReference classes and see how it can be used.

Problem with Finalization

To perform some postmortem cleanup on objects that garbage collector consider as unreachable, one can usefinalization. This feature can be utilized to reclaim native resources associated with an object. However, finalizers have many problems associated.

Firstly, we can’t foresee the call of finalize(). Since the Garbage Collection is unpredictable, the calling of finalize() cannot be predicted. There is no guarantee that the object will be garbage collected. The object might never become eligible for GC because it could be reachable through the entire lifetime of the JVM. It is also possible that no garbage collection actually runs from the time the object became eligible and before JVM stops.

Secondly, Finalization can slowdown an application. Managing objects with a finalize() method takes more resources from the JVM than normal objects.

As per doc,

You should also use finalization only when it is absolutely necessary. Finalization is a nondeterministic -- and sometimes unpredictable -- process. The less you rely on it, the smaller the impact it will have on the JVM and your application

 In Effective Java, 2nd ed., Joshua Bloch says,

there is a severe performance penalty for using finalizers... So what should you do instead of writing a finalizer for a class whose objects encapsulate resources that require termination, such as files or threads? Just provide an explicit termination method, and require clients of the class to invoke this method on each instance when it is no longer needed.

In short, Finalize() isn't used often, and also there is no much reason to use it. If we have a class with methods likeclose() or cleanup() and that should be called once user done with the object then placing these methods call in finalize()can be used as a safety measure, but not necessary.

Phantom Reference

phantom reachable, phantomly reachable

An object is phantom reachable if it is neither strongly nor softly nor weakly reachable and has been finalized and there is a path from the roots to it that contains at least one phantom reference.

The PhantomReference constructor accepts two arguments:

referent - the object the new phantom reference will refer to
q - the reference is registered with the given queue.

The argument q represents the instance of the ReferenceQueue class. If the garbage collector determines that the referent of a phantom reference is phantom reachable, then the PhantomReference will be added to thisReferenceQueue. You can then retrieve the PhantomReference by using the remove() methods of the ReferenceQueueclass.

Consider the following example,

1.ReferenceQueue q = new ReferenceQueue();
2.PhantomReference pr = new PhantomReference(object, referenceQueue);
3. 
4.// Later on another point
5.Reference r = q.remove();
6. 
7.// Now, clear up any thing you want

PhantomReference, when to use?

Phantom Reference can be used in situations, where sometime using finalize() is not  sensible thing to do.This reference type differs from the other types defined in java.lang.ref Package because it isn't meant to be used to access the object, but as a signal that the object has already been finalized, and the garbage collector is ready to reclaim its memory.

As per API doc,

Phantom reference objects, which are enqueued after the collector determines that their referents may otherwise be reclaimed. Phantom references are most often used for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism.

People usually attempt to use finalize() method to perform postmortem cleanup on objects which usually not advisable. As mentioned earlier, Finalizers have an impact on the performance of the garbage collector since Objects with finalizers are slow to garbage collect.

Phantom references are safe way to know an object has been removed from memory. For instance, consider an application that deals with large images. Suppose that we want to load a big image in to memory when large image is already in memory which is ready for garbage collected. In such case, we want to wait until the old image is collected before loading a new one. Here, the phantom reference is flexible and safely option to choose. The reference of the old image will be enqueued in the ReferenceQueue once the old image object is finalized. After receiving that reference, we can load the new image in to memory.

Similarly we can use Phantom References to implement a Connection Pool. We can easily gain control over the number of open connections, and can block until one becomes available.

Reference Objects and Garbage Collection

Soft Reference can be garbage collected after there are no strong references to the referent. However, it typically retained until memory is low. All softly reachable objects will be reclaimed before an OutOfMemoryException is thrown. Therefore, it can be used to implement caches of objects that can be recreated if needed. 

Weak Reference can be garbage collected when there are no strong or soft references to the referent. However, unlikeSoft Reference, they are garbage collected on a gc even when memory is abundant. They often can be used for “canonical mappings” where each object has a unique identifier (one-to-one), and in collections of “listeners”

On the other hand, Phantom Reference, can be garbage collected once there are no strong, soft or weak references to the referent. When object is phantomly reachable, it means the object is already finalized but not yet reclaimed, so the GC enqueues it in a ReferenceQueue for post-finalization processing.

As per Java Doc,

Unlike soft and weak references, phantom references are not automatically cleared by the garbage collector as they are enqueued. An object that is reachable via phantom references will remain so until all such references are cleared or themselves become unreachable.

PhantomReference is not automatically cleared when it is enqueued, so when we remove a PhantomReference from aReferenceQueue, we must call its clear() method or allow the PhantomReference object itself to be garbage-collected. 

Summary

In short, we should avoid finalize() as much as possible. There is no guarantee if the finalize() method will be called promptly following garbage collection, or even it will be called. If the finalize method runs for a long time, it can delay execution of finalize methods of other objects. Instead of relying on finalize(), we can use reference types define injava.lang.ref package.

Beside java.lang.ref package, Google collection library also provide some alternatives. For example,FinalizablePhantomReference extends java.lang.ref.PhantomReference, deals with processing the ReferenceQueue and call back a convenient method finalizeReferent(). So if we want to do some cleanup operation when an object is claimed by the garbage collector (GC) then we just need to override the finalizeReferent() method.

Resources

Garbage Collection

PhantomReference

http://docstore.mik.ua/orelly/java-ent/jnut/ch13_01.htm

Understanding Weak References

출처: 
http://java.dzone.com/articles/finalization-and-phantom 

  
 «이전 1 ··· 13 14 15 16 17  다음»