달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
2010. 5. 19. 15:49

Heapdump 파일 생성 이유 I.lib()/I.lib(Java)2010. 5. 19. 15:49

.. .. ..

웹서버 로그에 OutOfMemory에러가 떨어지며 루트 상에 core파일과 heapdump파일을 떨군다.
이게 지속되면 쌓이기 때문에 부하가 생겨 서버에 문제를 준다.
일단 원인은 메모리 부족 현상으로
과다한 데이터 양 조회, 무리하거나 비정상적인 화면 운용, 무거운 쿼리, 무거운 어플리케이션 화면,
동적 쿼리가 잘못 생성되는 것, 세션끊김현상
이 있다.

세션끊김 현상 : 세션이 끊길 경우에 대비한 우회 비즈니스 로직 구현

과다한 데이터 양 : fatch size의 조절로 무리하지 않는 선에서 진행하거나 메모리를 늘린다. money is 진리.
 
무리하거나 비정상적인 화면 , 쿼리, 화면 등의 이유 : 성능 튜닝이 길.

.
:
Posted by .07274.
2010. 4. 8. 18:10

JNDI 란? I.lib()/I.lib(Java)2010. 4. 8. 18:10

.. .. ..

1. 사전전 의미

JNDI (Java Naming and Directory Interface)

JNDI는 자바 프로그램들을 DNS, LDAP 및 NDS 등과 같은 네이밍/디렉토리 서비스에 연결하기 위한 썬의 API이다.
애플리케이션은 JNDI API에 작성되어 있으며, 디렉토리 드라이버는 JNDI SPI (Service Provider Interface)에 작성되어 있다.
JNDI는 썬의 J2EE 플랫폼의 일부이다.

2. JNDI 서비스의 종류

   - LDAP(Lightweight Directory Access Protocol) : 네트워크 디렉토리 서비스의 표준인 x.500을 위한 경량화 프로토콜
   - DNS(Domain Name System) : 인터넷 네이밍 시스템, 컴퓨터 이름(도메인)을 IP주소로 변환
   - NIS(Network Information System) : SUN에서 개발된 네트워크 네이밍 서비스
   - RMIRemote Method Invocation)  : 분산 객체 응용 프로그램
   - CosNaming(Common Object Services) : 코바응용프로그램을 위한 네이밍 서비스 지원 
   => JNDI SPI(Service Provider Interface) 제공

3.JNDI의 구조

 Java Application

 JNDI API

Naming Manager

JNDI SPI

  LDAP, NIS, DNS, RMI,CORBA


.
:
Posted by .07274.
2010. 3. 29. 14:19

자바 리플랙션 (Java Reflection) I.lib()/I.lib(Java)2010. 3. 29. 14:19

.. .. ..
일상에서의 리플렉션(reflection)이란 거울 속에 비친 자신의 모습입니다. 프로그래밍 세상에서의 리플렉션은 프로그램이 자신의 모습을 보고 심지어 수정하기 까지 하는 것을 말합니다. Java reflection API는 바로 그런 기능을 언어의 기본 요소인 클래스, 필드, 메소드를 들여다 볼 수 있는 평범한 Java API를 통해 제공합니다. 리플렉션을 이해하는 것은 여러분이 자주 사용하는 툴을 이해하는데 도움이 됩니다. Eclipse가 어떻게 자동완성으로 메소드 이름을 만들어 줄까? Tomcat은 web.xml파일에 있는 클래스 이름을 가지고 웹의 요청을 처리할 서블릿을 실행하는 걸까? Spring은 어떻게 마술 같은 dependency injection을 하는 것일까? 여러분의 프로그램에서도 리플렉션을 사용하여 보다 동적이고 유연한 코드를 작성하실 수 있습니다. 리플렉션을 사용하면 이전에 본적 없는 클래스들을 매우 멋지게 처리할 수 있습니다.

클래스 만들기

이미 말했듯이 리플렉션의 기본 아이디어는 프로그램이 동작하는 내부에 집어 넣을 API를 제공하는 것입니다. Java에서 가장 기본이 되는 사상이 바로 클래스기 때문에(클래스 없이 자바 프로그램을 만들어 보세요) Class 클래스부터 살펴보는 것이 좋겠습니다. 이것의 객체는 Class 타입일 것입니다. 일단 Class객체를 가지게 되면 그것으로부터 클래스에 관련된 모든 정보를 뽑아낼 수 있습니다. 클래스의 이름, 그것이 public 인지 abstract 인지 final 인지 그리고 심지어 상위 클래스까지 말이죠.

