- - PR -
req.getParameters("パラメーター名")で取得した値の操作に関して
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-08-27 10:36
お世話になります(なりっぱなしです)
遊説家@奈良です。Tomcat5.0+J2EE1.3.1環境でサーブレットを作成しています。 皆様のお知恵をお借しください。 サーブレットでのパラメーター取得後のデータ操作なのですが、下記ソース中、 コメントA、B部分で同じパラメーターを別の変数に格納しているつもりです。(wk1,wk2) サーブレットキックのHTMLソースはこれでやってみました ============================================================================ http://(サーバ名):8080/(サーブレット名)/servlet/svl001?_hoge="[7]123456" ============================================================================ その際、取得した値の1つを操作(下記例では、]文字以降を抽出) するともう一方の 値にも影響が出てしまいます。期待している動作は wk11は 123456 で wk12 は[7]123456 なのですが、いっしょになってしまいます。 まるで、wk1,wk2が同じポインターで操作されているような..... 何か根本的に間違っているのでしょうか? 皆様、お知恵を、何卒!お知恵を.... /* * svl001.java * Created on 2004/08/26 */ import java.io.PrintWriter; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; // public class svl001 extends HttpServlet { // protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { this.doPost(req, res); } // public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { // res.setContentType("text/html; charset=Shift_JIS"); PrintWriter writer = res.getWriter(); // writer.println("<html>"); // ヘッダー部 writer.println("<head>"); writer.println("<meta http-equiv=\\"Content-Type\\" content=\\"text/html; charset=iso-2022-jp\\">"); writer.println("<title>"); writer.println("Servlet Sample2"); writer.println("</title>"); writer.println("</head>"); // ボディー部 writer.println("<body><h1>"); writer.println("<center>"); // String[] wk1 = null; String[] wk2 = null; // A wk1 = req.getParameterValues("_hoge"); // B wk2 = req.getParameterValues("_hoge"); // // wk1だけ、']'よりあとの文字を抽出しているつもり // この時点で、wk1,wk2 は内容が異なるはず。 wk1[0] = wk1[0].substring(wk1[0].lastIndexOf(']') + 1); // // 念のため、shift-jis に再変換 String wk11 = new String(wk1[0].getBytes("8859_1"), "Shift_JIS"); String wk12 = new String(wk2[0].getBytes("8859_1"), "Shift_JIS"); System.out.println("wk11>" + wk11); System.out.println("wk12>" + wk12); // // wk11,wk12 は異なるはずなのにいっしょになってしまう.... writer.println("1度目の日本語[" + wk11 + "]"); writer.println("2度目の日本語[" + wk12 + "]"); writer.println("</center>"); writer.println("</h1></body>"); writer.println("<html>"); // } } | ||||||||
|
投稿日時: 2004-08-27 11:47
---------------------------------------------------------
--------------------------------------------------------- この時点でwk1とwk2は同じString配列を指していますよね。 ---------------------------------------------------------
--------------------------------------------------------- ここでwk1が指している配列の箱の0番目が参照している先を変えていますよね。 wk1とwk2は同じ配列を指しているんだから、wk2の0番目の参照先も変えたってことじゃないですか? | ||||||||
|
投稿日時: 2004-08-27 12:25
夏椰さんどうもありがとうございます
教えていただきたいのですが、ご指摘の内容は public class test2 { public static void main(String[] args) { // String[] wk1 = new String[1]; String[] wk2 = new String[1]; // wk1[0] = "12345"; wk2[0] = wk1[0]; // wk1[0] = wk1[0].substring(2); System.out.println( wk1[0]); System.out.println( wk2[0]); } } で、結果が 345 12345 となることとは関係ないのでしょうか? wk2[0] = wk1[0]; で、先の例の wk1 = req.getParameters("hoge"); wk2 = req.getParameters("hoge"); と同じなのでは?って思ってしまいましたが、なんか私の大歩危があるのでしょうね | ||||||||
|
投稿日時: 2004-08-27 12:33
説明不足でしたね。すみません。
2つ目のソースでは String[] wk1 = new String[1]; String[] wk2 = new String[1]; と記述されていてwk1とwk2は別々の配列を見ています。 1つ目のソースでは wk1 = req.getParameterValues("_hoge"); wk2 = req.getParameterValues("_hoge"); と記述されていてwk1とwk2は同じ配列を見ています。 だから動作に違いがでているんですよ。 | ||||||||
|
投稿日時: 2004-08-27 12:42
この時点で、wk1とwk2は同じString配列オブジェクトへの参照を持っています。これはおそらく、getParameterValuesメソッドが内部に持っている配列の参照を渡すからだと思います。(JavaDocにはそういうことは書いてなかった) なお、下記のコードで、wk1とwk2が同じ参照をもっていて、さらにwk1の中身を変えるとreq.getParameterValues("_hoge"); が返す値が変わることが分かります。
なお、 String[] wk1 = new String[1]; String[] wk2 = new String[1]; とすると、wk1とwk2にそれぞれ別の配列オブジェクトを生成するため wk1!=wk2 となります。つまり、wk1を変えても、wk2は変わりません。 [ メッセージ編集済み 編集者: H2 編集日時 2004-08-27 12:46 ] | ||||||||
|
投稿日時: 2004-08-27 13:05
Javaを使う上で知っておいてもらいたいのは、
「基本的にJavaはオブジェクト参照だ」ということです。 intやbooleanのようなプリミティブ型、それからString、その他にもあるかもしれませんが、これら以外のオブジェクトはオブジェクト参照です。 (Stringについては、特別です。) ですので、Stringの配列はオブジェクト参照で、値を変えることによってもう一方に影響します。 しかし、単にStringの値を変更した場合は、オブジェクト参照ではありませんので、他方には影響ありません。 # String[]とStringでは、値の参照の仕方が違います。 説明で間違っていたらご指摘ください。 [ メッセージ編集済み 編集者: ちょま吉 編集日時 2004-08-27 13:07 ] | ||||||||
|
投稿日時: 2004-08-27 13:51
どうも MINEです。
プリミティブ以外はオブジェクトへの参照ですよね Stringはデータの変更が許されていないから 一方を変更することで他方も変わってしまうという ことは起こりませんけど | ||||||||
|
投稿日時: 2004-08-27 14:09
H2殿、ちょま吉殿、夏椰殿ありがとうございました
>ちょま吉殿 ================================================= # String[]とStringでは、値の参照の仕方が違います ================================================= 自分なりに、値渡しか、ポインタ渡しの違いと理解するようにします。 違います? ともかく、ありがとうございました、です。 >H2殿 ============================================================================= getParameterValuesメソッドが内部に持っている配列の参照を渡すからだと思います ============================================================================= ポインタがwk1,wk2で共通になっているとの予想はあったのですが、なんか仕様上 へんな感じがしますね。 ありがとうございました。 配列の参照を渡されては困るので、結局、getParameters("_hoge") で String で受け取った値の操作をするようにしました。 このソースではないのですが本番のものも問題が解決しました。 /* * svl001.java * Created on 2001/06/28, 14:03 */ import java.io.PrintWriter; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; // public class svl001 extends HttpServlet { // protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { this.doPost(req, res); } // public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { // res.setContentType("text/html; charset=Shift_JIS"); PrintWriter writer = res.getWriter(); // writer.println("<html>"); // ヘッダー部 writer.println("<head>"); writer.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-2022-jp\">"); writer.println("<title>"); writer.println("Servlet Sample2"); writer.println("</title>"); writer.println("</head>"); // ボディー部 writer.println("<body><h1>"); writer.println("<center>"); // // String[]を止めて、String にしました String wk1 = null; String wk2 = null; // Sgtringを返却する getParameter("_hoge")にしました wk1 = req.getParameter("_hoge"); wk2 = req.getParameter("_hoge"); // // wk1だけ、']'よりあとの文字を抽出しているつもり // この時点で、wk1,wk2 は内容が異なるはず。 // → 異なるようになりました wk1 = wk1.substring(wk1.lastIndexOf(']') + 1); // // 念のため、shift-jis に再変換 String wk11 = new String(wk1.getBytes("8859_1"), "Shift_JIS"); String wk12 = new String(wk2.getBytes("8859_1"), "Shift_JIS"); System.out.println("wk11>" + wk11); System.out.println("wk12>" + wk12); // // wk11,wk12 は異なるはずなのにいっしょになってしまう.... // →異なるようになりました writer.println("1度目の日本語[" + wk11 + "]"); writer.println("2度目の日本語[" + wk12 + "]"); writer.println("</center>"); writer.println("</h1></body>"); writer.println("<html>"); // } } | ||||||||
