• ベストアンサー

基本的な構文について

いつも参考にさせて頂いています。 基本的なことなのですが、宜しくお願いします。 以下のBeanクラスがあるとします。 -------bean class public class Bean { private String str; public String getStr() { return str; } public String setStr(String str) { this.str = str; } } --------------- プロパティstrを取得してあるメソッドに引数として渡す場合、1と2ではどちらが適切でしょうか? 1. public class Test { Bean bean = new Bean(); String testStr = bean.getStr();   methodAAA( testStr ); } 2. public class Test { Bean bean = new Bean(); methodAAA( bean.getStr() ); } 1のほうが新しいオブジェクトを作成してしまうのでコストがかかってしまう気がするのですがいかがでしょうか。 methodAAA( bean.getStr(). … )と長くなる場合は一度違うオブジェクトに格納したほうがいいとか… 双方ともにメリットデメリットあるとは思いますが、噛み砕いて説明して頂けると助かります。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

#1です。 だんだん混乱してきたので、以下に補足します。 String型のオブジェクトを生成するには2つの方法があります。 (1) String str = new String(""); (2) String str = ""; オブジェクトとは新しく生成する場合newしますが、Stringには(2)の ような生成も可能です。そんなことは既にご存知だと思いますが。。。 ここが実に大事なことです。(1)と(2)はどちらもStringを生成しますが バッググランドで動作する生成方法は全く異なるのです!!! 通常のオブジェクトで使用される(1)の方法では常に新しくオブジェクトが生成されます。要するに、 ------------------------------------------------- String strA = new String("dog"); String strB = new String("dog"); String strC = new String("cat"); ------------------------------------------------- この場合、同じ内容(dog)のstrAとstrBは物理的に違うオブジェクト をそれぞれ生成してしまい、結果的に”3つ”のオブジェクトがメモリ上に展開されます。 一方、String特有の(2)の方法では内容が同じものは物理的に同じメモリを参照し、違うオブジェクトとして扱われます。要するに、 ------------------------------------------------- String strX = "dog"; String strY = "dog"; String strZ = "cat"; ------------------------------------------------- この場合、同じ内容(dog)のstrXとstrYは物理的に同じメモリを参照するので、結果的に”2つ”のオブジェクトがメモリ上に展開されます。 ★ただし、ここで気をつけなくてはいけないのが!! 『あくまでメモリ上の参照する場所が同じだけで、扱いは違うオブジェクトだ』ということです。 つまり、(1)と(2)は使用方法や動作は同じです。違うのはメモリ上に展開する”バックグランド処理”だけなのです。 何か特別な理由がない限りは、コスト削減を行うためにStringを使用する際は(2)をお勧めします。(個人的には。) ってなんだか長くなってしまった割には、言いたいことの40%くらいしか伝えられていないような気がしますが。。。。。

pgBeginImo
質問者

お礼

詳しい説明ありがとうございます。 なんとなく仕組みが理解できました。 また何かあれば宜しくお願いします。 本当にありがとうございました!!

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • i2719
  • ベストアンサー率35% (11/31)
回答No.4

私の場合は、参照を1回しか使わないとわかっていれば、ローカル変数に 格納することはしません。(変数名を考えるのが無駄) 1.と2.でオブジェクトは全く同じで、コストの差もメソッドを一回呼ぶ より小さく、気にしなくていいです。

pgBeginImo
質問者

お礼

返事ありがとうございます。 気にしなくていいってことでなんだか楽になれました・ 的確なアドバイスありがとうございます。 確かに変数名を考えるのが「コスト」と言えるかもしれません。

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

#1です。 >test1とtest2はそれを参照するだけってことでしょうか? 少しわからなかったので確認です。 getB()、getC()はB、Cのオブジェクトそのものを返すアクセサでしょうか?そうだとすると、test1とBは同じオブジェクトとなります(test2とCも同様です)。しかし、BとCは同じオブジェクトではありません(何度も言うようですが。。。)。つまり、test1とtest2も同じオブジェクトではありません!

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

