stack overflowで(a ==1 && a== 2 && a==3)を常にtrueにできるかという記事が流行っています。
元ネタはjavascriptの問題ですが、Periで同様の問題をやっている記事を見かけので、私も流行に乗るべく記事を投稿します。
現在、業務で主にJavaを使用しているのですが、そこでJavaならどうやってできるか考えました。
流石にQiitaのどこかに上がってるでしょ~って気分で色々漁りましたが、(a==1&&a==2&&a==3)を常にtrueにするStackOverflowの問題を解いたQiita記事まとめを見る限りでは無さそうでした。
じゃあ見つければ一番乗りでは? と思い、試行錯誤して玉砕した結果がこれです。
考えられる解法
解法はいろいろあるようです。一例としては、こんな感じ。
-
==
演算子のオーバーロードによって全ての真偽値判定を真にする - aを関数にして、呼ばれる度にaの戻り値を変更する
- aをオブジェクトにして(以下略)
参考:((a == 1 && a == 2 && a == 3) を常に真にできますか?)
とりあえずこれだけ試行しました。
Javaはコーディング制約が厳しいというか、他の言語ではできるような書き方の省略を許していなかったり、他の言語にある機能を実装していなかったりすることが多いので、基本的にうまくいきませんね。
==
演算子のオーバーロード
Javaには演算子のオーバーロードなんて高度な機能は実装されていません。
C++やPerlにはあるのに。
aを関数にする
public class Main {
static int i = 1;
public static void main(String[] args) {
System.out.println(a() == 1 && a() == 2 && a() == 3);
//trueが表示される
}
static int a() {
return i++;
}
}
Javaに「引数の無い関数は()を省略してもよい」みたいな機能があればできました。多分これが一番惜しいと思います。
aをオブジェクトにする
そもそもオブジェクトとプリミティブ型を比較することができないと怒られてしまいます。
Object a = 1;
System.out.println(a == 1 && a == 2 && a == 3); //コンパイルエラー
オブジェクト内のフィールドやメソッドを呼ぼうにも、結局はa.number
やa.getint()
のように書かなければならないため、ダメです。
オブジェクトをそのまま呼んでも勝手に型変換してくれる都合の良いクラスはあるにはあります。ラッパークラスです。
Integer a = 1;
System.out.println(a == 1); //内部的にはa.intValue() == 1になる
じゃあこれを継承したクラスを作ってintValue()
を弄ればいいじゃん! と思ったら、finalクラスで継承できませんでした。そりゃそうですよねー。
「関数インタフェースを使用した場合、引数が無いときは()を省略してもよい」みたいなルールでもできませんかね。
結論
Javaでは(a == 1 && a == 2 && a == 3)を常にtrueにするのは不可能説。
解法を知ってる方は是非教えてください。。。
追記
ちゃんと調べればありました。先人の皆様、すみませんでした。
Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい
Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい(黒魔術編)
Javaでif (a == 1 && a == 2 && a == 3)でtrueを出力(見えない識別子編)
Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい(PowerMockito編)
Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい(真っ黒編)
PowerMockito使えばIntegerを無理矢理継承できたんですね。