【トリビアの泉】Java初心者質問スレ【32へぇ〜】

このエントリーをはてなブックマークに追加
>>949
>> ただNullPointerExceptionの性質を考えるとやはり別例外を
>> 定義して使うべきと俺は思う。
>NullPointerException はどーゆー性質だと考えてるんだ?

だからnull参照に対する操作を行うとおきるもの、って…。
Javaの言語仕様として起こるのとnewで起こすのは違うでしょ。
>>951
その前には
| ランタイム例外を投げるにしても、ちゃんと代わりの
| ものを定義して使う方がわかりやすいと思う。
って書いただけだよ。いらんツッコミやめておくれ。
>>950
> RuntimeExceptionは特別な理由がない限りcatchすべきでは
> ないよ。
とは APIリファレンスには書いてないね、って話。

で、Error は特別な理由が無い限り catch すべきでない、と書かれてるので
RuntimeException と Error を混同してるのかと考えただけ。
>>952
> だからnull参照に対する操作を行うとおきるもの、って…。
NullPointerException の発生原因が null 参照に対する操作だけである、
という前提だと標準API 使うだけでも不都合起きないか?
>>953
> > > > ランタイム例外を投げるにしても、ちゃんと代わりの
> > > > ものを定義して使う方がわかりやすいと思う。
> > > NullReferenceException extends Exception を導入しろとでも?
> > > 素直に NullPointerException 使った方がマシ。
> > これはRuntimeExceptionのサブクラスなら何でもいいけど
> > NullPointerExceptionでないもの、というつもりで書いた。
> おいおい、言ってる事が変わってるぞ。
>
> > > 基本的にRuntimeExceptionはシステム(プログラム)の
> > > バグによってのみしか起こりえない、という位の認識を
> > > しておくべき。なのでチェック例外といっしょくたにcatchしたり、
> > > 無闇にthrowしてはいけません。

って事は、やっぱり
> > > NullReferenceException extends Exception を導入しろとでも?
を導入しろって事か?
それにしては、これへのレスが
> > これはRuntimeExceptionのサブクラスなら何でもいいけど
> > NullPointerExceptionでないもの、というつもりで書いた。
では意味が通じないような…
>>956
ごめん、全然わからん。
ランタイム例外を投げるならぬるぽじゃないものにしたほうが
いいんじゃないかって書いただけなんだが。

class MyRuntimeException extends RuntimeException

'Exception' は 'RuntimeException' のサブクラスだが、
'Exception' のサブクラスを定義してもそれはランタイム
例外じゃないんだが。
>>957
自己フォロー・・・
> 'Exception' は 'RuntimeException' のサブクラスだが、
逆だw

○ 'RuntimeException' は 'Exception' のサブクラスだが、
null にアクセスしたときに NullPointerException が発生するのは
0 で割り算したときに ArithmeticException が発生するのと同様に
JVM が (言ってみれば) 気を利かせて発生させてくれているに過ぎない。

プログラム上エラーにすべきことがわかっているならば null にアクセスする前に
プログラマが明示的に NullPointerException を発生させるべきである。
>>957
> > > 基本的にRuntimeExceptionはシステム(プログラム)の
> > > バグによってのみしか起こりえない、という位の認識を
> > > しておくべき。なのでチェック例外といっしょくたにcatchしたり、
> > > 無闇にthrowしてはいけません。
を前提にすると、throw new NullPointerException() の代わりに
> > > NullReferenceException extends Exception を導入しろとでも?
は導入すべきと考えるのか、考えないのか?
(もちろん俺は導入しないほうが良いと考える)

> ランタイム例外を投げるならぬるぽじゃないものにしたほうが
> いいんじゃないかって書いただけなんだが。
根拠が無いので却下。っつーか
if(obj==null) throw new NullPointerException();
がダメってんなら標準API 使えないし。

