出産前後の痔にはご注意!

JAVAを独学で勉強しております。synchronizedをインスタンスメソッドに使用したのですが、同期化できません。いくら考えてもわからなかったので、質問しました。ソースを記入します。

class Test extends Thread{

public void run(){
ss();
}
public synchronized void ss(){
for(int x=1;x<=10;x++){
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String[] args){
Test t1 =new Test();
Test t2 =new Test();
Test t3 =new Test();
t1.start();
t2.start();
t3.start();
}
}
実行すると、同期化されてなく、ランダムに表示されます。違うオブジェクトで参照しているから、ロックかけても意味がないのかなーとも思っていますが、
Threadの拡張じゃなく、Runnableの実装に書き換えると同期化されます。なぜでしょう?自分なりに精一杯考えましたがわかりません。分かる方、説明お願いできますでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (5件)

No.3です。


そのRunnable継承版のソースコードだと、
たしかに同期化される…。
 
 MXPXさんの書いた
 Thread継承版のソースコードと
 Runnable継承版のソースコードとでは、
 「別物の」ソースコードになっているので、
 この書き方のままでは両者を比較できない。
 (※ソースコードの書き方の違いであって、
 Thread継承とRunnable継承の違いではない)
 
 /**
  *Runnable継承版のmain()
 */
 public static void main(String[] args){
  Test test = new Test();//Testのインスタンス作成(唯一)
  Thread t1 = new Thread(test);//第1スレッド作成
  Thread t2 = new Thread(test);//第2スレッド作成
  Thread t3 = new Thread(test);//第3スレッド作成
  t1.start();//第1スレッド開始
  t2.start();//第2スレッド開始
  t3.start();//第3スレッド開始
  
  /*この時点で、3つのスレッドが存在し、
  そのいずれもが「唯一のTestインスタンスのrun()メソッド」
  を定期的に呼び出すことになる
  (つまり3つのスレッドが競って1つのインスタンスのメソッドを呼び出す)。
  いいかえると
  「スレッド3つに、呼ばれるほう1つ」。
  ってことで、その「呼ばれる」唯一のメソッドにsynchronized
  を付ければ当然、
  そのメソッド呼び出しは同期化される。
  */
 }
 
 
 /**
  Thread継承版のmain()
 */
 public static void main(String[] args){
  Test t1 = new Test();//第1Testインスタンス(かつ第1スレッド)作成
  Test t2 = new Test();//第2Testインスタンス(かつ第2スレッド)作成
  Test t3 = new Test();//第3Testインスタンス(かつ第3スレッド)作成
  t1.start();//第1スレッド開始
  t2.start();//第2スレッド開始
  t3.start();//第3スレッド開始
  
  /*この時点で、3つのスレッドが存在し、
  それぞれが「別々のTestインスタンスのrun()メソッド」
  を定期的に呼び出すことになる
  (つまり3つのスレッドが競って1つのインスタンスの
  メソッドを呼び出すわけではない)。
  いいかえると
  「スレッド3つに、呼ばれるほうも3つ」。
  呼ばれる側のメソッド1つに、
  (いわば専属の)実行用スレッド1つが対応してる感じ。
  よって同期も何もない。
  */
 }
    • good
    • 0
この回答へのお礼

試していただいてありがとうございます。
kacchannさんの説明を読ませていただくと、なるほど!と思います。ありがとうございました。

お礼日時:2004/01/14 08:40

No.1です。


現在、No.1の参考URLにアクセスできないようなので
こちらに書き込ませていただきます。

Q.メソッドに付ける synchronized って何ですか?
A.インスタンスをスレッド間で排他的に利用するための宣言です。
 排他の範囲はメソッドではなくインスタンスであることに
 注意して下さい。すなわち、 synchronized は
 「メソッドを排他的に実行するための宣言」ではありません。
 インスタンスが異なれば待たされずに同時に実行されますし、
 synchronized を付けた別のメソッドであっても
 同じインスタンスに対するものならば同時に実行されません。

ということです。
後はNo.4の方の書かれたとおりです。
    • good
    • 0

Runnable継承版のソースコードも載せよう。



あと、for()ループの回数を10回でなくもっと長くすると、
状況が変わるような気がする。

この回答への補足

Runnableの方のソースです。

Test t1 =new Test();
Test t2 =new Test();
Test t3 =new Test();
上記のソースを下記に変更です。
Test test = new Test();
Thread t1 = new Thread(test);
Thread t2 = new Thread(test);
Thread t3 = new Thread(test);
それと、Threadの拡張から、Runnableの実装に変更します。分かりにくいかもしれませんが、アドバイスお願いします!ループの件ですが、100回に変更しても結果は変わりません。よろしくお願いします。

補足日時:2004/01/13 23:10
    • good
    • 0

> Runnableの実装の場合、なぜ同期化できるのかお分かりでしたら、教えてもらいたいのですが?



同期化しているのではなく、単に逐次実行しているのでは?

ご質問のプログラムでは、t1,t2,t3は異なるインスタンスなので、別個に排他制御されます。
つまり、事実上排他制御されないのです。

この回答への補足

ご回答ありがとうございます。
Runnableの実装の場合:
synchronizedキーワードがないと、t1,t2,t3、ランダムに表示されます。synchronizedを付けると、順番に表示します。
Threadの拡張の場合:
synchronizedキーワードがないと、t1,t2,t3、ランダムに表示されます。synchronizedを付けても、ランダムに表示します。

別々のオブジェクトなんで、別個に配置制御されるのは、なんとなくですが、理解できます。
Runnableの実装の場合について、もう少し詳しい情報がほしいので、お分かりでしたら、教えてください!
よろしくお願いします。

補足日時:2004/01/13 18:39
    • good
    • 0

とりあえずpublic synchronized void ss()をstaticにしてみてください。


詳細は参考URLをご覧ください。

参考URL:http://www.gimlay.org/~javafaq/S021.html#S021-02
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございました。
Runnableの実装の場合、なぜ同期化できるのかお分かりでしたら、教えてもらいたいのですが?
参考書を見ていると、私が書いたソースのパターンで、Runnableの実装のものが多くあります。これをThreadの拡張に変更すると、同期化しなくなります。
お分かりでしたら、おしえてください。
よろしくお願いします。

お礼日時:2004/01/13 16:54

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qシンボルが見つかりませんというエラーが理解できません。

以下のようなじゃんけんゲームのプログラムを書いたのですが、「シンボルが見つかりません。」というエラーが表示されるのですが、エラーの意味が理解できず、解決できません。どこが間違っているのか教えていただけませんか。

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.File;

public class janken extends Applet
implements Runnable, ActionListener {
private static final int EXTERNAL_BUFFER_SIZE = 128000;

Image image[] = new Image[3];
Thread t;
int index1 = 0;
int index2 = 0;
String msg = "";
String msg1 = "";

boolean state = false;
Button b1 = new Button("ぐー");
Button b2 = new Button("ちょき");
Button b3 = new Button("ぱー");

public void init(){
for(int i = 0; i<=2; i++){
img[i] = getImage(getDocumentBase(),"hanabi" + (i+1) + ".JPG");
}
add(b1);
add(b2);
add(b3);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
msg1 = "結果は・・";

}

public void paint(Graphics g){
g.drawImage(img[index1],350,30,this);
g.drawImage(img[index2],695,30,this);
g.drawString("コンピューター",420,300);
g.drawString("あなた",800,300);
g.drawString(msg,630,320);
g.drawString(msg1,550,320);
}

public void start(){
state = true;
t = new Thread(this);
t.start();

}

public void run(){
while(state){
index1++;
if(index1 == 3){
index1 = 0;
}
index2++;
if(index2 == 3){
index2 = 0;
}
repaint();
try {
Thread.sleep(60);
}catch(InterruptedException e) { }
}
}

public void actionPerformed(ActionEvent e){
if(state == false) {
start();
return;

}
state = false;
if(e.getSource() == b1) {
msg = "ぐー";
index2 = 0;
}

else if(e.getSource() == b2){
msg = "ちょき";
index2 = 1;
}

else if(e.getSource() == b3){
msg = "ぱー";
index2 = 2;
}
check();
repaint();
}

public void check() {
if(index1 == index2) msg ="あいこ";


else if (index1 == 0) {
if(index2 == 2) msg="あなたの勝ち";
else msg ="あなたの負け";
}

else if(index1 == 1) {
if(index2 == 0) msg="あなたの勝ち";
else msg="あなたの負け";
}

else if(index1 == 2) {
if(index2 == 1) msg="あなたの勝ち";
else msg="あなたの負け";
}

}
}

以下のようなじゃんけんゲームのプログラムを書いたのですが、「シンボルが見つかりません。」というエラーが表示されるのですが、エラーの意味が理解できず、解決できません。どこが間違っているのか教えていただけませんか。

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.File;

public class janken extends Applet
implements Runnable, ActionListener {
private static final int EXTERNAL_BUFFER_SIZE = 128000;

Image image[] = new Imag...続きを読む

Aベストアンサー

「シンボルを見つけられません。」というエラーの下に何か表示がありませんでしたか?そこにヒントがあると考えられます。
シンボルを見つけられませんといエラーが表示される主な理由は4つあります。
(1)クラス、メソッド、変数などの綴りミスや定義していない変数を使用している可能性がある。
(2)コンストラクタを呼び出すときに、newを忘れている可能性がある。(3)公開されていないメンバーを呼び出している可能性がある。
(4)必要なimport文を記述し忘れている可能性がある。
ここでのあなたのエラーは(1)番ではないでしょうか?上記ではimageとなっている変数がimgになっていますね。
これはエラー表示をよく見ることで意外と簡単に解決できるのです。
ゆっくり丁寧にエラー表示を見るように心がけることが大事ですよ。

Qsynchronizedについて

こんにちは!質問です!

javaのsynchronizedについて教えてください。

DBへの更新メソッドに、
排他制御をしようと思っているのですが、調べて自分で
コーディングしました。アドバイスをお願いします!

public static synchronized void update() throws SQLException{
Connection db = null;
PreparedStatement objPs = null;
ResultSet rs = null;
StringBuffer sql = new StringBuffer();
try {
Context ctx=new InitialContext();
DataSource ds=(DataSource)ctx.lookup("java:/comp/env/test/sample");
db=ds.getConnection();
sql.append("UPDATE ");
sql.append("test ");
sql.append("SET ");
sql.append("aaa = '000', ");
sql.append("bbb = '000', ");
sql.append("ccc = '000' ");
sql.append("WHERE dd = '0'");
objPs=db.prepareStatement(sql.toString());
objPs.executeUpdate();
} catch (SQLException e) {
//エラー処理
} catch(Exception e) {
//エラー処理
} finally {
try {
if(rs!=null) {rs.close();}
if(objPs!=null){objPs.close();}
if(db!=null) {db.close();}
} catch(Exception e){
e.printStackTrace();
}
}
}

クラスはpublicですが、static synchronized にしていたら、
排他制御が可能でしょうか?
staticなので、インスタンス複数でも1つしか存在しないのですよね?
その場合、このメソッドを呼び出しているスレッドが終了しないうちに
別のスレッドが呼び出した場合、そのスレッドはどうなるのでしょうか?
目で見て確認する方法もできれば、教えていただきたいです!

また、sql発行メソッド(上記メソッド)を直接排他制御するのと、
上記メソッドの呼出元を排他制御するのと、どちらがいいとかって
あるのですか?

ご存知の方、よろしくお願い致しますm(_ _)m

こんにちは!質問です!

javaのsynchronizedについて教えてください。

DBへの更新メソッドに、
排他制御をしようと思っているのですが、調べて自分で
コーディングしました。アドバイスをお願いします!

public static synchronized void update() throws SQLException{
Connection db = null;
PreparedStatement objPs = null;
ResultSet rs = null;
StringBuffer sql = new StringBuffer();
try {
Context ctx=new InitialContext();
DataSource ds=(D...続きを読む

Aベストアンサー

> また、static synchronized と synchronized
> どういう違いがあって、どちらを使ったらいいのでしょうか?

synchronizedはそれを含むオブジェクトを排他制御の対象にします。
staticメソッドのsynchonizedは同じクラスのstaticメソッドに対して、
staticでないメソッドのsynchonizedは同じインスタンス中の他のsynchronizedに対して
排他制御がかかります。
今回のような場合はインスタンス化せず、staticで排他制御を行ったほうが良いかと思います。

サンプルコードを書きましたのでご覧ください。
staticメソッドのupdateとインスタンスメソッドのget同士では排他制御がかかりません。
さらにメソッド中でフィールド変数を使用していると、これに対しても排他制御がかかりません。注意が必要です。

public class SynchroTest1 {

private static String str;

public static void main( String[] args ) {
for( int i = 0; i < 10; i++ ){
new SyncroTest1Thread( i ).start();
}
}

public static synchronized void update(String arg) {
System.out.println( "-- " + arg + " start.");
str = arg;
try {
Thread.sleep( 500 );
} catch ( InterruptedException e ) {
e.printStackTrace();
}
System.out.println( "-- " + arg + " finish." + str );
}

public synchronized void get( String arg ) {
System.out.println( "++ " + arg + " start.");
str = arg;
try {
Thread.sleep( 500 );
} catch ( InterruptedException e ) {
e.printStackTrace();
}
System.out.println( "++ " + arg + " finish." + str );
}
}

class SyncroTest1Thread extends Thread {
int id;

SyncroTest1Thread ( int i ) {
id = i;
}
public void run() {
System.out.println( "Thread " + id + "in");
if( id % 2 == 0)
SynchroTest1.update( "Thread " + id );
else
new SynchroTest1().get( "Thread " + id );

System.out.println( "Thread " + id + "out");
}
}

> また、static synchronized と synchronized
> どういう違いがあって、どちらを使ったらいいのでしょうか?

synchronizedはそれを含むオブジェクトを排他制御の対象にします。
staticメソッドのsynchonizedは同じクラスのstaticメソッドに対して、
staticでないメソッドのsynchonizedは同じインスタンス中の他のsynchronizedに対して
排他制御がかかります。
今回のような場合はインスタンス化せず、staticで排他制御を行ったほうが良いかと思います。

サンプルコードを書きましたのでご覧ください。...続きを読む

QIOException ってどういうときに起こるのでしょうか?

IOException ってどういうときに起こるのでしょうか?

http://www.atmarkit.co.jp/fjava/rensai2/javaent12/javaent12.html
を見て勉強しています。

  catch ( IOException e) {
    System.out.println( "キーボードが故障しているのかもしれません" );
  }

と書いてあります。
ハード(キーボード)が故障しているのを Java のプログラムのレベル(ソフトウェア)で感知できるというのがよくわかりません。「

NumberFormatException の方はわかるのですが・・・

Aベストアンサー

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接続だったりするわけですけど、
InputStreamは、その入力元の情報を持っていないので、
データを読み取る際は常に
IOExceptionをキャッチするコードを書かなくてはいけません。
たとえ、絶対にIOエラーが発生しないストリームだとしても。

さらに付け加えるなら、
そもそも「標準入力=キーボード」であるとは限りません。
(一般的にはキーボードであることが多いですが。)
Javaでは、
System.setIn(InputStream)
を呼び出して、標準入力を変えてしまうことができますし、
標準入力を指定してプログラムを実行することができるOSもあります。

追伸1:
例外をキャッチしたときは、
スタックトレースをプリントすることをおすすめします。
catch (IOException e) {
e.printStackTrace();
}

追伸2:
そのプログラムでIOExceptionを発生させる最も簡単な方法は、
readLine()を呼び出す前に
標準入力(System.in)を閉じてしまうことです。
System.in.close();

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接...続きを読む

QString型の日付(2005/11/25)の比較

Java初心者です。String型で2005/11/25 のように2つString型で日付を取得したときに、大小の比較をしたいのです。どういう方法が考えられますか?よろしくお願いします。

Aベストアンサー

書式がyyyy/mm/ddで決め打ちならば他の方が書かれているとおりString#compareTo()で充分でしょう。
yyyy/m/dなど書式が不定の場合には、java.text.DateFormatを利用してjava.util.Dateに変換して比較するか、/で文字列を分解し、年・月・日を抽出してそれぞれを比較するなどが考えられます。

Qvolatileの振る舞いが分かりません。

Javaのプログラミングを行っているのですが、volatileをつけた結果になっとくがいきません。
volatileというのは、他のスレッドによって変数の値が書き換えられる状態になるのを防ぐことができる
とあるのですが、出力結果からしてそうじゃないんじゃないかと考えています。
下記のソースの実行結果がなぜそうなるのかいまいち分かっていません。

public class Thirsty {
//ボトル
static Bottle bottle;

public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
bottle = new Bottle(2000);

// ボトルから水を飲む人
class Person extends Thread {
public Person(String name) {
super(name);
}
public void run() {
// 200ml飲んでみる。飲めたらtrueが返される
while(true) {
if(bottle.drink(10)) {
System.out.println(Thread.currentThread().getName() + " did drink water ");
} else {
System.out.println(Thread.currentThread().getName() + " couldn't drink water ");
break;
}
}
}
}

Person yamada = new Person("Yamada");
Person tanaka = new Person("Tanaka");
yamada.start();
tanaka.start();
}
}

class Bottle {
private volatile int water;// volatileを使用した場合
Bottle(int amount) {
water = amount;
}

// ボトルにamountで指定した量だけ残っているか
private boolean contains(int amount) {
if(amount <= water) {
return true;
} else {
return false;
}
}

// ボトルの水をamountで指定した量だけ水を飲む
public boolean drink(int amount) {
if(contains(amount)) {//水があれば残りの量から引く 残量を出力する
water -= amount;
System.out.println(Thread.currentThread().getName() + " water = "+water);
return true;
}
return false;
}
}


私の場合、出力結果で、最後の方には
Yamada did drink water
Yamada water = 0
Yamada did drink water
Yamada couldn't drink water
Tanaka water = 80
Tanaka did drink water
Tanaka couldn't drink water
となります。 途中でも waterの値がいきなり高くなったりします。
なぜこのような結果がでるのでしょうか?
volatileというのはメインメモリの値を必ず参照するとあるのですが、このメインメモリというのは
class Thirstyのメモリを指すのでしょうか?

Javaのプログラミングを行っているのですが、volatileをつけた結果になっとくがいきません。
volatileというのは、他のスレッドによって変数の値が書き換えられる状態になるのを防ぐことができる
とあるのですが、出力結果からしてそうじゃないんじゃないかと考えています。
下記のソースの実行結果がなぜそうなるのかいまいち分かっていません。

public class Thirsty {
//ボトル
static Bottle bottle;

public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
bottle = new Bo...続きを読む

Aベストアンサー

実はクラスのフィールドには複数のコピーが存在します。
その存在場所がメインメモリと作業用メモリです。
メインメモリにあるものがマスターコピーであり、
スレッドごとに存在する作業用メモリ上にそのコピーが置かれます。
フィールドの読み書きはこの作業用メモリにあるコピーに対して行われ、
適宜マスターコピーとの間で同期が取られます。
これは実行効率を上げるために行われています。

volatileなフィールドの場合はマスターコピーがフィールドの読み書きでの操作対象になります。
> volatileというのはメインメモリの値を必ず参照する
というのがまさにこれで、マスターへのアクセスが行われることが保証されます。
> volatileというのは、他のスレッドによって変数の値が書き換えられる状態になるのを防ぐことができる
わけではなく、
どのスレッドも確実にそのフィールド(のマスターコピー)をその時点で書き換えることを保証するということです。
したがって、volatileは同期制御が不要になる魔法の呪文ではありません。
どのスレッドも自分の好き勝手なタイミングでフィールドを書き換えるのはvolatileを付けても同じです。
ただ、作業用コピーに対して行い同期はシステムに任せるのか、直接マスターコピーに対して行うのかの違いだけです。
質問者のサンプルでいえばcontainsとdrinkにsynchronizedを付ける等、
同期を取る仕組みを加えないとおかしなことになります。

volatileは最適化によってマスターコピーが変更されない事態を防ぐことの他に、
double型やlong型のようなメイン-作業間でのアトミックな扱いが保証されていないような型のフィールドを
マルチスレッドで扱えるようにするためにもあります。
64ビット幅のdouble型やlong型はマスターコピーと作業用コピーとの間でやりとりする時に、
一度に同期が取られることが保証されていません(非アトミックな扱い)。
32ビット幅分ずつで2回でコピーされうるので、
例えばあるスレッドから32ビット分だけ作業用コピーからマスターへコピーされた時点で、
他のスレッドによってマスターコピーが読まれるような事態が起こりえます。
volatileはこれを防ぐことができ、
全幅64ビット分の同期が終了しない限り他のスレッドからアクセスされなくなります。
この機能が
> volatileというのは、他のスレッドによって変数の値が書き換えられる状態になるのを防ぐことができる
という誤解を生んでいるんじゃないかなとも思ったりします。

volatileについてはJava言語仕様の他、Java仮想マシン仕様に詳細があるので、
これらの文書の中をvolatileをキーワードに探してみてください。

実はクラスのフィールドには複数のコピーが存在します。
その存在場所がメインメモリと作業用メモリです。
メインメモリにあるものがマスターコピーであり、
スレッドごとに存在する作業用メモリ上にそのコピーが置かれます。
フィールドの読み書きはこの作業用メモリにあるコピーに対して行われ、
適宜マスターコピーとの間で同期が取られます。
これは実行効率を上げるために行われています。

volatileなフィールドの場合はマスターコピーがフィールドの読み書きでの操作対象になります。
> volatileというのは...続きを読む

Q空の文字列とnullと""

java初心者です。
空の文字列とnullと""の3つの関係がよくわかりません。

TextFieldを使った簡単なプログラムを作りました。そこで、”TextFieldに何も入力されていないこと”を判定する文を書こうと思ったのですが、どう書けばいいのか迷いました。

TextFieldのオブジェクトをtfとして、tf.getText()==""かtf.getText()==nullで大丈夫だと思いましたが、実行してみると、どちらを用いても判定できませんでした。結局、tf.getText().length()==0で判定できました。そこで、リファレンスを見ると、getText()はデフォルトで空の文字列を返すと、書いてありました。

したがって、「""とnullは空の文字列とは異なる」という理解に至ったのですが、では空の文字列とは何なのかという疑問がわいてきました。

また、自分は""とnullの違いもよくわかっていません。""とnullが異なるものである、ということはわかるのですが・・・

質問をまとめると
・空の文字列とは何なのか?
・空の文字列は""やnullとどう違うのか?
です。よろしくお願いします。

java初心者です。
空の文字列とnullと""の3つの関係がよくわかりません。

TextFieldを使った簡単なプログラムを作りました。そこで、”TextFieldに何も入力されていないこと”を判定する文を書こうと思ったのですが、どう書けばいいのか迷いました。

TextFieldのオブジェクトをtfとして、tf.getText()==""かtf.getText()==nullで大丈夫だと思いましたが、実行してみると、どちらを用いても判定できませんでした。結局、tf.getText().length()==0で判定できました。そこで、リファレンスを見ると、getText()はデフ...続きを読む

Aベストアンサー

tf.getText() == ""
では、オブジェクト比較になってしまうので、当然NGです。

"".equals(tf.getText())

とすれば良いでしょう。

空文字と呼ばれているものは、""と同じですよ。
Stringクラスで考えると、インスタンス化がされているが、中身の文字列が""の状態にあります。

nullは、そもそもオブジェクトすら設定されていない状態です。
例えばStringBufferクラスの変数を宣言しても、インスタンス化されていない状態、それがnullです。

QJavaで文字列をゼロ埋め(ゼロパディング)

Javaで文字列を前ゼロで埋め(ゼロパディング)たいのですが、
exceptionが発生してうまくいきません。
だれかお助け頂けたら助かります。

(例)123の前に0を5つ結合したい場合、

String str2="123";
String str = String.format("%08s",str2);

で問題無いと思ったのですが、
exceptionが発生してしまいます。

回答お待ちしております。

Aベストアンサー

そのExceptionはどういったExceptionなのか把握されてますか?
何が悪いのかの理由もそのExceptionからわかると思いますが。

http://docs.oracle.com/javase/jp/6/api/java/util/Formatter.html#syntax
をよく読んで"%08s"という指定ができるのかどうか確認しましょう。

やられたいことは"123"の先頭に"00000000"をつけて後ろから8文字取り出せばできると思いますが。

Qフォーム上で押されたボタンによってサーブレットの処理を変えたい

Urizakaです。
さて、さっそく質問です。
JSPの同一フォーム上に「登録」「修正」「削除」のボタンを置き、その押された
ボタンによってサーブレット内での処理が切り替わる(具体的には、違う
SQL文を実行し、違うJSPページをgetRequestDispatcherメソッドで生成
する)ようにしたいのですが、どのようにすればよいのでしょうか?
もちろんそれぞれの処理に対して別々のサーブレットを作り、javaScript
でそれぞれのサーブレットへ飛ぶように制御するという処理も考えたことは
考えたのですが、できれば一つのサーブレットで済ませたいと考えたもので
…宜しくお願いします。

Aベストアンサー

お恥ずかしい限りです。
前述の例、動くわけがありませんね(汗)

2つめの例、書きなおします。

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

■JSPのフォーム

<form name=MyForm action="<<サーブレットのURL>>" method=post>
<input type=button name=MyClick value=登録 onClick="func('Toroku');">
<input type=button name=MyClick value=修正 onClick="func('Shusei');">
<input type=button name=MyClick value=削除 onClick="func('Sakujo');">
<input type=hidden name=MySubmit>
</form>

<script language="JavaScript">
function func(MyCommand){
document.MyForm.MySubmit.value=MyCommand;
document.MyForm.submit();
}
</script>

■Servletでの処理
// リクエストの取得
String MyAction = req.getParameter("MySubmit");

// 処理の実行
if (MyAction.equals("Toroku")){...}
if (MyAction.equals("Shusei")){...}
if (MyAction.equals("Sakujo")){...}



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

こんな感じでどうでしょうか。
ちなみにこうやって書いておくと、フォームのボタンからじゃなくても
アンカーをクリックすることで同じ効果が出せそうな……

<a href="JavaScript:func('Toroku')">登録</a>

あ、でもまたボロが出そうなのでこの辺で(^_^;)

お恥ずかしい限りです。
前述の例、動くわけがありませんね(汗)

2つめの例、書きなおします。

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

■JSPのフォーム

<form name=MyForm action="<<サーブレットのURL>>" method=post>
<input type=button name=MyClick value=登録 onClick="func('Toroku');">
<input type=button name=MyClick value=修正 onClick="func('Shusei');">
<input type=button name=MyClick value=削除 onClick="func('Sakujo');">
<input type=hidden name=M...続きを読む

QJavaで改行などが出来ないのです。

 Java の事で質問です。 
 

 System.out.println("このようにしても\n");

 改行できません。
 
 このようにしても\n   

 と表示されてしまいます。どうしてでしょう。ちなみにOSはMacOS9.1です。なにか関係があるのでしょうか?

Aベストアンサー

> class amigo{
> public static void main(String args[]) {
> System.out.print("aaaaaaaa");
> System.getProperty("line.separator");
> System.out.print("bbbbbbbb");
> }
> }
> のような使い方でしょうか?

String line_sep = System.getProperty("line.separator");
System.out.println("あいうえお" + line_sep + "かきくけこ");

こうです。

Qラジオボタンの選択肢をサーブレットで取得するには?

サーブレットの開発を行っていますが、ブラウザー側で
ラジオボタンを選択した際に何を選択したかのデータを取得したいのです。
(下記のHTMLで言えば、割引手形か、手形貸付か、証書貸付というのを取得したいのです)
パラメーターをサーブレットで受け取りたいのですが
うまくいきません
HTMLでHIDDENを使用するとか聞いたことはあるのですがどのようにコーディングすればいいんでしょうか?
よろしくお願いいたします。

<p>
<input type="radio" name="radiobutton" value="radiobutton">
割引手形 
<input type="radio" name="radiobutton" value="radiobutton">
手形貸付 
<input type="radio" name="radiobutton" value="radiobutton">
証書貸付
</p>

ブラウザー側からは
<form action="http://localhost/servlet/yuushi" method=post>
の指定を行っています。
サーブレットでの受け取り方を、
String p2=request.getParameter("radiobutton");
 とすると、p2=radiobuttonとデータがセットされました。

サーブレットの開発を行っていますが、ブラウザー側で
ラジオボタンを選択した際に何を選択したかのデータを取得したいのです。
(下記のHTMLで言えば、割引手形か、手形貸付か、証書貸付というのを取得したいのです)
パラメーターをサーブレットで受け取りたいのですが
うまくいきません
HTMLでHIDDENを使用するとか聞いたことはあるのですがどのようにコーディングすればいいんでしょうか?
よろしくお願いいたします。

<p>
<input type="radio" name="radiobutton" value="...続きを読む

Aベストアンサー

それぞれの項目の value を、ユニークにして下さい。例えば、

<input type="radio" name="radiobutton" value="1"> 割引手形 
<input type="radio" name="radiobutton" value="2"> 手形貸付 
<input type="radio" name="radiobutton" value="3"> 証書貸付

そうすれば、「手形貸付」を選択したときに

String p2 = request.getParameter("radiobutton");

とすれば、p2 は "2" になります。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング