SJC-WC合格対策サイト
TOPページ > 標準アクションを使用したJSPの構築 > <jsp:useBean>のclassとtypeの違い

Sun認定資格のSJC-WCの合格対策を目的としているサイトです。


<jsp:useBean>のclassとtypeの違い

<jsp:useBean>のclasstypeは、機能が似ています。
この2つの違いについては、SJC-WCの試験でもよく出題される部分です。

<jsp:useBean>で考えられるパターンごとに説明していきます。

classのみ指定

サンプルコード(hoge.jsp)

<jsp:useBean id="hoge" class="test.TestBean" />

サンプルコード(hoge.jsp - コンパイル済み)

test.TestBean hoge = null;
synchronized (_jspx_page_context) {
  hoge = (test.TestBean) _jspx_page_context.getAttribute("hoge", 
                                                  PageContext.PAGE_SCOPE);
  if (hoge == null){
    hoge = new test.TestBean();
    _jspx_page_context.setAttribute("hoge", hoge, PageContext.PAGE_SCOPE);
  }
}

最初にpageContextから"hoge"を持つ属性を取得しようとします。
早い話は、既存の同名のインスタンスを探しだそうとします。

そして、classの場合はインスタンスが取得できなかった場合、新たにインスタンスを作成します。

typeのみ指定

サンプルコード(hoge.jsp)

<jsp:useBean id="hoge" type="test.TestBean" />

サンプルコード(hoge.jsp - コンパイル済み)

test.TestBean hoge = null;
synchronized (_jspx_page_context) {
  hoge = (test.TestBean) _jspx_page_context.getAttribute("hoge", 
                                                  PageContext.PAGE_SCOPE);
  if (hoge == null){
    throw new java.lang.InstantiationException("bean hoge not found 
                                                           within scope");
  }
}

class同様、最初にpageContextから"hoge"を持つ属性を取得しようとします。
しかし、lassの場合はインスタンスが取得できなかった場合、新たにインスタンスを作成しません。
例外を投げて終了します。

classとtypeを両方指定

サンプルコード(hoge.jsp)

<jsp:useBean id="hoge" type="test.TestBeanInterface" 
                                    class="test.TestBean" />

サンプルコード(hoge.jsp - コンパイル済み)

test.TestBeanInterface hoge = null;
synchronized (_jspx_page_context) {
  hoge = (test.TestBeanInterface) _jspx_page_context.getAttribute("hoge", 
                                                  PageContext.PAGE_SCOPE);
  if (hoge == null){
    hoge = new test.TestBean();
    _jspx_page_context.setAttribute("hoge", hoge, PageContext.PAGE_SCOPE);
  }
}

(TestBeanはTestBeanInterfaceを実装していると仮定してください)

typeでは抽象クラスやインターフェースも指定できます。
classで抽象クラスやインターフェースを指定することはできません。

typeのみ指定した場合、新たにインスタンスを作成してしまうと抽象クラスやインターフェースも作成しようとします。
抽象クラスやインターフェースはインスタンス化できないので、コンパイルエラーになります。
そのため、typeでは新たにインスタンスを作成しようとしません。

beanNameの使用

サンプルコード(hoge.jsp)

<jsp:useBean id="hoge" type="test.TestBean"
                            beanName="test.TestBean" />

サンプルコード(hoge.jsp - コンパイル済み)

test.TestBeanInterface hoge = null;
synchronized (_jspx_page_context) {
  hoge = (test.TestBean) _jspx_page_context.getAttribute("hoge", 
                                                PageContext.PAGE_SCOPE);
  if (hoge == null){
    try {
      hoge = (test.TestBean) java.beans.Beans.instantiate(
                                       this.getClass().getClassLoader(),
                                                       "test.TestBean");
    } catch (ClassNotFoundException exc) {
      throw new InstantiationException(exc.getMessage());
    } catch (Exception exc) {
      throw new ServletException("Cannot create bean of class " + 
                                                   "test.TestBean", exc);
    }
    _jspx_page_context.setAttribute("hoge", hoge, PageContext.PAGE_SCOPE);
  }
}

まず、beanNameを使用する場合はtypeが必須になります。
この2つの属性を併用することで、スコープ内にインスタンスがない場合は新たにインスタンスを作成するようになります。

ですが、インスタンスの生成方法がclassのときとは異なります。
コンパイル済みのコードを見ると、java.beans.Beans.instantiate()メソッドでインスタンスを作成します。
このメソッドに関する説明は省略します(SJC-WCの試験範囲ではないため)。
試験対策 書籍
inserted by FC2 system