というわけで、
> > > 素直に NullPointerException 使った方がマシ。
という結論にいたるわけ。
>>959
> 0 で割り算したときに ArithmeticException が発生するのと同様に
float とか double だと 0除算で ArithmeticException 投げないので注意。
生の java.lang.NullPointerException を投げると、
そのメッセージを他の誰かが見たときに、

 ・その例外が発生することをプログラマが知らなかった == バグ なのか、
 ・あえてその例外を発生させてくれている == 親切 なのか

が、わかりにくくなる。(ソース見りゃわかるけど)

なので私は、メソッドが引数として null を受け付けないことを表明するために
そのアプリなり、ライブラリなりの名前を付けた例外を throw するようにしてます。

アプリ/ライブラリ名が foo の場合の例:

  public void func(Object hoge) {
    if (hoge == null) throw new fooNullPointerException();
    /* これ以降は確実に hoge は null ではない */
    /* hoge を使った何かの処理・・・ */
  }

毎回、例外オブジェクトを new するかどうかはまた別な話として。
>>960
> > > > NullReferenceException extends Exception を導入しろとでも?
> は導入すべきと考えるのか、考えないのか?
ランタイム例外を投げるとしても、って前提で始めた話に対するレスとして
その例を引き合いに出すのは明らかにおかしいが。
その質問に対してのみ答えるならば(nullチェックを前提に考えるとわかりにくいが)
引数がnullで渡ることが正常パターンとして予測されるならチェック例外を
投げるように定義しておくのもありでしょ。例えばお粗末だがこんなのとかさ。
public int toInt(String value) throws ConvertException {
 if (value == null) throw new ConvertException("value is null.");
 try {
  return Integer.parseInt(value);
 } catch (NumberFormatException e) {
  throw new ConvertException("value is not numeric.", e);
 }
}
nullかもしれないしNumericでないかもしれない文字列を
渡すことを許し、チェック例外で変換失敗時の処理を強制する、と。

> 根拠が無いので却下。っつーか
> if(obj==null) throw new NullPointerException();
> がダメってんなら標準API 使えないし。
んで俺の意見は標準APIと、どこぞの誰が書いたかわからんもの
(自分が書いたものも含む)とでは信頼度が違うってこと。
そもそも、あえてぬるぽにしなければならない理由も全くないわけだ。
例外は原因が明確であったほうがいい。
NullPointerExceptionだと原因が明確じゃない。
標準APIでNullPointerExceptionが出たら、普通は自分のコードを
疑うが、標準API以外だとどちらを疑えばいいか判断しにくい。
Exceptionのメッセージでわかるだろと言われればそれまでだ…。

もう寝ます。
質問です・・・。
あるデータの下位12bitだけを取り出すためにマスクをしたいのですが、
やり方がよくわかりません。
b=(b&0xFFF);
このような形でやってみてますができないので、どなたか知ってる方教
えてもらえませんでしょうか?
>>962
例外は毎回newしないと駄目ですよ…。
>>964
どんなエラーがでるの?
967964:03/10/09 04:43
>>966
エラーは出ないのですが、実際ほしい値と違うものが出てるようなのです。
データが2byteづつならんでいるファイルから1byteづつ取り出して、その
後にくっつけてそれの下位12bitだけを取り出したいのですが、

a[0]=bytearray[i+1]; a[1]=bytearray[i];
a[0]=(a[0])&(a[1]);
b=a[0] & 0xFFF;

これでbを出力という感じでやっています。
>>967
多分エンディアン
969964:03/10/09 05:35
>>968
今、エンディアンというものを調べて自分なりに解釈して
以下のように変えてみたのですが、すべて0になって出力さ
れてしまいました。

b=(byte)(((a[0]<<8)&((a[1])&0xFF)) & 0xFFF);

訂正してもらえれば幸いです。同時にもう少し試します。
>>969
ここではエンディアンは関係なかったかも

byte a[0] = bytearray[i+1], a[1] = bytearray[i];
short b = (short)a[0] << 8 & a[1] & 0xFFF;