이 정도면 이론은 충분합니다. 자, 이제 리플렉션 현미경을 가지고 아래에 있는 매우 간단한 Employee 클래스를 살펴봅시다.
package com.russolsen.reflect;

public class Employee{
   public String _firstName;
   public String _lastName;
   private int _salary;

      public Employee()   {
      this( "John", "Smith", 50000);
   }
 
   public Employee(String fn, String ln, int salary)   {
      _firstName = fn;
      _lastName = ln;
      _salary = salary;
   }
   
   public int getSalary()   {
      return _salary;
   }
   
   public void setSalary(int salary)   {
      _salary = salary;
   }
   
   public String toString()    {
      return "Employee: " + _firstName +  " "
             + _lastName + " " + _salary;
   }

}
Class 객체를 만드는 가장 쉬운 방법은 해당 클래스 객체의 getClass 메소드를 호출하는 것입니다. 아래에 있는 코드는 Employee 객체를 만들고 그것의 Class 객체를 만들어서 클래스에 대한 다양한 정보들을 출력합니다.
package com.russolsen.reflect;

import java.lang.reflect.Modifier;

public class GetClassExample{
   public static void main(String[] args)   {
 
      Employee employee = new Employee();
      Class klass = employee.getClass();
      
      System.out.println( "Class name: " + klass.getName());
      System.out.println( "Class super class: " + klass.getSuperclass());
      
      int mods = klass.getModifiers();
      System.out.println( "Class is public: " + Modifier.isPublic(mods));
      System.out.println( "Class is final: " +  Modifier.isFinal(mods));
      System.out.println( "Class is abstract: " + Modifier.isAbstract(mods)); 
   }

}
코드를 실행하면 다음과 같은 결과를 확인할 수 있습니다.
Class name: com.russolsen.reflect.Employee
Class super class: class java.lang.Object
Class is public: true
Class is final: false
Class is abstract: false
예제에서 보이듯이 클래스의 이름과 상위 클래스를 알아내는 것은 다른 접근 메소드들(Getters or Accessors)을 호출하는 것처럼 쉬운 일입니다. 만약 해당 클래스가 public 인지 abstract 인지 final 인지 알고 싶다면 약간 복잡해 집니다. 이 모든 정보가 getModifires에 의해 하나의 int 값으로 패키징되어 넘어오기 옵니다. 다행히 Java는 Modifier 클래스를 통해 getModifiers에서 넘어온 숫자를 가지고 여러 일을 할 수 있는 static 메소드들을 제공해 줍니다.

객체에 getClass를 호출하는 것 만이 Class 객체를 얻을 수 있는 유일한 방법은 아닙니다. 클래스 이름을 사용하여 직접 얻을 수도 있습니다.
Class klass = Employee.class;
 
세 번째 방법은 좀 더 흥미로운 방법입니다. 문자열을 통해서 Class 객체를 생성할 수 있습니다. 물론 그 문자열이 클래스 이름을 포함하고 있을 때 말이죠. 다음과 같이 Class 클래스에 있는 forName 을 호출하여 얻을 수 있습니다.
      Class klass = Class.forName("com.russolsen.reflect.Employee");
      
      System.out.println( "Class name: " + klass.getName());
      System.out.println( "Class super class: " + klass.getSuperclass());
      
      // Print out the rest...
forName을 사용할 때 한 가지 주의할 것은 클래스 이름 앞에 완전한 패키지 경로를 붙여줘야 한다는 것입니다. 평범하고 늙은 “Employee” 말고 “com.russolsen.reflect.Employee" 여야만 합니다. forName을 통해 리플렉션 API의 기본적인 강력함(그리고 멋진 것)을 살펴봤습니다. 클래스 이름을 포함한 문자열로 시작할 수도 있고 class로 끝낼 수도 있습니다.

바로 인스턴스 만들기

class 객체를 가져오고 그것에 관한 정보를 찾는 것은 그것 자체로도 흥미롭고 유용합니다. 하지만 진짜 재미있는 것은 리플렉션을 사용하여 무언가를 실제 해보는 것입니다. Class 객체를 가지고 할 수 있는 가장 눈에 띄는 작업은 그 클래스의 새로운 객체를 만드는 것입니다. newInstance 메소드를 사용하여 간단하게 만들 수 있습니다. 실제 사용하는 것을 보여 주기 위하여 아래에 있는 간단한 프로그램은 커맨드 라인 인자(command line argument)로 Class 객체를 만들고 그 클래스 타입의 객체를 만드는 프로그램을 보여줍니다.
package com.russolsen.reflect;

