gooID利用規約 改定のお知らせ

Javaで条件分岐などによってコード自体を削除することはできるのでしょうか。
目的はデバッグコードの負荷軽減です。
C言語でいうところの、プリプロセッサのようなことができることが理想です。

例えば、メソッド中に以下のようなコードがあるとします。
------------------------------------
final boolean DEBUG = true;

if (DEBUG) System.out.println("Debug: hogehoge");
------------------------------------

上の場合はif文条件分岐の処理負荷が発生すると思います。
この程度であれば低負荷であることは認識していますが、どうも気持ちが悪いです。


例えば、C言語であれば以下のようにしてコンパイル時にコードごと削除することができると思います。
-------------------------------------
#define DEBUG

int main(){
#ifdef DEBUG
   printf("Debug: hogehoge");
#endif
return 0;
}
-------------------------------------

Javaで上記のようなことを実現することは可能でしょうか。

デバッグコードの削除が目的ですので、仮にこれができなかったとしてもIDEやそのプラグインなどで目的が達せられれば問題ありません。

どなたか解決策をご存知であればご教示願います。

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

A 回答 (2件)

「java プリプロセッサ」で検索すれば、Java用に作られた


プリプロセッサがいくつか見つかります。
(参考)
http://mfsocket.blogspot.com/2011/08/001java.html

また、Cコンパイラにjavaソースをプリプロセッサ処理させる
という手もあります。
(参考)
http://www.symmetric.co.jp/blog/archives/21

ただ、上記参考URLにも書かれている通り、
こういったプリプロセッサ処理をやるとeclipseとの連携が
難しくなります。

http://blawat2015.no-ip.com/~mieki256/diary/2006 …
に書かれていますが、あまりシビアでなければ
コンパイラの最適化に期待した方が幸せかもしれません。
少なくともif文の条件式が定数値の場合の最適化くらいは
してくれると思います。
    • good
    • 0

こうしたものは、JavaではAOPを利用するのが一般的だろうと思います。

AOPというのは、多くのクラスで特定の地点で要求される処理を「横断的関心事(アスペクト)」として扱い、指定されたクラスに一斉に処理を外部から挿入したり取り除いたりする機能です。

AspectJというライブラリがそのための機能を提供します。が、Spring AOPを利用したほうがアノテーションでポイントカットを簡単に挿入できるので、私はもっぱらSpring利用です。AspectJやSpring AOPなどで検索してみてください。

AOPの場合、コードを挿入する位置はポイントカットと呼ばれる地点に限られており、だいたいメソッドの呼び出し前と呼び出し後という感じなので、細々とコード内に埋め込んでいくわけにはいきません。このへんが少し不自由な感じがするかも知れません。が、デバッグコードだけでなく、例えばテスト関連などでも用いられますし、データベースなどのダミーデータ挿入などいろいろ応用が効くので、覚えておいて損はないと思いますよ。
    • good
    • 0
この回答へのお礼

回答ありがとうございます!

Spring AOPなるものについて調べてみました。
確かに任意の箇所にコードを挿入するのは難しいようですが、きちんとモジュール化されているものであれば、十分に役割を果たせそうです。
存在を知らなかったので、大変勉強になりました。ありがとうございました。

お礼日時:2014/05/15 01:27

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

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

このQ&Aを見た人はこんなQ&Aも見ています

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

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

Qjavaでunsignedは使えないのですか?

Eclipseを使い始めた初心者です。
short型変数を符号無しで宣言しようと思ったのですが、
赤の下線が出てしまってエラーの扱いになってしまっています。

javaではunsignedは使えないのでしょうか?
使えないのであれば、その理由と対処策を教えていただけましたら嬉しいです。
宜しくお願い致します。

Aベストアンサー

unsigned short などのような構文はありませんが、とりあえず負の値を使いたくないのなら char型を数値のように使えばよろしいかと思います。
char型のとりうる範囲は0~65535で、範囲外の数値はint型とみなされます(数値を直接代入する場合のみ)。
ただし負のintをcharにキャストすると上位ビットが欠落します。

char c;
c = 0;
c = 65535;
c = 65536; ←コンパイルエラー
c = -1; ←コンパイルエラー
c = (char)-1; ←コンパイルエラーにはならないが65535になる

QJavaには、構造体はないんですか?

 C言語の構造体みたいなのはないんですか?

野球のデータを扱っているのですが、構造体がないのでできません。

打率の順位をソートしたいのですが、Cでは構造体でソートすれば選手名まで全部ソートできたのですが。。。

Javaでは、いちいち選手名、打率などの配列を作っているのですが、打率をソートしてから選手名と一緒に表示しようとしても打率の配列だけ、ソートしてあり選手名の配列と打率の配列があいません。

要するに、打率の配列はソートし、選手の配列はデータを入力したときのままなので、順番が違っているのです。

うまい方法を教えてください。初歩的な質問でごめんなさい。

Aベストアンサー

メンバーが public なクラスが構造体と(ほぼ)同じです。

大体こんな感じ。

// sort Object using Arrays.sort()

import java.util.Arrays;

class Batter implements Comparable {
 public double rate;
 public String name;
 Batter(double r, String n) {
  rate = r;
  name = n;
 }
 public int compareTo(Object o) {
  return (int)((rate - ((Batter)o).rate)*1000.);
 }
}

class w03 {
 public static void main(String[] args) {
  Object[] batter = {
   new Batter(0.3, "ichiro"),
   new Batter(0.1, "shinjo"),
   new Batter(0.0, "irabu")
  };

  // sort
  Arrays.sort(batter);

  // print-out to console
  for (int i=0; i < batter.length; i++) {
   Batter b = (Batter)batter[i];
   System.out.println(b.name + " " + Double.toString(b.rate));
  }
 }
}

このように java.util.Arrays の sort() メソッドを使うと、C でやってた
イメージに近くなります。

C の qsort() と違って、どんなデータでもソートできるわけではなく、対象と
なるクラスは Comparable インターフェースを実装しなくてはいけません。

メンバーが public なクラスが構造体と(ほぼ)同じです。

大体こんな感じ。

// sort Object using Arrays.sort()

import java.util.Arrays;

class Batter implements Comparable {
 public double rate;
 public String name;
 Batter(double r, String n) {
  rate = r;
  name = n;
 }
 public int compareTo(Object o) {
  return (int)((rate - ((Batter)o).rate)*1000.);
 }
}