で出ないかな?
多分a[0]をシフトしてなかったことと,シフトする前にshortにキャストしてなかったのが原因
足しあわせるのはorだよ。
((short)a[0] << 8 | a[1]) & 0xFFF;
>>971
スマソ
凡ミス
>>963
> ランタイム例外を投げるとしても、って前提で始めた話に対するレスとして
> その例を引き合いに出すのは明らかにおかしいが。
「ランタイム例外を投げるとしても〜」なら、
「チェック例外を投げろって事か?」という意味の反応は当然。

> 引数がnullで渡ることが正常パターンとして予測されるなら
普通は正常パターンには例外使うなって事になると思うが。

> そもそも、あえてぬるぽにしなければならない理由も全くないわけだ。
APIリファレンスに不正な null の使用に対しては NullPointerException 投げろと書いてある。
974964:03/10/09 08:17
>>968>>970>>971
ありがとうございました。何とかデータを取り出せた模様です。
しかし、数値があわないのでもう少し考えて見ます。
エンディアンについてももう少し調べてみます。
>>974
エンディアンの問題ならインデックスの0と1をひっくり返すだけで直るよ
>>974
((bytearray[i+1] & 0xF) << 8 ) | (bytearray[i] & 0xFF);
>>970
> シフトする前にshortにキャストしてなかったのが原因
関係ない。
byte の値でもシフト演算に際して単項数値昇格で int に格上げされる。
>>977
じゃあ逆にはみ出た部分を無視して欲しい場合にキャストが必要になるのな
979964:03/10/09 08:41
>>976-978
ありがとうございます。本当にたすかります。
>>976
>>((bytearray[i+1] & 0xF) << 8 ) | (bytearray[i] & 0xFF);

でいきました!これでようやく作業が始められます。
どうもありがとうございました。がんばります。
>>960
>  ・その例外が発生することをプログラマが知らなかった == バグ なのか、
>  ・あえてその例外を発生させてくれている == 親切 なのか
fooNullPointerException使うにしろ使わないにしろ、
前者の場合はソース見なきゃ原因(不正な null の入力があったのか、
初期化を忘れたのか)がわからんし、それほどライブラリ作成者を疑うなら、
後者の場合でも間違って例外投げてる可能性も考えなきゃいかんし。