public class NewInstanceExample
{
   public static void main(String[] args)
      throws ClassNotFoundException,
      InstantiationException, IllegalAccessException
   {

      Class klass = Class.forName(args[0]);
      Object theNewObject = klass.newInstance();
      System.out.println("Just made: " + theNewObject);
   }
}
위 코드를 "com.russolsen.reflect.Employee" 인자와 함께 실행하면 새로운 Employee 객체를 만들게 됩니다.
Just made: Employee: John Smith 50000

Run it again, but this time feed it "java.util.Date" and you will get:

Just made: Tue Feb 27 20:25:20 EST 2007
간단한 코드 몇 줄로 얼마나 많은 유연성을 얻게 되었는지 생각해보세요. 위에 있는 프로그램은 실제 Employee 나 Date 클래스에 관해 아는 것이 하나도 없지만 각각의 새로운 객체들을 만들 수 있습니다. 이것이야 말로 Java 프로그래밍을 하는 또 다른 방법입니다.

인자 없는 생성자 너머에

Class.newInstance 메소드를 호출하는 것은 인자 없이 new를 사용하는 것과 동일합니다. 그러나 만약 인자가 없는 생성자 즉 default 생성자가 없는 클래스에 newInstance를 호출하면 어떻게 될까요? 좋을 일 없습니다. 별로 맘에 안 드는 InstantiationException을 받게 됩니다.

좋은 소식이 있습니다. 생성자 인자를 필요로 하는 클래스의 객체를 동적으로 만들 수 있습니다. 하지만 약간 더 힘든 작업을 해야 합니다. 그건 바로 클래스에서 해당 생성자를 찾고 적당한 인자를 사용하여 그것을 호출하는 일입니다. 적당한 생성자를 찾는 일은 여러분이 찾고자 하는 생성자에 대한 정보를 가지고 getConstrucor 메소드를 사용하면 됩니다. 그럼 Constuctor 객체를 얻게 되고 그것을 사용하여 새로운 객체를 만들 수 있습니다.
Let's see how this all works in code:
      Class klass = Class.forName("com.russolsen.reflect.Employee");

      Class[] paramTypes = {
            String.class, 
            String.class, 
            Integer.TYPE };
      
      Constructor cons = klass.getConstructor(paramTypes);
      
      System.out.println( "Found the constructor: " + cons);

      
      Object[] args = { 
            "Fred", 
            "Fintstone", 
            new Integer(90000) };
      
      Object theObject = cons.newInstance(args);
      System.out.println( "New object: " + theObject);
생성자들 사이의 차이점은 오직 그것들이 가지고 있는 매개 변수들입니다. 따라서 getConstructor 메소드에 찾고자 하는 생성자에 들어갈 매개변수 각각의 Class들 객체의 배열을 넘겨줍니다. 위에 있는 예제에서는 두 개의 String 그리고 하나의 int를 받는 생성자를 찾게 됩니다. Constructor 객체를 얻은 뒤 새로운 객체를 생성하는 일은 간단합니다. 실제 인자로 들어갈 객체의 배열을 newInstance 메소드를 호출하면서 넘겨주면 됩니다.

geConstructor에는 조그만 지뢰가 하나 있습니다. 파라미터의 타입으로 생성자를 식별하여 원하는 것을 찾을 때 primitive 인자와 그것의 wrapper 클래스를 잘 구별해야 합니다. 생성자가 인자로 primitive 타입인 int를 받는 것인가 아니면 그것의 삼촌 격인 java.lang.Integer 클래스의 객체를 받는 건가요? 만약 java.lang.integer 같은 wrapper 타입의 객체를 받는 생성자라면 Integer.class처럼 wrapper 클래스를 사용하면 됩니다. primitive 타입인 int를 사용하는 생성자라면 Integer.TYPE을 사용합니다. TYPE은 primitive을 위해 마련한 것입니다. 모든 wrapper 클래들은 static 타입인 TYPE 필드를 가지고 있고 이것을 사용하여 primitive 타입이라는 것을 알려줄 수 있습니다

----------------------------------------------------------------------------------

클래스를 좀 더 자세히 살펴보기

첫 번째 예제에서 봤듯이 Class 객체는 그것의 이름이나 상위 클래스 같은 정보를 제공합니다. 이 이름을 사용하여 좀 더 자세히 rank 와 시리얼 넘버(serial number) 차원의 정보까지 알 수 있습니다. 예를 들어 getMethods 메소드를 사용하여 클래스가 가진 모든 public 메소드를 찾을 수 있습니다.
      Class klass = Class.forName("com.russolsen.reflect.Employee");
           
      Method[] methods = klass.getMethods();
      
      for(Method m : methods )   {
         System.out.println( "Found a method: " + m );
      }