class w03 {
 public static void main(String[] args) {
  Object[] batter = {
...続きを読む

Qinterface,extend,implementのちがい

お世話になります、

Javaを勉強しているのですが、
interface,extend,implementの使い分けがわかりません。

私の解釈としては、
(1)interfaceは、グローバル変数の定義、グローバルメソッドの定義(実装はしない)。

(2)extendは、extendクラスを親クラスとして親クラスの機能を使用できる。

(3)implementは…,implementもextendと同じような意味だと解釈しているんですが、違う点は、implementで定義してあるメソッドは、使用しなくても、実装しなければならないという点でしょうか?

とにかくこの3つのを使い分けるコツとかあれば教えてください。
よろしくお願いします。

Aベストアンサー

バラバラに理解してもしょうがないッス。

まず、
(1)interface と implements
(2)class と extends

が対応しているわけっす。

JavaはC++と違って、比較的言語仕様を「簡単」にしたので「多重継承」という
概念がないです。
多重継承っていうのは、複数のクラスを親クラスにして継承するってことですね。

たとえば、 「TextFieldクラス」と「Japaneseクラス」を多重継承すると、
「JTextFieldクラス」ができるっていうのが自然な考え方でしょう?

まぁ、例えば、日本語クラスであれば、getStringLength()メソッドなどが
あったほうが良いでしょうか。
このgetStringLength()メソッドは、2バイト文字も1バイト文字も「1文字」
と数えてくれると言う点で、まさに、日本語クラス用のメソッドだと言えるでしょう。

例えば、Java的に記述すると、、、
class Japanese {
public int getStringLength() {
  ・・・
return strlength;
 }
 ・・・
}

class TextField {
・・・
}

class JTextField extends TextField, extends Japanese {
・・・・
}

C++ではそのように実装するでしょう。
しかし、Javaにはこのような高度な機能はありません。

そこで、生まれた苦肉の策が、「interfaceとimplements」です。

interface Japanese {
public int getStringLength(); // interfaceは実装を含まない!
                 // すなわち「実装の継承」ができるわけではない。
}

class TextField {
・・・
}

class JTextField extends TextField implements Japanese {
・・・・
public int getStringLength() {
  ・・・
return strlength; //implementsの実装を「各クラスで」実装してやる必要がある。
 }
}


結局のところ、Javaでは、複数のクラスを親クラスには持ち得ないため、継承できなかったクラスは「各クラスで実装してやる必要性」があるのです。


ではどのように使うのが効果的か?

なまえのままです。「代表的なインターフェイス」にたいしてinterfaceを使うのが良いと思います。

例えば、プレイヤー系であれば、ビデオ・コンポ・ウォークマン・などにかかわらず、
interface controlpanel {
public play();
public stop();
public next();
public back();
}
というような基本的インターフェイスを「持っているべき」です。

こうすることで、それぞれのクラス宣言の際に、これらの「インターフェイスを持っているべきであり、実装されるべきである」ということを「強く暗示」することができます。
class videoplayer extends player implements controlpanel {
public play() {・・・}
public stop() {・・・}
public next() {・・・}
public back() {・・・}
}

こうすることで、同様のクラスを作成するユーザーは、
「プレイヤー系は、4つ操作が出来るコントロールパネルをインターフェイスとして持つべきなのだな!?」という暗示を受け取り、自分のクラスでもそれを模倣するでしょう。

class mp3player extends player implements controlpanel {
public play() {・・・}
public stop() {・・・}
public next() {・・・}
public back() {・・・}
}

また、これらのクラスを使用するユーザーも、「implements controlpanel」という
表記を見て、「4つの基本操作は押さえられているのだな!」という基本中の基本動作を抑えることが出来ます。

まとめると、クラスに「こういう特徴もたしてください!」「こういう特徴持ってますよ!」という一種の暗示的警告や方向性を与えることができるわけですね。

バラバラに理解してもしょうがないッス。

まず、
(1)interface と implements
(2)class と extends

が対応しているわけっす。

JavaはC++と違って、比較的言語仕様を「簡単」にしたので「多重継承」という
概念がないです。
多重継承っていうのは、複数のクラスを親クラスにして継承するってことですね。

たとえば、 「TextFieldクラス」と「Japaneseクラス」を多重継承すると、
「JTextFieldクラス」ができるっていうのが自然な考え方でしょう?

まぁ、例えば、日本語クラスであれば...続きを読む

Qjavaでの#if 0 #endif文

javaでC言語のような一部分のプログラムのコメントアウトとしての機能の#if 0に当たるコードはどのように書いたら良いでしょうか?

どうぞ、教えて頂きますようお願い致します。

Aベストアンサー

コメントアウト

QJAVA  ArrayListからArrayListへのコピー

java で、ArrayListからArrayListへコピーはできるのでしょうか?
clone()というメソッドがありましたが、よくわからず、コピーできてないようなので伺いました。

ベーシックではできるようですが、JAVAでもできるのでしょうか?
どなたか教えていただけませんでしょうか?

Aベストアンサー

ArrayList li = new ArrayList(list);
でよいでのでは?

QJavaでポインタ的なことはできるか?

JavaでC言語のようにポインタを使おうとしたらJavaには
ポインタが表面上はサポートされていないことを知りました。

関数を呼び出した際に、呼び出し元の変数に影響を与えるようなプログラムは
Javaで作れるのでしょうか?
例えば、以下のプログラムはCで関数を呼び出した際に呼び出し元の
変数の中身を関数内で書き換えてしまうプログラムです。
こういうことをJavaでするにはどう書けばよいのでしょうか?
もしこういうことができないのであれば、Javaにはポインタに代わるやりかたがあるのでしょうか?

実行結果:
1 10

#include <stdio.h>

void func( int *n ){
  *n = 10;
}

int main(){
  int n = 1;
  printf("%d ", n );
  func( &n );
  printf("%d ", n );
}

Aベストアンサー

質問のコードを書き直すと
private void func(Integer n){
  n = 10;
}

public static void main(String[] args){
  Integer n = 1;
  System.out.printf("%d ", n );
  func( n );
  System.out.printf("%d ", n );
}

Javaのプリミティブ型にはそれぞれをラップした型があります。
int Integer
long Long
short Short
double Double
float Float
byte Byte
char Character
boolean Boolean

Q生成したインスタンスを削除する方法

言語:JAVA

生成したインスタンスを削除するにはどのようにすれば良いでしょうか?

testData = new TestData();

testDataはセッション内に格納してあります。
また、testDataはNULLのままだったり、実際に値が入っていたりもします。

NULLのままだと不具合があるため、NULLの場合は、インスタンスそのものを削除してしまいたいと考えています。
初歩的な質問ですみませんが、教えてください。

よろしくお願いいたします。

Aベストアンサー

浅学なため、TestDataというクラス名と「セッション内に格納」という表現だけからどうしてHttpSessionが出てくるのか分かりませんが...

Javaでは、明示的な操作(C++のdeleteのような)によってインスタンスを削除することはできません。そのインスタンスがどこからも参照されなくなったらGCで消えます。もう要らない(消えてほしい)インスタンスを参照している変数やフィールドにはnullを代入することで参照をなくします。

testData = null;

> NULLのままだと不具合があるため、NULLの場合は、インスタンスそのものを削除してしまいたい

何がNULLだとどのように不都合なのかを説明してもらえると、別の回答がつくかもしれません。

Q「いずれか」と「いづれか」どっちが正しい!?

教えて下さいっ!
”どちらか”と言う意味の「いずれか」のかな表記として
「いずれか」と「いづれか」のどちらが正しいのでしょう???

私は「いずれか」だと思うんですが、辞書に「いずれか・いづ--。」と書いてあり、???になってしまいました。
どちらでもいいってことでしょうか?

Aベストアンサー

「いずれか」が正しいです.
「いづれ」は「いずれ」の歴史的かな遣いですので,昔は「いづれ」が使われていましたが,現代では「いずれ」で統一することになっていますので,「いずれ」が正しいです.

Qequalsの逆

javaで、文字列の場合は比較演算子の「==」は用いずに

if ((str1.getText()).equals(str2)){
(※…str1,2は文字列)

と書きますよね?
この逆で、文字列str1とstr2は等しくないとき、にはif以下の条件文をどのように書けばよいでしょうか?

Aベストアンサー

>if !((str1.getText()).equals(str2)){

あくまで
if(){
}


!(str1.getText()).equals(str2)
が入っているので
if !((str1.getText()).equals(str2)){
じゃなくて
if (!(str1.getText()).equals(str2)){
こう。

Qflush()とclose()について

Javaを独習Javaで独習しています。現在、入出力の所まできたのですが、Writerクラスのclose()とflush()の違いがわかりません。それぞれのメソッドの意味はわかるのですがそれらを使う目的がわかりません。flush()は「バッファ付けデータをそのストリームで表されている物理デバイスに書き込む」とあるのですが、サンプルには(バッファ付け文字ストリームの単元にも)flush()は一度も出てこずclose()のみで書き込みが行われています。探したのですが独習Javaのサンプルの中には結局flush()は一度も出てきませんでした。この二つの違いはなんなのでしょうか?初心者のためわかりにくい質問かとは思いますがよろしくお願いします。

Aベストアンサー

フラッシュすれば、ファイルやその他物理デバイスに強制的にバッファの内容が出力されるということは、理解されていると考えてよいですね?

で、なかなかストリームをクローズできない(またはしない)場合には、いつまで経ってもバッファの内容が物理デバイスに出力されないかも知れませんよね?でも、適当なタイミングで定期的にフラッシュすれば、その時点でバッファに溜まっている内容が物理デバイスに出力されます。

そのサンプルの場合は、書き出してすぐ?クローズしちゃうため、明示的なフラッシュは必要なかったんだと思いますが、

・フラッシュは、(ストリームを閉じずに)バッファの内容を強制的に物理デバイスに出力する。
・クローズは、(フラッシュされていなければフラッシュしてから)そのストリームを閉じる。

とまぁ、目的も内容も全然違うわけです。


人気Q&Aランキング

おすすめ情報