> アプリ/ライブラリ名が foo の場合の例:
>
>   public void func(Object hoge) {
>     if (hoge == null) throw new fooNullPointerException();
ってのはなんだかなぁ…

それに、fooNullPointerException は RuntimeException か Error のサブクラスでしかありえないが、
常識的に Error ではないと考えると RuntimeException のサブクラスだよな。
> > 基本的にRuntimeExceptionはシステム(プログラム)の
> > バグによってのみしか起こりえない、という位の認識を
> > しておくべき。なのでチェック例外といっしょくたにcatchしたり、
> > 無闇にthrowしてはいけません。
に反してないのかね? ひょっとして、「RuntimeException」 はダメだが、
「RuntimeExceptionのサブクラス」は無闇に throw しても良いのか?

> 毎回、例外オブジェクトを new するかどうかはまた別な話として。
小細工してまで例外オブジェクトの生成コストを削減ですか…
そんなに例外投げまくるよーなプログラム書いてるのかな?
>>962
>生の java.lang.NullPointerException を投げると、
>そのメッセージを他の誰かが見たときに、
>
> ・その例外が発生することをプログラマが知らなかった == バグ なのか、
> ・あえてその例外を発生させてくれている == 親切 なのか
>
>が、わかりにくくなる。(ソース見りゃわかるけど)

バカだなあ。
NullPointerExceptionにはメッセージ (String) を引数にとるコンストラクタもある。
それを使えばいいだけのこと。
あえてfooNullPointerExceptionなんぞを作る必要はない。
>>973
揚げ足取りばかりしてきますね…。

>>980
> > アプリ/ライブラリ名が foo の場合の例:
> >
> >   public void func(Object hoge) {
> >     if (hoge == null) throw new fooNullPointerException();
> ってのはなんだかなぁ…
>
> それに、fooNullPointerException は RuntimeException か Error のサブクラスでしかありえないが、
> 常識的に Error ではないと考えると RuntimeException のサブクラスだよな。
> > > 基本的にRuntimeExceptionはシステム(プログラム)の
> > > バグによってのみしか起こりえない、という位の認識を
> > > しておくべき。なのでチェック例外といっしょくたにcatchしたり、
> > > 無闇にthrowしてはいけません。
> に反してないのかね? ひょっとして、「RuntimeException」 はダメだが、
> 「RuntimeExceptionのサブクラス」は無闇に throw しても良いのか?

>>960は俺じゃないけど
関数の仕様として引数nullが許されないのに、null渡すプログラム
書いたらそれはバグだろ。
ランタイム例外は誰もcatchしてる保証がないわけだしcatchして
しまったらバグをトラップしてしまっている可能性を憂慮しなければ
ならないから「無闇に」catch/throwするなって書いたの。
こういう議論は誰かが納得することはまずないから
984937:03/10/09 10:43
>>938-940
教えて頂いたページで、無事ダウンロードできそうです。
遅くなりましたが、レス有難うございます。
JBoss3.2.1+Tomcat4.1.24 で、EJB の実験しています。
クライアントアプリケーションは、Eclipse からのデバッグ、コマンドラインからの実行どちらとも巧くいっているのですが、
Servlet (JSP) から呼ぶと、getHome() したあとのリモートメソッド呼び出しで Invalid Invocation になってしまい、困っています。

デバッガでトレースしてみると、Class の(つまり Object の) equals が false になっているようで、
Method インスタンスの同定に障害がおきているようです。
(どういう文脈で行われているかよく分からないのでうまく説明できません・・・)
Class オブジェクトが、パッケージ・クラス名は同じですが、コンテナ上で違うインスタンスとして存在しているようです。

デプロイしたパッケージと、JSP が拾ってくるパッケージは別のところに置いてあるのですが、関係あるでしょうか?
(それぞれ server\all\deploy と WEB-INF/lib )
もしそうなら Webコンテナのあるサーバと EJB コンテナのあるサーバが別個のとき、
巧くいかないようにも思うのですが・・・
986デフォルトの名無しさん:03/10/09 12:53
外部からの多人数作業をするときに、変更されたくない変数をprivateで外部クラス
にすることがあるという前提で作業をしています。
Human.htmlからの各入力データ(名前・年齢・体重)をサーブレット(Human3)から
外部クラスHumanに代入し、セッションにArrayListとしてどんどん追加していきます。
そして現在セッション内にある各データをHtml上で出力したいのですが
うまくいかずに悶絶しています。

987986:03/10/09 12:54
外部クラスHumData.java

public class HumData {
 //各入力データ用変数
 private String name;
 private int age;
 private double weight;

 //name変数の代入値と戻り値
 public void setName(String name){
  this.name=name;
 }
 public String getName(int index) {
  return name;
 }
 //age変数の代入値と戻り値
 public void setAge(int age) {
  this.age=age;
 }
 public int getAge(int index) {
  return age;
 }
 //weight(名前)変数の代入値と戻り値
 public void setWeight(double weight) {
  this.weight=weight;
 }
 public double getWeight(int index) {
  return weight;
 }
}
988986:03/10/09 13:00
Htmlからの入力データをセッションへArrayList追加 Human3.java

import java.util.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Human3 extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)
//セッションの開始or新規作成
HttpSession session = request.getSession();
//属性の取得(属性 data )
ArrayList al=(ArrayList)session.getAttribute("data");
if(al == null) {
al=new ArrayList();
}

989986:03/10/09 13:00
//Htmlより年齢入力テキストnaem="ag"をint型にキャスト(変換)
String str=request.getParameter("ag");
int a=Integer.parseInt(str);
//Htmlより体重入力テキストnaem="wei"をdoble型にキャスト(変換)
String str2=request.getParameter("wei");
double b=Double.parseDouble(str2);
//HumanDataのインスタンス化と各入力データの代入
HumData hd=new HumData();
hd.setName(request.getParameter("nam"));
hd.setAge(a);
hd.setWeight(b);
//ArrayListの各入力データ)をまとめて追加
al.add(hd);
 //セッションへ追加
session.setAttribute("data", al);
990986:03/10/09 13:02
 //ブラウザ表示
 response.setContentType("text/html;charset=Shift_JIS");
 PrintWriter out=response.getWriter();

 out.println("<html><head>");
 out.println("<title>皆々様のデータ</title>");
 out.println("</head><body>");
 out.println("<table border='1'>");
 out.println("<tr style='background:#00ccff'>");
 out.println("<th>No</th><th>名前</th><th>年齢</th><th>体重</th>");
 out.println("</tr>");

 //セッション内容の表示
 for(int i=0; i<al.size(); i++) {
 out.println("<tr>");
 out.println("<td>" + i + "</td>");
 out.println("<td>" + hd.getName(i) + "</td>");
 out.println("<td>" + hd.getAge(i) + "</td>");
 out.println("<td>" + hd.getWeight(i) + "</td>");
 out.println("</tr>");
 }
 out.println("</table>");
 out.println("<tr>");
 out.println("<td><a href='/soesoe3/Human.html'>入力画面へ戻る</a></td>");
 out.println("</tr>");
 out.println("</body></html>");
 }
}
991986:03/10/09 13:04
このままだと見てのとおり最後に入ったデータがそのままきてしまいます。
(来るようになってます)
現状ではArrayListの中身をどのようにして順に引き出したらいいか
わかりません。
よろしくお願いいたします。
992962:03/10/09 14:04
>>983
> こういう議論は誰かが納得することはまずないから