getMethods 는 클래스가 가지고 있는 public 메소드 각각에 해당하는 Method 객체의 배열을 반환합니다.
Found a method: public java.lang.String com.russolsen.reflect.Employee.toString()
Found a method: public int com.russolsen.reflect.Employee.getSalary()
Found a method: public void com.russolsen.reflect.Employee.setSalary(int)
Found a method: public native int java.lang.Object.hashCode()
Found a method: public final native java.lang.Class java.lang.Object.getClass()
Found a method: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
Found a method: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
Found a method: public final void java.lang.Object.wait() throws java.lang.InterruptedException
Found a method: public boolean java.lang.Object.equals(java.lang.Object)
Found a method: public java.lang.String java.lang.Object.toString()
Found a method: public final native void java.lang.Object.notify()
Found a method: public final native void java.lang.Object.notifyAll()
getMethods는 클래스의 사용자(client) 입장이기 때문에, 배열에는 자신이 가지고 있는 모든 public 메소드 (Object 까지 달하는 모든 상속 계층의 상위 클래스들에 있는 public 메소드까지 포함하여)를 배열에 담아 줍니다.

만약 하나의 메소드에만 관심이 있다면, getMethod(단수 형태 입니다.)를 사용할 수 있습니다. getConstructor와 비슷하게 동작하지만 파라미터 타입들 뿐만 아니라 메소드의 이름도 넘겨 줘야 합니다. 아래에 있는 코드는 하나의 int 파라미터를 가지는 setSalary 라는 메소드를 찾습니다.
      Class klass = Class.forName("com.russolsen.reflect.Employee");
      Class[] paramTypes = {Integer.TYPE };
      Method setSalaryMethod = 
         klass.getMethod("setSalary", paramTypes);
           
      System.out.println( "Found method: " + setSalaryMethod);
리플렉션을 사용하여 메소드를 호출하는 것은 constuctor를 호출하는 것과 매우 유사합니다. 앞서 살펴봤던 Method 객체만 있으면 되고 메소드에 인자로 넘겨 줄 배열과 메소드를 호출할 객체가 필요합니다. 아래에 있는 코드는 우리 직원에게 월급을 올려주기 위해서 Employee 객체에 있는 setSalary 메소드를 호출합니다.
      Class klass = Class.forName("com.russolsen.reflect.Employee");

      Class[] paramTypes = {Integer.TYPE };
      Method setSalaryMethod = 
         klass.getMethod("setSalary", paramTypes);
      
      Object theObject = klass.newInstance();
      Object[] parameters = { new Integer(90000) };
      
      setSalaryMethod.invoke(theObject, parameters);
그냥 theObject.setSalary(9000)를 호출하지 않고 왜 그렇게 귀찮게 했을까요? 위에 있는 코드를 자세히 살펴보시길 바랍니다. 코드의 첫 번째 줄을 빼면 위에 있는 프로그램은 완전히 일반적입니다. 어떤 클래스의 어떤 객체든 상관없이 setSalary 메소드를 호출할 것입니다. 약간만 수정하면 어떤 클래스의 어떤 객체든 거기에 있는 모든 메소드를 호출하는 코드로 사용할 수 있습니다.

필드 가지고 놀기

리플렉션을 사용하여 메소드를 호출하는 데에서 그치지 않습니다. 필드에 대한 모든 권한 역시 가지고 있습니다. getMethods 처럼 getFields는 해당 클래스 또는 그것의 상위 클래스에 있는 모든 public 필드 각각에 대한 Fileld 객체의 배열을 반환합니다.
      Class klass = Class.forName("com.russolsen.reflect.Employee");
      System.out.println( "Class name: " + klass.getName());
      Field[] fields = klass.getFields();
      for(Field f : fields ){
         System.out.println( "Found field: " + f);
      }
Employee 가 두 개의 public 필드를 가지고 있기 때문에 두 개의 멤버를 가진 배열을 얻게 됩니다. 
Class name: com.russolsen.reflect.Employee
Found field: public java.lang.String com.russolsen.reflect.Employee._firstName
Found field: public java.lang.String com.russolsen.reflect.Employee._lastName
getField메소드를 사용하여 특정 필드 하나만 가져올 수도 있습니다.
      Field field = klass.getField("_firstName");
      System.out.println("Found field: " + field);