あまり私も詳しいわけではありませんが。 Stringは他のオブジェクトとは違う特色(性質といいますか)があり、 『同じ内容のStringは使いまわされる』のです! 例えば、以下のようにプログラムしたとします。 ------------------------------------------------------------ String A = "aaa"; String B = "bbb"; String C = "bbb"; ------------------------------------------------------------ 上記Stringが物理的に生成される数は2つです。 BとCは物理的には同じStringを参照することになるのです。 ただし、同じオブジェクトというわけではありませんのでご注意を! つまり、pgBeginImoさんの1と2は”同じ”コストだと思います。 また、Beanの中で宣言されているオブジェクトがStringでなければ 2の方がコストが少ないと言えると思います。

pgBeginImo
質問者

お礼

早速の返事ありがとうございます。 >BとCは物理的には同じStringを参照することになるのです。 それは知りませんでした。ちょっとびっくりです。 >物理的に生成される数は2つです 例えば、kuruthiusuさんが提示してくれたソース上で言うと、BとCの取得メソッド "getB()" と "getC()"があった場合、 String test1 = getB(); String test2 = getC(); 上記ソースでBとCを呼び出してもtest1とtest2の2つのオブジェクトの参照がメモリのヒープ上に割り当てられるわけではなく、結局String BBB = "bbb"; とオブジェクトを作成した時点で割り当てられているのでtest1とtest2はそれを参照するだけってことでしょうか?

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • JAVAの継承について

    JavaでクラスA,B,Cがあり、A,BはクラスCを継承しています。 この時にAのインスタンスを生成しCにある変数に値を設定します。 この設定した情報をBのインスタンスに一気に設定することは可能でしょうか? やりたいこととしてはAに設定した情報をBにコピーするようなイメージです。 すべてのsetterを呼びだして設定するのが面倒なので。 例)構文的に間違ってるかもしれませんがやりたいことは以下のような感じです。 A a = new A(); a.setStr("aaa"); a.setInt(5); B b = new B(); b.setStr(a.getStr()); b.setInt(a.getInt(); class A extends C{} class B extends C{} class C {  int x = 0;  String str = "";  private String setStr(String str){this.str=str;}  private String setInt(int i){this.x=i;}  private String getInt(){return this.x;}  private String getStr(){return this.str;} }

    • ベストアンサー
    • Java
  • フォームBeanのメソッド内で変数の呼び出しでエラーとなる

    初歩的な質問かと思いますが、下記について教えてください。 以下のようなソースがあり、フォームBeanのvalidateメソッドのところで 検証を行うプログラムを書きたいと思っています。 しかし、(1)のところで、InputForm クラスの外で定義している変数を扱う ことができず、以下のエラーが発生します。 エラー: No variable or field with this name could be found at this location. どのようにすれば、フォームBeanの中でtest1などの値を呼び出すことができますか? なぜ、呼び出すことができないのでしょうか? よろしくお願いいたします。 ================================== public class controller extends PageFlowController { String test1 ="aaa"; ・・・ /** * @jpf:action * @jpf:forward name="success" path="index.jsp" */ protected Forward form() {   //ここでtest1は呼び出せる。 string test2= test1; ・・・ } ・・・ public static class InputForm extends FormData { private String str1; ・・・ public void setStr1(String str1) { this.str1 = str1; } public String getStr1() { return this.str1; } ・・・ public ActionErrors validate(ActionMapping arg0, HttpServletRequest arg1) { ・・・     //ここでtest1を呼び出すことができない。 String tmp = test1; ・・・ }   } }

    • ベストアンサー
    • Java
  • メソッドの中に、作ったメソッドを呼び込みたいんですが

    メソッドの中に、作ったメソッドを呼び込みたいんですが シグネチャを int argCheck(String args[]) に指定して、 引数のチェック処理メソッドというものを作成してるんですが、 よくわからないんです。 内容は (1) 引数の数が1個でない場合、1を返却 (2) 引数が『aaa』でも『ZZZ』でもない場合、99を返却 (3) 以外は、0を返却 public class Test { public static void main(String args[]) { Test test = new Test(); int result = test.argCheck(args); test.argCheck(); //メソッドを呼び込み } private int argCheck(String args[]) { if(args[0].length != 1) // 引数の数が1以外の場合 { return 1; // 1を返す } else if (!args[0].equalsIgnoreCase("aaa") && !args[0].equalsIgnoreCase("ZZZ")) //引数が aaa でも ZZZ でもない場合(大/小文字区別せず) { return 99; // 99を返す } else // それ以外の場合 { return 0; // 0を返す } } }

    • ベストアンサー
    • Java
  • 文字の表示

    オブジェクトを受け取るメソッド ↓は引数にString型のオブジェクトを指定するプログラムです public class Sample { public static void main(String args[]) { String str = "abcd"; change(str); System.out.println(str); } private static void change(String str) { str = "efgh"; } } 私の中ではefghがでると思っていたんですが・・ これを実行してみると変数strに最初に代入した文字列が表示されるんです! なぜですか? できれば理由を教えてください 回答よろしくお願いします

  • StrutsでJSPからListを受け取りたい

    JSPに複数のhidden(動的に数が変化)があり、これらの値をformのlist(配列)に詰めたいです。 尚、nameの値は別の処理でjavascriptを使いvalueを変化させるため連番であれば構わないです。です。 ~~~JSP~~~ <input type="hidden" name="str1" value="a"/> <input type="hidden" name="str2" value="b"/> <input type="hidden" name="str3" value="c"/> ~~~~~~~~ 上のJSPから下記のFORMに詰めたい ~~~form~~~ private List strList; public List getStrList(){ return strList; } ~~~~~~~~ 又、こちらで調べたところ下記のようにすればいけるようですが欲しい値は一つのためBeanを使用しなくても実現可能ではないかと思い、質問させていただきました。 よろしくお願い致します。 ~~~JSP~~~ <input type="hidden" name="testArray[0].str" value="a"/> <input type="hidden" name="testArray[1].str" value="b"/> <input type="hidden" name="testArray[2].str" value="c"/> ~~~~~~~ ~~~FORM~~~ private List list; public TestBean getTestA(int iIndex) { while (this.list.size() <= iIndex) { this.list.add(new TestBean ()); } return ( TestBean ) this.list.get(iIndex); } public Object[] getTestArray() { return list.toArray(); } public static class TestBean { private String str = ""; public String getStr() { return str; } public void setStr(String str) { this.str = str; } }

    • ベストアンサー
    • Java
  • パラメータのやりとり

    3つのクラスの中でHTML上から取得したパラメータをやり取りしたいと思っています。 1つ目のクラス(CLASS_1.java) public class CLASS_1 extends CLASS_0 { public void doMain(HttpServletRequest request,HttpServletResponse response){ try{ String[] str = makeItem(request); CLASS_2 class_2 = new CLASS_2(); class_2.setItem(str); private String[] makeItem(HttpServletRequest request){ String[] result = new String[3]; result[0] = request.getParameter("test1"); result[1] = request.getParameter("test2"); result[2] = request.getParameter("test3"); return result; 2つ目のクラス(CLASS_3.Java) public class CLASS_3{ public void setItem(String[] data){ } public boolean makeTEXT(){ return true; } public ByteArrayOutputStream getTEXT(){ return null; } } 3つ目のクラス(CLASS_2) public class CLASS_2 extends CLASS_3 { public boolean makeTEXT(){ return true; } } という3つのクラスを作成しました。 CLASS_1で取得したstrの中の値をCLASS_2で使用したいと考えています。 ただ羅列するだけでかまいませんので、わかるかたヒントや参考になりそうなHPなどありましたら よろしくお願いします。

  • 引数の違うメソッド

    PHPで同名で引数の違うメソッドを作成したいのですが、可能でしょうか? <?php class Test { var $test_str = ""; function set($str){ $test_str = $str; //$this->$test_str = $str; // どちらでも良い? } function Test() { // 引数なし } function Test($str) { // 引数あり $this->set($str); } } $obj = new Test(); ?>

    • ベストアンサー
    • PHP
  • インターフェイス実装クラスの表示について

    /* インタフェースPlanetを実装したクラスEarth、Marsがあります。  以下の実行結果になるようにクラスAggregateへshowメソッドを  追加してください。 [実行結果] 地球 太陽系にある惑星の1つで、太陽から3番目に近い。・・・ 火星 太陽系の太陽に近い方から4番目の惑星である。・・・ */ // [Planet.java] // 実装したいPlanetクラス interface Planet {   public String getName();   public String getOutline(); } // Planetを実装したEarthクラス // [Earth.java] class Earth implements Planet {   private final String name="地球";   // getNameメソッド:戻り値String、引数無し   public String getName(){    return name;   }   // getOutlineメソッド:戻り値String、引数無し    public String getOutline(){      return "太陽系にある惑星の1つで、太陽から3番目に近い。・・・";    } } // Planetを実装したMarsクラス // [Mars.java] class Mars implements Planet {   private final String name="火星";   // getNameメソッド:戻り値String、引数無し   public String getName(){     return name;   }   // getOutlineメソッド:戻り値String、引数無し   public String getOutline(){     return "太陽系の太陽に近い方から4番目の惑星である。・・・";   } } // メインクラス // [Main.java] class Main{   public static void main(String[] args){   // Earth&Marsクラスのインスタンス化    Earth earth = new Earth();     Mars mars = new Mars();   // Aggregateクラスのインスタンス化   Aggregate aggregation = new Aggregate();   // showメソッド呼び出し:戻り値無し、引数earth・mars    aggregation.show(earth);    aggregation.show(mars); } } // [Aggregate.java] class Aggregate { // ここにshowメソッドを追加   public void show(Earth planet){     System.out.println();   }   public void show(Mars planet){     System.out.println();   }  } showメソッドに引数としてEarth planet,Mars planetを渡すというところまでは理解しています。後は星の名前と概要を表示するのですが、例えば、 showメソッド内 // ここにshowメソッドを追加 public void show(Earth planet){ String str = earth.getName(); System.out.println(str); } public void show(Mars planet){ String str2 = mars.getOutline(); System.out.println(str2); } } とすると、erathとmarsの部分が「シンボルがありません」のエラーになります。自分の認識としては、EarthクラスとMarsクラスでフィールド変数を宣言しているので使えるのでは?と思っていたのですが、全然違うようです。どなたかどちらかのコード例を表記して頂けないでしょうか?よろしくお願い致します。

    • ベストアンサー
    • Java
  • カスタムタグで日本語の文字化けを解決できない

    カスタムタグでパラメータから取得した日本語の文字化けを解決できません。 実行しているのは以下のソースです。 test.java package test; public class test extends javax.servlet.jsp.tagext.TagSupport{ private static final long serialVersionUID=1L; private String testStr; public void setTestStr(String testStr){ this.testStr=testStr; } //タグの開始時に実行されるメソッド public int doStartTag() throws javax.servlet.jsp.JspException{ try{ response.setContentType("text/html;charset=UTF-8"); pageContext.getOut().write(new String(this.testStr.getBytes("8859_1"),"JISAutoDetect")); }catch(java.io.IOException e){ throw new javax.servlet.jsp.JspException(e.getMessage()); } return SKIP_BODY; } } test.jsp <%@ page contentType="text/html;charset=UTF-8"%> <%@ taglib uri="custom" prefix="custom"%> <html> <head><title>test</title></head> <body> <custom:test testStr="${param.test}" /> </body> </html> どのようにすれば解決できるでしょうか。

    • ベストアンサー
    • Java
  • Javaの構文について

    よろしくお願いします。 以下のようなJavaのプログラムがあるのですが、 Object str = new Object[]{"test"}; 右辺のnew Object[]{"test"}は、何をやっているのでしょうか? どなたかご教授願います。

    • ベストアンサー
    • Java
彼氏いない高校生が嘘をついた
このQ&Aのポイント
  • 彼氏いない高校生が、インスタで知り合った男友達に彼氏がいるか聞かれて嘘をついてしまった。
  • 高校生で周りはカップルが多い中、今まで付き合ったことがなく恥ずかしい思いをしている。
  • 告白された経験もあり、過去の好きな子についてもまだ思いがある可能性があるが、どう返すべきか悩んでいる。
回答を見る

専門家に質問してみよう