自分が馬鹿だったことを納得し始めています。

fooNullPointerException を自作するくらいなら、
あらかじめ用意されている、生の NullPointerException を使って
そのコンストラクタに必要なだけメッセージを渡すべきだ、と。

>>980
>> 毎回、例外オブジェクトを new するかどうかはまた別な話として。
>小細工してまで例外オブジェクトの生成コストを削減ですか…
>そんなに例外投げまくるよーなプログラム書いてるのかな?

はい。書いてました。
小細工はしてなかったけれど、激しく例外投げまくるプログラムを
書いていました。それで、例外オブジェクトって再利用すべきなの
かもしれない、とか思ってました。
それが何故正しくないのか、もっと勉強します。
過去ログ、関連スレの一覧や、
これからJavaでプログラミングを始めたいが、
なにをすればいいか、わからないひとは、下のリンクをクリック。
http://www.wikiroom.com/java/

以下のエラーが表示されて、途方にくれているあなたは、下のリンクを。
「コマンドまたはファイル名が違います」
「'javac' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。」
「Exception in thread "main" java.lang.NoClassDefFoundError: Hello」
http://www.wikiroom.com/java/?path%2Cclasspath

前スレ。
【トリビアの泉】Java初心者質問スレ【32へぇ〜】
http://pc2.2ch.net/test/read.cgi/tech/1063774151/l50

// とりあえずテンプレはこんな感じでいかが?
// まだリンク先のwikiのページは編集しおわってないけれど。
994デフォルトの名無しさん:03/10/09 16:04
>>993
スッキリして(・∀・)イイ!!
では、とりあえず1000行くまえに、たててきます。
建ててきました。でも、ここまですっきりすると、
もうすこし、>2以降に色々追加してもいいかもしれないや。

【初心者】 Java質問・相談スレ33 【大歓迎】
http://pc2.2ch.net/test/read.cgi/tech/1065684016/l50

//とりあえず、wikiのほうの過去ログ一覧、編纂してきます。
99741:03/10/09 18:18
今回のトリビアも興味深いものでした。

これからもよろしくお願いします。

埋め。
a
(д゚≡゚д)
キタ━━━━(゚∀゚)━━━━!!
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。