Field 객체를 가지고 get 메소드를 호출하면 필드가 가진 값을 가져올 수 있고 set을 사용하여 값을 설정할 수 있습니다.
      Object theObject = new Employee("Tom", "Smith", 25);
      
      Class klass = Class.forName("com.russolsen.reflect.Employee");
      
      Field field = klass.getField("_firstName");
      
      Object oldValue = field.get(theObject);
      System.out.println( "Old first name is: " + oldValue);
      
      field.set( theObject, "Harry");
      Object newValue = field.get(theObject);
      System.out.println( "New first name is: " + newValue);
위에 있는 코드를 실행하고 _firstName 필드가 변하는 것을 주의 깊게 살펴보시기 바랍니다.
Old first name is: Tom
New first name is: Harry
규칙 깨기

Java의 가장 신성한 규칙 중 하나를 깨는 방법을 얘기하지 않고서는 리플렉션을 마무리할 수 없습니다. 여러분 모두 잘 알다시피 해당 클래스 밖에서는 private 메소드를 호출 할 수 없습니다. 그렇죠? 아마 평범한 기술을 사용하는데 그친다면 하지 못할 것입니다. 하지만 리플렉션을 사용하면 거의 모든 걸 할 수 있습니다.

private 메소드를 호출하기 위해서 가장 먼저 해야 할 일은 호출하고 싶어 하는 메소드를 나타내는Method객체를 얻는 것입니다. getMethod로는 얻을 수 없습니다. 그건 오직 public 메소드만 반환합니다. private(또는 protected)메소드를 가져오는 방법은 getDeclaredMethod를 사용하는 것입니다. getMethod는 해당 클래스의 사용자 관점(client’s view)에서 public 메소드만 가져오지만, getDeclaredMethod는 클래스에 선언한 모든 메소드를 반환합니다. 아래에 있는 예제에서 java.util.ArrayList 클래스에 있는 private 메소드인 removeRange 를 가져옵니다.
      ArrayList list = new ArrayList();
      list.add("Larry");
      list.add("Moe");
      list.add("Curley");

      System.out.println("The list is: " + list);

      Class klass = list.getClass();

      Class[] paramTypes = { Integer.TYPE, Integer.TYPE };
      Method m = klass.getDeclaredMethod("removeRange", paramTypes);

      Object[] arguments = { new Integer(0), new Integer(2) };
      m.setAccessible(true);
      m.invoke(list, arguments);
      System.out.println("The new list is: " + list);
private 메소드를 받은 뒤에 간단히 setAccessable 안전장치를 제거하고 호출하면 됩니다.
The list is: [Larry, Moe, Curley]
The new list is: [Curley]
removeRange 메소드는 리스트에서 주어진 범위의 아이템을 제거하는 것처럼 보입니다. 이것은 매우 강력한 마술입니다. java.util 에 있는 클래스에 접근하여 그 안에 있는 private 메소드를 호출할 수 있습니다. 이것을 사용하여 코드의 의도를 우회하여 private 메소드를 호출하는 취미를 즐기실 건가요? 아니죠! 그러나 저런 것들이 약간은 유용할 때가 있습니다.

결론

리플렉션을 사용하여 Java의 규칙을 무시하는 것처럼 보이는 것들을 하는 프로그램을 작성할 수 있습니다. 일반적으로는 알 수 없는 클래스에 관한 정보를 모두 알아내는 코드를 작성할 수 있습니다. 그리고 동적으로 알아낸 정보에 어떤 행위를 할 수도 있습니다. 즉 새로운 객체를 만들고 메소드를 호출하고 필드에 값을 설정하거나 가져올 수 있습니다. 극단적인 경우에서는 클래스의 private 멤버들에 접근할 수 있습니다. 점점 복잡해져가는 Java 개발 툴의 동작을 이해하기 위해서는 리플렉션에 대한 이해가 필요합니다. 또한 “평범한” Java 프로그램이 할 수 있는 것 이상의 프로그램을 작성해야 할 때도 필요합니다.


제공 : 한빛 네트워크
저자 : Russ Olsen
역자 : 백기선
원문 : Reflections on Java Reflection

'I.lib() > I.lib(Java)' 카테고리의 다른 글

Heapdump 파일 생성 이유  (0) 2010.05.19
JNDI 란?  (1) 2010.04.08
자바의 abstract와 인터페이스(Interface)  (0) 2010.03.24
Javap 란? (자바 역어셈블러)  (1) 2010.03.24
POJO (Plain Old Java Object) 란?  (0) 2010.03.23
.
:
Posted by .07274.
.. .. ..

1> abstract 키워드란?

하위 클래스에서 반드시 오버라이딩(재정의)를 해줘야만 하는 키워드이다.
메서드와 클래스에만 쓸수 있다.

2> abstract 특징

  1. 클래스와 메서드에만 사용 가능.
  2. 메서드에서는 프로타입(선언부)만 정의, 내용(구현부)은 없다.
  3. abstract 은 final, static과 같이 쓸순없다.

3> abstract 클래스 인경우

  1. 미완성 클래스(추상메서드가 포함된 클래스는 자동으로 추상클래스가 됨)
  2. 추상클래스는 추상메서드를 포함 가능(반드시 포함해야 하는 것은 아님)
  3. 구조상 상속해서 재정의해야만 사용 가능
  4. 자체적으로 객체를 생성할 수 없음
  5. 하위클래스에서 추상메서드를 반드시 구현(오버라이딩)해야 함
  6. 형식>>> abstract class 클래스명 {.......}

4> abstract 메서드 인경우

  1. 메서드의 원형만 선언된 메서드 : 블록({})이 없는 메서드
  2. 하위 클래스에서 반드시 오버라이딩해야함.
  3. 추상메서드를 포함하는 클래스는 반드시 추상클래스
  4. 형식>>> abstract 반환형 메서드명 (인자);

5> abstract 클래스 vs abstract 메서드

  • 추상메서드를 포함하는 클래스는 반드시 추상클래스
    -- 클래스에 abstract를 표시하지 않으면 에러
  • 추상클래스는 추상메서드를 포함 가능
    -- 반드시 포함해야 하는 것은 아님
  • 하위클래스에서 상속 받은 추상메서드를 반드시 재정의해야 함




▶ 인터페이스(Interface)

 1> 인터페이스(Interface)란?

 자바에서는 다중상속(여러 클래스로부터의 동시상속)을 금지하고 있다. 이 덕분에 명확한 상속관계가 유지되지만 필요에 따라 다중 상속이 필요할 때도 있다.이런 경우를 위해서 인터페이스라는 개념이 도입되었다. 즉, 인터페이스는 다중상속을 허용해 준다.
나중에 살펴볼 이벤트에서 인터페이스를 사용하므로 반드시 개념을 이해한다.

1. 객체모델링을 통한 클래스 구성

만약 tv, 오디오, 카메라를 클래스로 작성한다고 하자. 이 세가지에는 리모컨이라는 기능이 공통적으로 가지고 있으나 서로의 기능은 다르다. 따라서 상속을 한다면 다중상속이 되지 않기 때문에 각기 따로 클래스를 작성해서 상속을 해야한다. 그러면 코딩도 많아지고 불편할 것이다. 

2. 인터페이스를 통한 클래스 구성

다중상속이 허용되는 인터페이스를 사용하는 경우 리모컨 인터페이스를 선언해서 각 클래스에서 구현해서(인터페이스를 사용하는 것은 상속이라 하지 않고 '구현'이라 한다.) 각각의 클래스에 맞게 새롭게 내용만을 정의해 주면 된다. 이는 특히 공동작업을 하는 프로그램에서 통일된 코드를 작성할 수 있다.

2> 인터페이스 특징

  1. 클래스와 메서드 선언만 하고 내용은 없다.
  2. 인터페이스 사용시 반드시 하위 클래스는 인터페이스를 오버라이딩 해야한다.
  3. 인터페이스는 자동적으로 다음과 같이 된다.
    멤버 변수 : public final static
    메서드 : public abstract
  4. 구현을 위해 implements 키워드 사용.
    예> class 클래스명 implements 인터페이스1, 인터페이스2, 인터페이스3...{....}
  5. 다중 상속이 가능 . ,(콤마)를 구분으로 여러개 의 인터페이스를 상속가능.
  6. 인터페이스 끼리 상속 가능. 이때는 extends 키워드 사용.



 



 

'I.lib() > I.lib(Java)' 카테고리의 다른 글

JNDI 란?  (1) 2010.04.08
자바 리플랙션 (Java Reflection)  (1) 2010.03.29
Javap 란? (자바 역어셈블러)  (1) 2010.03.24
POJO (Plain Old Java Object) 란?  (0) 2010.03.23
클레스 어샘블리. (Class -> Java )변환  (1) 2010.03.05
.
:
Posted by .07274.
2010. 3. 24. 10:00

Javap 란? (자바 역어셈블러) I.lib()/I.lib(Java)2010. 3. 24. 10:00

.. .. ..

java를 설치하면, bin 디렉토리 내에 다양한 실행파일들이 설치가 됩니다.

 하지만, 일반적으로 사용하는 것은 javac와 java가 대부분이죠..

 bin 디렉토리 내부를 잘 보면, javap 라는 실행파일도 있습니다.

 이글의 주제는 바로 이 javap 에 대한 얘기가 되겠습니다.

 javap는 간단하게 설명하면, 클래스 파일의 역어셈블하는 실행파일입니다.

 여기서 역어셈블이라는 것이 중요한데요, 역컴파일과는 사뭇 다릅니다.

 역컴파일은 클래스 파일을 가지고 원래 소스로 변환하는 것을 말하지만, 역어셈블은 클래스 파일의 내부의 기본 구조와 역어셈블코드(JVM의 바이너리 코드)만을 나오게 됩니다.

 특정 클래스의 내부 전체를 보고 싶은 경우는 역컴파일러를 이용하셔야 하고, 클래스 내부의 상수/함수들의 목록을 간단히 보고자 할때는 javap를 이용하는 것이 대부분입니다.

 이를 통해서 symbol not found 같은 에러를 찾는데 도움이 됩니다.

 

* 실행예

Integer 클래스의 javap 결과를 보겠습니다.

 public final class java.lang.Integer extends java.lang.Number implements java.lang.Comparable{
    public static final int MIN_VALUE;
    public static final int MAX_VALUE;
    public static final java.lang.Class TYPE;
    static final char[] digits;
    static final char[] DigitTens;
    static final char[] DigitOnes;
    public static java.lang.String toString(int,int);
    public static java.lang.String toHexString(int);
    public static java.lang.String toOctalString(int);
    public static java.lang.String toBinaryString(int);
    public static java.lang.String toString(int);
    static void appendTo(int,java.lang.StringBuffer);
    public static int parseInt(java.lang.String,int);
       throws java/lang/NumberFormatException
    public static int parseInt(java.lang.String);
       throws java/lang/NumberFormatException
    public static java.lang.Integer valueOf(java.lang.String,int);
       throws java/lang/NumberFormatException
    public static java.lang.Integer valueOf(java.lang.String);
       throws java/lang/NumberFormatException
    public java.lang.Integer(int);
    public java.lang.Integer(java.lang.String);
       throws java/lang/NumberFormatException
    public byte byteValue();
    public short shortValue();
    public int intValue();
    public long longValue();
    public float floatValue();
    public double doubleValue();
    public java.lang.String toString();
    public int hashCode();
    public boolean equals(java.lang.Object);
    public static java.lang.Integer getInteger(java.lang.String);
    public static java.lang.Integer getInteger(java.lang.String,int);
    public static java.lang.Integer getInteger(java.lang.String,java.lang.Integer);
    public static java.lang.Integer decode(java.lang.String);
       throws java/lang/NumberFormatException
    public int compareTo(java.lang.Integer);
    public int compareTo(java.lang.Object);
    static {};

[출처] javap의유용성|작성자 하자두


'I.lib() > I.lib(Java)' 카테고리의 다른 글

JNDI 란?  (1) 2010.04.08
자바 리플랙션 (Java Reflection)  (1) 2010.03.29
자바의 abstract와 인터페이스(Interface)  (0) 2010.03.24
POJO (Plain Old Java Object) 란?  (0) 2010.03.23
클레스 어샘블리. (Class -> Java )변환  (1) 2010.03.05
.
:
Posted by .07274.
2010. 3. 23. 20:29

POJO (Plain Old Java Object) 란? I.lib()/I.lib(Java)2010. 3. 23. 20:29

.. .. ..

POJO (Plain Old java Object) 를 해석하면 평범 자바 오브젝트라고 한다.
POJO를 이해 하기 전  POJO라는 단어가 만들어진 역사적 배경을 살펴볼 필요가 잇다. POJO는 마틴 파울러가  2000년 가을에 열렸던 어느 컨퍼런스의 발표를 준비하면서 처음 만들어낸 말이다. 마틴 파울러는EJB(Enterprise JavaBean)보다는 단순한 자바 오브젝트에 도메인 로직을 넣어 사용하는 것이 여러가지 장점이있는데도 왜 사람들이 그 EJB가 아닌 '평범한자바 오브젝트'를 사용하기를 꺼려 하는지에 대해 의문을 가졌다. 그리고 그는 단순한 오브젝트에는 EJB와 같은 그럴듯한 이름이 없어어서 그 사용을 주저하는 것이라고 결론 내렸다.
  그래서 만든 단어가 POJO라는 용어인 것이다. POJO기반의 기술을 사용한다고 말하면 왠지 첨단 기술을 사용하는 앞선 개발자인 듯한 인상을 주기 때문인다.

POJO기반의 프로그래밍 기술이 EJB의 강력한 대안으로 등장했고 ,POJO 기반 프레임워크 ,POJO 애플리케이션을 위한 플랫폼 등이점점 인기를 끌게 되었고, 결국 POJO가 배제하려고 했던 EJB는 POJO기반의 기술에 밀려 이제 레거시 기술로 사라질 위기에처했다. 그렇다면 단지 EJB를 사용하지 않으면 모두 POJO라고 할 수 있을까? 그렇지 않다. POJO프로그래밍이라는 개념은단지 "EJB가 아닌 자바"이상의 특징을 가지고 있는 프로그래밍 모델이다. POJO기반의 개발은 생각보다 단순하지 않다.
  POJO를 좀더 이해하려면 EJB의 장단점을 함께 이해해야 한다. 그것은 POJO 프로그래밍이 다시 EJB시대이전으로 돌아 가자는 것이 아니고 ,EJB를 넘어 그보다 더 앞으로 나아가자는 것이기 때문이다.
EJB를 사용하지 말고 POJO를 쓰자는 것은  EJB이전의 방식으로 돌아 가는 것을 의미한다면 또 다른 문제가 발생 할 수 밖에없다. 여전히 복잡한 로우레벨의 API를 이용해 코드를 작성해야 하고, 많은 기술적인 문제를 애플리케이션 코드에 그대로 노출시켜개발해야 한다면 기껏 POJO로의 복귀 덕분에 얻는 많은 장점들을 놓칠 수 밖에 없다.

  그래서 등장한 것이 POJO 기반의 프레임워크이다. POJO프레임워크는 POJO를 이용한 애플리케이션 개발이 가진 특징과 장점을 그대로 살리면서 EJB에서 제공하는 엔터프라이즈 서비스와 기술을 그대로 사용할 수 있도록 도와주느 프레임워크이다. 나아가 이는 기존의 EJB에서보다 훨씬 더 세련되고 나은 방법이다. 데표적인 프레임웤 스프링 하이버네이트~!

참고로 스프링은 엔터프라이즈 서비스들을 POJO기반으로 만든 비지니스 오브젝트에서 사용할 수 있게 한다. 대표적인 선언적인트랜잭션 서비스와 보안이다. 또한 EJB와 마찬가지로 오브젝트 컨테이너를 제공해서 인스턴스의 라이프사이클을 과리하고 필요에 따르스레딩, 풀링 및 서비스 인젝션 등의 기능을 제공한다. 또한 OOP를 더  OOP답게 사용 할 수있게 하는 AOP기술을 적용해서POJO개발을 더 쉽게 만든다.

POJO프로그램의 진정한 가치는 자바의 객체지향적인 특징을 살려 비지니스 로직에 충실한 개발이 가능 하도록 하는것이기도 하다.

------------------------------------------------------------------------------------------

내생각을 적자면
평범한 자바 객체로 프로그래밍 하기라고 부르며, 침략적인 코드를 적지 않은 것이다.
쉽게 말해 implement 와 extends를 사용 하지 않으며
콤포지션과 인터페이스타입으로 프로그래밍 하는것(이건 레디 존슨)

특정 클래스의 concrete class가 되면 안되고, 구현 체도 되면 안된다.


[출처] POJO (Plain Old java Object)란?|작성자 네모

'I.lib() > I.lib(Java)' 카테고리의 다른 글

JNDI 란?  (1) 2010.04.08
자바 리플랙션 (Java Reflection)  (1) 2010.03.29
자바의 abstract와 인터페이스(Interface)  (0) 2010.03.24
Javap 란? (자바 역어셈블러)  (1) 2010.03.24
클레스 어샘블리. (Class -> Java )변환  (1) 2010.03.05
.
:
Posted by .07274.
.. .. ..
클래스 파일을 자바파일로 역컴파일 해주는 프로그램


'I.lib() > I.lib(Java)' 카테고리의 다른 글

JNDI 란?  (1) 2010.04.08
자바 리플랙션 (Java Reflection)  (1) 2010.03.29
자바의 abstract와 인터페이스(Interface)  (0) 2010.03.24
Javap 란? (자바 역어셈블러)  (1) 2010.03.24
POJO (Plain Old Java Object) 란?  (0) 2010.03.23
.
:
Posted by .07274.