20220110のJavaに関する記事は15件です。

【OOP】01_オブジェクト・クラス・インスタンス

こんにちは、コイキングです。 本記事では OOP(Object Oriented Programming == オブジェクト指向プログラミング)の説明のうち、オブジェクト・クラス・インスタンスについて、説明したいと思います。 1. オブジェクトとは? まず一般的なオブジェクトの概念について探してみると**現実世界に存在する'物体'、'対象'になります。 ※ 参考 https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88 具体的に例えてみると人間・犬のような動物も、スマートフォン・PC・箱のような物も、ポケモン・デジモンのようなゲームのキャラクターもオブジェクトと言えると思います。 ではOOPでのオブジェクトは何でしょう? 私は現実世界のオブジェクトから重要で核心的な所を抽象化してクラス化し、クラスを元にしてメモリー上にロードされたデータだと思います。 オブジェクト指向では上記の説明通りメモリー上にロードされたオブジェクトの相互作用を通してプログラムを実装します。 2. クラスとは? クラスは'OOPのオブジェクトを作るための一種の設計図'です。 クラスを作るためには現実世界のオブジェクトから重要で核心的なもの・共通点・特徴などを洗出し、1) 属性と 2)行為に定義します。 こちらで属性はクラスのメンバー変数、行為はクラスのメソッドになります。 ※ クラスの宣言文法 [アクセス制御子] class クラス名 { //...メンバー変数・メソッド } Person.java public class Person { // メンバー変数 String eye; String nose; String mouth; String hand; String foot; // メソッド public void eat() { System.out.println("eat"); } public void sleep() { System.out.println("sleep"); } public void defecate() { System.out.println("defecate"); } } 上記のPersonクラスは人間をクラス化したものです。 人間がもつ目・鼻・口・手足などの属性はメンバー変数に 食べる・寝る・トイレに行くなどの行為をメソッド化しました。 3. インスタンスとは? インスタンスとはクラスを元にしてメモリー上にロードされたデータを意味します。 OOPで言っているオブジェクトと言えます。 コードを解析する際に'オブジェクト'という単語と'インスタンス'という単語を同じ意味でよく混用して使ったりします。 ※ インスタンスを作る方法は以下となります。 [クラス名] [インスタンス変数名] = new [コンストラクター()]; ※ インスタンスのメソッド及びメンバー変数の値にアクセスする方法は以下となります。 [インスタンス変数名].[メソッド() 又は メンバー変数]; public static void main(String[] args) { Person person = new Person(); person.eat(); String eye = person.eye; System.out.println(eye); } ※ 例示コード https://github.com/leeyoungseung/algorithmBasic/blob/master/algorithm/src/objective/basic01/Person.java ※ 韓国語のポストは以下のURLで確認できます。 https://koiking.tistory.com/87
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Android開発におけるドキュメント作成ツール"Dokka / KDoc"について

Dokkaとは "KDoc"形式で記載したコメントを、Javadocと同様な形でドキュメントを作成できる。 JavaとKotlinが混在したプロジェクトのドキュメントも生成可能 導入 project/build.gradle buildscript { ext { dokka_version = "1.6.10" } dependencies { classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}" } app/build.gradle apply plugin: "org.jetbrains.dokka" android {} dependencies {} // dokkaHtml 用の設定 dokkaHtml.configure { outputDirectory.set(new File("${buildDir}/dokkaHtml")) dokkaSourceSets { configureEach { // Moduleやパッケージに対するドキュメントを作成する際に指定する includes.from("ModuleDoc.md", "PackageDoc.md") } } } app/ModuleDoc.md # Module app ## パッケージ構成について | Package | Contents | | ---- | ---- | | view | view / ViewModel | | domain | logic / service | | model | Data model | | repository | Repository | | infra.api | Remote Resource | | infra.db | Local DB | | infra.local | Local Resource | app/PackageDoc.md #Package jp.co.foxsal.githubreader.view.repolist リポジトリ一覧 #Package jp.co.foxsal.githubreader.view.repodetail リポジトリ詳細 ドキュメント生成 ./gradlew dokkaHtml または ./gradlew dokkaJavadoc 成果物イメージ dokkaHtml dokkaJavadoc 参考リンク KDoc dokkaHtmlのオプション設定
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Android開発におけるドキュメント作成"Dokka / KDoc"の導入手順

Dokkaとは "KDoc"形式で記載したコメントを、Javadocと同様な形でドキュメントを作成できる。 JavaとKotlinが混在したプロジェクトのドキュメントも生成可能 導入 project/build.gradle buildscript { ext { dokka_version = "1.6.10" } dependencies { classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}" } app/build.gradle apply plugin: "org.jetbrains.dokka" android {} dependencies {} // dokkaHtml 用の設定 dokkaHtml.configure { outputDirectory.set(new File("${buildDir}/dokkaHtml")) dokkaSourceSets { configureEach { // Moduleやパッケージに対するドキュメントを作成する際に指定する includes.from("ModuleDoc.md", "PackageDoc.md") } } } モジュールコメント ここで全体的なパッケージ構成を書いておくと理解が進みそう app/ModuleDoc.md # Module app ## パッケージ構成について | Package | Contents | | ---- | ---- | | view | view | | viewmodel | ViewModel | | domain | logic / service | | model | Data model | | repository | Repository | | infra.api | Remote Resource | | infra.db | Local DB | | infra.local | Local Resource | パッケージコメント パッケージに対するコメント app/PackageDoc.md #Package jp.co.foxsal.githubreader.view.repolist リポジトリ一覧 #Package jp.co.foxsal.githubreader.view.repodetail リポジトリ詳細 クラス/メソッド等のコメント KDoc形式で各所に記載する ドキュメント生成 ./gradlew dokkaHtml または ./gradlew dokkaJavadoc 成果物イメージ dokkaHtml dokkaJavadoc 参考リンク KDoc dokkaHtmlのオプション設定
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Java Gold SE 11に合格しました【正答率85%】

先日Java Goldを受験し、見事合格しましたのでその経緯をまとめたいと思います。 Java Gold試験概要 まず簡単な試験概要です。 ・試験名:Java SE 11 Programmer II Pearson VUEで試験の申込みをする時に「Java Gold」だと検索に引っかからないので注意です。 ・試験時間:180分 一般的なベンダ試験の試験時間だと思います。普通に解いていれば180分丸々問題に費やすことはないと思います。 ・出題数:80問 ・合格ライン:63% ベンダ試験の上位資格にしてはかなり合格ラインは低いな、という印象でした。なので20問くらい間違えてもいいかぁくらいの気楽な気持ちで取り組みました。 ・受験要件:Java Silverを取得済みであること 自身の背景 まず今回Java Goldを受験するにあたり、自身の経歴について記載します。 Javaの経験 大学時代と社会人1年目で少し触れて、Java Bronzeは取得。しかしその後は業務等で使う機会は全くなく、内容はほとんど忘れてしまった。昨年6月にJavaを使う部署へと異動し、猛勉強を開始。昨年8月にはJava Silverを取得(Goldの受験要件)。Pythonは独学でも少しやっていたのでプログラミングに対する抵抗はあまりなかったです。 その他スキル ・AWSソリューションアーキテクト プロフェッショナルを含む、AWS資格5冠  ・ソリューションアーキテクト(アソシエイト、プロフェッショナル)  ・SysOpsアドミニストレーター(アソシエイト)  ・デベロッパー(アソシエイト)  ・クラウドプラクティショナー  11冠を目指してその他資格についても学習中 ・その他:基本情報処理技術者、第一級陸上特殊無線技士 学習方法について 基本的に下記書籍を使って学習しました。いずれもSE8のものも販売されていますが、ご自身が受けるバージョンと差異がないことを確認してください。SE8とSE11ではかなり出題範囲が異なります。 ・徹底攻略Java SE 11 Gold問題集 通称黒本。後述しますが、試験対策としてはぜひ読みたい一冊です。Silverのときもお世話になりました。下記流れで学習に取り組みました。 1周目 1章から順番に問題を解いていく。その際、正否に関わらず解説は一通り読み込む。ただし、並列処理の章だけは一旦飛ばして、模擬試験の章の前に取り組みました。また、間違えた問題についてはチェックを付けています。 模擬試験の正答率は約50%。 2周目 もう一度、今度は並列処理も含めて1章から問題を解いていく。間違えた問題についてはチェックをつけるが、この時にチェックが付かなかった問題については解説をスキップした。 模擬試験の正答率は約60%。 3週目 チェックが一つ以上ついている問題を解き直す。正解したら特に解説は読まない。間違えたらその問題が書いてあるページに折り目をつけてあとから振り返りができるようにした。 模擬試験の正答率は85%。 4週目 通常、3周くらいすれば大抵の資格は取れる自信が出てくるのですが、あと一歩足りないなと感じていました。なので、チェックが付いている問題(模擬試験も含め)だけ最後に取り組みました。 ・オラクル認定資格教科書 Javaプログラマ Gold SE11 通称紫本。The教科書でした。Java Goldの学習を始めたのが9月頭だったのですが、先述の黒本がまだ発売していなかったため、先にこちらを購入して学習をしていました。情報量としては書籍の中で一番多いと思います。それ故、飽きやすさが若干出てしまったため、1週は読みましたが、練習問題・模擬試験は2週しかしていません。読み物が好きな人はこの一冊だけでも合格できるかもしれません。 ・オラクル認定資格教科書 Javaプログラマ Gold SE11 スピードマスター問題集 通称白本。試験前最後の1週間で総仕上げとして解きました。掲載されている問題としてはこの本が一番実試験に近かったと思います。1周目は全問題を解き、2周めは間違えた問題だけ解きました。問題の質は素晴らしいのですが、問題集としては致命的な誤植が多数あります(答えが違うとか・・・)。ですので、その誤植に気づけるくらいの一定の知識は必要なので、これ一冊だけで合格はなかなか難しいと思います。 それぞれの本の難易度・特徴をまとめると下記のようになります。 難易度 良い点 悪い点 黒本 易〜中 Java Goldの取っ掛かりとしては一番取り組みやすい 合格に必要な知識量としてはこれだけだと若干不安 紫本 中〜難 合格に必要な知識量はこれで最も習得可能 文字量が多いため学習の意欲は下がりやすい 白本 易〜中 掲載されている問題は一番実戦向き 誤植が多いため正誤表を参照しながら取り組む必要がある 試験当日 試験当日はテストセンターで受験しました。何回か受験している場所で、流れもいつもどおりなので特に緊張することなく試験に臨みました。試験時間は180分ですが、判断に迷った問題にはチェックを入れつつ、合計90分で80問を解きました。その後20分ほどで問題を振り返り、試験を終了しました。直後に正答率と合否が出てくるのでボタンを押す瞬間は緊張しました。 余談ですが、試験日については予めこの日に受ける!と宣言するような形で、先に予約すると良いかと思います。ダラダラ勉強しなくなります。 試験で注意すべきこと・テクニック コレクションの型に注目 こんな感じのやつです。 List<Integer> list = new ArrayList<>(); <>の中身を意識して、何型の変数であるかがカギです。特に、 List list = new ArrayList<>(); のように、<>の中身がない場合はObject型であるため注意が必要です。 あとは、superやextendsを利用した宣言にも注意が必要です。 List<? super Integer> list = new ArrayList<Number>(); // OK List<? extends Number> list = new ArrayList<Integer>(); // OK List<? extends Number> list = new ArrayList<Object>(); // コンパイルエラー アクセス修飾子に注目 オーバライドすると、子クラスのアクセス修飾子は親と同じか、より広い範囲のアクセス修飾子にしなければなりません。特にinterfaceの継承時は、抽象メソッドに暗黙のpublicがないか注意してください。 Func1.java public interface Func1 { boolean call(int x); } Main.java public class Main implements Func1 { public static void main(String[] args) { } boolean call(int x) { // publicで修飾しないといけないためコンパイルエラー return false; } } 試験当日は体調を良くして取り組む これが一番大切だと思います。夜ふかしは厳禁です。 その他おすすめ書籍 試験対策以外では下記書籍がおすすめです。 ・スッキリわかるJava入門 実践編 第3版 単純に試験対策ではなく、業務に役立つ内容が多めです。この中にもJava Goldで出てくる内容があるため、いきなり試験対策に抵抗があればこちらの本もおすすめです。 さいごに 勉強時間は3ヶ月で90時間程度(1日1時間目標)だったと思います。SilverのスキルがあってもGoldは範囲が広いということもあり、かなりの勉強時間が必要でした。わからないところは分かるまで勉強する、の意識のもと努力した甲斐がありました。 この資格を取って終わりではなく、業務に活かして使えなければ意味がありません。あくまでスタート地点に立てたということを意識して今後も様々な勉強に取り組みたいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javaデベロッパが知るべきDockerセキュリティ5つの大切なこと

セキュリティのシフトレフトを考えると、開発段階から考えるということが重要ということはわかってはいても、どう実践すれば良いものか、、、 わかってはいつつ、なんとなく不安になりつつも、忙しく作業に没頭せざるをえないJavaデベロッパの方も多いのではないでしょうか。 今回はJavaデベロッパ向けDockerのセキュリティの短めの記事のご紹介です。 参考資料: JavaデベロッパのためのDocker:セキュリティを失敗させないために知っておくべき5つのこと(原文) Docker for Java developers: How not to fail your security(動画) JavaデベロッパのためのDocker:セキュリティを失敗させないために知っておくべき5つのこと Brian Vermeer ブライアンフェルメール 2020年11月20日 Dockerは、アプリケーションをコンテナ化するために最も広く使用されている方法です。Docker Hubを使えば、事前に作っておいたイメージを簡単に作成したりプルできます。Docker Hubにあるイメージを使用して、Javaアプリケーションのイメージをすばやく構築できるため、これは非常に便利です。ただし、Javaアプリケーション用のカスタムDockerイメージを作成する単純な方法には、多くのセキュリティ上の懸念が伴います。では、JavaデベロッパにとってセキュリティをDockerの必須要素にするにはどうすればよいでしょうか。 アプリケーション用の優れたDockerJavaイメージを作成する方法を説明する前に、このトピックに関するよくある質問をいくつか見てみましょう。 JavaアプリケーションをDocker化するには? JavaアプリケーションをDockerコンテナで実行するには、.jarまたは.warファイルをJREベースイメージにコピーするだけですが、その際にはいくつか注意すべき点があります。適切なJVM引数を選択し、コンテナのランタイム設定を一致させることは、対策の半分にすぎません。選択によっては、脆弱性があるため、どのベースイメージを使用するかは、セキュリティの観点から非常に重要です。 この記事は、ベースイメージの選択による影響をより深く理解するための情報を提供し、アプリケーションに利用可能な最も安全なイメージを見つけるためのガイドです。 JavaデベロッパにとってDockerはどのように役立ちますか? Javaアプリケーションをコンテナにパッケージ化することで、JRE、構成設定、OSレベルの依存関係、ビルドアーティファクトを含む完全なアプリケーションをコンテナイメージと呼ばれる自己完結型のデプロイ可能なアーティファクトに定義することができます。これらのイメージはソフトウェアで定義されており、作成に完全な再現性があり、開発者はすべての環境で同じプラットフォームを実行することができます。さらに、コンテナを利用することで、開発者は特別な権限を必要とせずに、デスクトップ上で新しいプラットフォームのリリースやその他の変更を簡単に試すことができます。 Javaアプリケーションに適したDockerベースイメージの選択 Dockerイメージを作成する際には、DockerHubから取得したいくつかのイメージをベースにしてイメージを作成します。これをベースイメージと呼びます。ベースイメージは、Javaアプリケーションのビルドに関する新しいイメージの基盤です。ベースイメージを選択することで、そのイメージで利用可能なすべてのものを利用することができるため、ベースイメージは不可欠です。ただし、これには代償が伴います。ベースイメージに脆弱性がある場合、新しく作成するイメージにもそれが引き継がれてしまうのです。 ベースイメージを見てみると、脆弱性の多くは、このベースイメージが使用するオペレーティングシステム(OS)レイヤーの一部です。2019年の以前の調査Dockerセキュリティのシフトレフトでは、OSレイヤーによってもたらされる脆弱性は、何を選択しているかによって大きく変わる可能性があることが示されています。 2019年のレポート–Dockerセキュリティのシフトレフト AdoptopenjdkのDockerJavaベースイメージの人気セット、openjdk11を見てみましょう。デフォルトタグを使用すると、このイメージはubuntuディストリビューションの上に構築されます。ただし、たとえばDebian、Centos、Alpineをベースにした特定のバージョンのタグを選択することもできます(注意:Alpineはglibcベースではないため、ネイティブのJNIコールを行うアプリケーションとの互換性がない可能性があります)。 正しいベースイメージを選択することは、セキュリティの観点から非常に重要であると結論づけることができます。おそらく、完全なオペレーティングシステムに付属するすべてのバイナリは必要ないでしょう。最アプリケーション用に新しいDocker Javaイメージを構築するには、最小限のベースイメージをベースにすることをお勧めします。持っていないバイナリが害を及ぼすことはできません。 セキュリティの面に加えて、最小限のベースイメージは、新しく作成するイメージのサイズを小さくします。Dockerイメージが小さければ、フットプリントも小さくなり、おそらく起動時間も速くなるでしょう。もう1つの考慮できる事項として、Dockerfileを必要としない最小限のJavaイメージを作成するjibでビルドすることも考えられます。 JDKではなくJREを使用する Dockerイメージを作成する際には、正しく機能するために必要なリソースのみを割り当てるべきです。つまり、本番イメージは、完全なJava Development Kit (JDK)ではなく、適切なJava Runtime Environment (JRE)を使用することから始める必要があります。さらに、本番イメージにはMavenやGradleなどのビルドシステムを含めべきではありません。ビルドの成果物、たとえばjarファイルがあれば十分です。 Dockerコンテナ内でアプリケーションをビルドする場合でも、マルチステージビルドを使用して、ビルドイメージを本番イメージから簡単に分離できます。 例: java-code-workshopアプリケーション用にDockerJavaイメージを作成したいと思います。これはmavenで構築されたspring-bootベースのアプリケーションで、Javaバージョン8を必要とします。 このDockerJavaイメージを作成する単純な方法は、次のようなものです。 mavenとopenjdk8を含むベースイメージを選択し、そのイメージにソースをコピーし、mavenを呼び出してアプリケーションをビルドして実行します。この例は全く問題なく動作します。アプリケーションは起動し、スムーズに動作します。しかし、先ほど作成したDockerイメージのサイズが631MBになっています。 このDockerfileを変更して、マルチステージビルドを使用してみましょう。 ここで何が起こっているのかというと、プロジェクトのビルドにmaven-openjdk8のイメージを使用しているということです。しかし、これはアウトプットではありません。かなり小さいjava 8 JREイメージをベースにした新しいイメージを作成し、実行可能なspring-boot jarだけをコピーします。あとは、そのjar-file、を実行するだけで完了です。その結果、JDKやmavenを含まない、JREのみのDockerイメージが作成されます。イメージサイズは132MBと劇的に小さくなりました。 イメージ小さいほど、アップロードが簡単で起動時間を短縮できるだけでなく、より安全です。もし何らかの理由で、JDK、ソースコード、ビルドツールが入った稼働中のコンテナに攻撃者がアクセスしたらどうなるか想像できますか? プライベートリポジトリにアクセスするためのシークレットを含める必要がある場合にも、これを使用できます。これらの種類のシークレットを本番用イメージのキャッシュに入れたくありません。本番環境ではビルドイメージを使用しないため、シークレットを使用してもまったく問題ありません。このテクニックを使えば、他のイメージから必要なものをチェリーピックして、必要なリソースだけを持つ製品Dockerイメージを作ることができます。 Dockerコンテナをrootで実行しない Dockerコンテナを作成する際、デフォルトではrootとして実行されます。これは開発時には便利ですが、本番用のイメージではこのようなことは避ける必要があります。何らかの理由で、攻撃者が端末にアクセスできたり、コードを実行できたとします。その場合、実行中のコンテナに対して重要な権限を持っているだけでなく、不適切に高いアクセス権でファイルシステムバインドマウントを介してホストファイルシステムにアクセスできる可能性があります。 これを防ぐための最も簡単な方法は、以下のように特定のユーザーを作成することです。 3行目では、新しいグループを作成し、ユーザーを追加しています。このユーザーは、パスワードとホームディレクトリを持たないシステムユーザー(-r)です。また、新しく作成したグループにも追加しています。 次に6行目で、このユーザーにアプリケーションフォルダへのアクセス権を与えています。7行目も忘れないでください。ここでは、使用したいユーザーを設定しています。こうすることで、新しく作成された制限付きユーザーが最後の行のコマンドを実行します。 開発中のDockerイメージとJavaアプリケーションのスキャン DockerfileからDockerイメージを作成し、イメージを再構築することでさえ、システムに新しい脆弱性をもたらす可能性があります。開発中のDockerイメージをスキャンすることは、脆弱性を可能な限り早期に発見するためのワークフローの一部であるべきです。 Snyk CLIを使えば、Dockerイメージを簡単にスキャンできます。ローカルマシンでも、パイプラインの一部として、またはその両方で使えます。Snyk CLIをインストールして認証した後イメージをスキャンするためにしなければならないことはただ一つです。 $ snykコンテナテスト 最初のセクションで説明したように adoptopenjdkのイメージをスキャンしたい場合、コマンドは次のようになります。 $ docker pull adoptopenjdk/opendjdk11:latest $ snyk container test adoptopenjdk/opendjdk11:latest アウトプット: Docker イメージのテストとモニタリングの両方が可能です。モニタリングには snyk container monitor <image> を使用します。モニタリングでは、スナップショットを取り、時間の経過とともにイメージに新しい脆弱性や修正プログラムが利用できるかどうかを監視します。 イメージをスキャンしてDockerfile(新しいDocker Javaイメージを作成)がある場合は、フラグ--Dockerfile=<dockerfile>をsnyk container testかsnyk container monitor`のいずれかに追加する必要があります。これで、より適切な修復アドバイスが得られます。たとえば、利用可能な脆弱性の数を減らす利用可能なベースイメージがある場合、それを知ることができます。 例: $ snyk container test myImage:mytag --Dockerfile=path/Dockerfile $ snyk container monitor myImage:mytag --Dockerfile=path/Dockerfile Javaアプリケーションのスキャン 構築しているDockerJavaイメージには、アプリケーションも含まれています。明らかに、これは攻撃のポイントとなり得ます。あなたのJavaアプリケーションにセキュリティ脆弱性がないことを確認する必要があり、JavaデベロッパのDocker環境において、最初の段階でセキュアな方法を採用したことになります。アプリケーションに、 あなたのアプリケーションが、REST エンドポイントを呼び出すときにリモートでコードの実行を可能にするライブラリを含んでいると想像してください。あなたのイメージの残りの部分に何の脆弱性もないとしても、これは悲惨な結果になる可能性があります。 Dockerイメージに挿入するJavaバイナリの大部分は、おそらくインポートするコードです。アプリケーションが持つライブラリとフレームワークは依存関係と考えることができます。Snyk CLIを使用で、依存関係を簡単に確認できます。これは、さきほどイメージをスキャンするために使用したものと同じCLIです。ルートフォルダでsnyk testまたはsnyk monitorを呼び出すと、ライブラリのセキュリティの脆弱性についてアプリケーションをスキャンまたは監視することができます。 自分が書いたコードには、コード分析ツールまたはSonarLint、PMD、spotbugsなどのリンターを使用することをお勧めします。これらのツールは、より優れたコードを作成するための汎用ツールですが、明らかなセキュリティミスを防ぐのにも役立ちます。 再構築するためのビルド Dockerイメージ用のJavaアプリケーションを、いつでも破棄して再構築できるようにビルドします。実行中のコンテナに問題があることに気付いたとしましょう。単にkillし(プロセス停止)し、新しいインスタンスを起動することができれば最高です。そのためには、データがコンテナの外部に格納されるように、ステートレスJavaアプリケーションを設計する必要があります。次のことが考えられます。 コンテナ内でデータベースのデータストアを実行しない。 コンテナ内にファイル(ログ)を保存しない。 自動回復のキャッシュを確認する(該当する場合)。 アプリケーションを破棄して、いつでも新しいインスタンスを起動できるようにビルドしている場合、Dockerイメージ全体も安全に再構築することができます。脆弱なDockerイメージの20%は、イメージを再構築するだけで、1つ以上のセキュリティ問題を修正できることをご存知ですか?Dockerイメージは、多くの場合、ベースイメージの「最新の」タグに基づいています。この「最新」は時間の経過とともに変化し、より新しく改良されたバージョンに置き換えられます。aptやyumなどのパッケージマネージャーを使用してコンテナーにインストールされたキーバイナリについても同様です。もちろん、最新バージョンを使用することは、最新のセキュリティ修正が自動的に適用されるため、セキュリティの観点からは良いことです。しかし、ベースイメージは時間の経過とともに変化し、結果として特定の時間のスナップショットでイメージを再現することが難しくなるということとのバランスを取る必要があります。 アプリケーションに変更がなかったとしても、定期的にDockerイメージを再構築し、場合によってはベースイメージのバージョンタグを新しくしたり、最新のものにしたりしてください。OSレイヤーのような基礎的なレイヤーの改善は、イメージの品質を向上させ、セキュリティの脆弱性を減らすことができます。 最後に、一般的な最適なDockerイメージまたはJavaアプリケーションを構築するためのセキュリティのベストプラクティスについて把握しておきたい方は、以下をご覧ください。 10 best practices to build a Java container with Docker<原文> - Javaアプリケーション用に安全でパフォーマンスの高いDockerイメージを構築する方法を、ステップバイステップで詳細に説明しています。 Javaセキュリティ・ベスト・プラクティス10<原文>→<翻訳記事coming soon> - あらゆる環境でJavaアプリケーションを構築する際に従うべきセキュリティ・プラクティスです。 Contents provided by: Jesse Casman, Fumiko Doi, Content Strategists for Snyk, Japan, and Randell Degges, Community Manager for Snyk Global
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java文法】例外処理

こんにちは、コイキングです。 本記事では'例外処理'について、説明したいと思います。 1. 例外処理とは? 例外処理はプログラムの実行中に予想されていない結果が発生した際の対応を言います。 例えるとコンソールからユーザー入力で'数字データ'を入力するべきものを'文字列データを入力してもらい'、文字列のデータを数字変数に代入しようとする場合 プログラムは例外を発生させます。 上記のような状況で 1) 例外発生の理由をログなどで知らせたり、2) 例外が発生した際に必要なロジックを実行することなどを例外処理で担います。 2. try-catch構文 try-catch構文は 例外が発生が予想されたり、必ず例外処理をしないといけないコード囲み例外を処理します。 例外発生が予想される所のコードをtry構文で囲んで、catch構文に例外を処理するロジックを記載します。 File file = new File("newFile.txt"); //file.createNewFile(); // ファイル作成時に例外処理をしないとコンパイルエラーが発生 try { file.createNewFile(); // 例外発生がよそされるところをtry構文に囲む } catch (Exception e) { e.printStackTrace(); } 3. メソッドにthrowsを宣言する メソッドにthrowsを宣言すると、メソッド内部では別途try-catch構文をセットする必要はありません。 しかし、メソッドにthrowsを宣言するだけで終わりません。 throws宣言の意味は例外処理をメソッドを呼出した所で行うという意味でメソッドを呼出した所でtry-catch構文を使い例外処理をする必要があります。 // メソッドにthrowsを付けると例外処理をメソッドの呼出した所で行える。 try { writeFile(file); } catch (Exception e) { e.printStackTrace(); } // 呼出した所で処理する例外の種類は複数セットできます。 // ex) throws IOException, Exception {... public static void writeFile(File file) throws IOException { List<String> list = new ArrayList<String>(); list.add("ArrayList-String01"); // Index 0 list.add("ArrayList-String02"); // Index 1 list.add("ArrayList-String03"); // Index 2 BufferedWriter wr = null; wr = new BufferedWriter(new FileWriter(file, true)); for (String var : list) { wr.append(var); wr.append("\n"); } wr.flush(); if (wr != null) { wr.close(); wr = null; } } 4. throwにて例外を発生させる throwを使うとわざと例外を発生させることができます。 try { if (file.exists()) { System.out.println(file.getCanonicalPath()); throw new Exception("file exist!!"); } } catch (Exception e) { e.printStackTrace(); System.out.println("file delete!!"); file.delete(); } ※ 例示コード https://github.com/leeyoungseung/algorithmBasic/blob/master/algorithm/src/basic/B_14_Exception.java ※ 韓国語のポストは以下のURLで確認できます。 https://koiking.tistory.com/86?category=1068655
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SpringBoot Bean Validation:フィールド名を出力する

はじめに Bean Validationのエラーメッセージにフィールド名を出力させるために、プロパティファイルに {0} を追記したが、「{0}を入力してください。」と表示される。 message.propertiesに記述していたのをValidationMessages.propertiesに変えてみたり、@Validを@Validatedに変えたりしたのだが、改善せず。 当たり前に使っていたのに、いざ上手くいかないと、何が原因なのか検討がつかず。解決するまでに、結構は時間を使った・・・。 どうようにお困りの方もいるかと思い記録しておきます。 不足していたのはMessageSourceの利用 bindingResultに登録された時点で、{0}にフィールド名が置き換わると思い込んでいたが、MessageSourceを使って置き換える必要がありました。(フォームだと自動的にやってくれていたのかも?) Controller(抜粋) import org.springframework.context.MessageSource; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("sample/api") public SampleController { @Autowired private MessageSource messageSource; SampleResponse index(@Validated @RequestBody SampleRequest request, BindingResult bindingResult) { if (bindingResult.hasErrors()) { bindingResult.getAllErrors().stream() .map(m -> messageSource.getMessage(m, Locale.getDefault())) .forEash(System.out::println); } return new SampleResponse(); } } ValidationMessages.properties javax.validation.constraints.NotNull.message={0}を入力してください。 messages.properties name=名前 References https://kntmr.hatenablog.com/entry/2017/09/11/233032
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java文法】セット(Set)

こんにちは、コイキングです。 本記事では'セット(Set)'について、説明したいと思います。 1. セット(Set)とは? Setは重複されていないデータの集まりを格納するためのデータ構造です。 Setを実装したクラスはHashSet, LinkedHashSet, TreeSetなどがあります。 2. HashSet ハッシュセットはHashMapのKeyの値がユニークである特性を利用して実装されています。 そのため、HashMapの特性と長・短所を共有します。 1) データの挿入 Set<String> set = new HashSet<String>(); set.add("HashSet-value-01"); set.add("HashSet-value-02"); set.add("HashSet-value-02"); // 重複された値は挿入できない。 set.add("HashSet-value-03"); set.add("HashSet-value-04"); 2) データの出力 for (String str : set) { System.out.println("Set value : "+str); } 3) データの削除 値を指定して削除 set.remove("HashSet-value-01"); 全体データ削除 set.clear(); 3. LinkedHashSet リンクドハッシュセットはLinkedHashMapの特性を共有しています。 セットに格納する各データの順序が重要な場合使います。 ※ データのCRUD機能はHashSetの機能を共有するため省略。 4. TreeSet ツリーセットはTreeMapの特性を共有します。 セットに格納するデータの順序が重要で、格納するデータの数が多い場合使います。 ※ データのCRUD機能はHashSetの機能を共有するため省略。 ※ 例示コード https://github.com/leeyoungseung/algorithmBasic/blob/master/algorithm/src/basic/B_13_Set.java ※ 韓国語のポストは以下のURLで確認できます。 https://koiking.tistory.com/85?category=1068655
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java文法】マップ(Map)

こんにちは、コイキングです。 本記事では'マップ(Map)'について、説明したいと思います。 1. マップ(Map)とは? マップはKey-Value構造に構成されているデータを格納するデータ構造です。 Keyを使ったデータ検索に最適化されたデータ構造で、 **Key値は重複できないという特徴があります。 Mapを実装したのはHashMap, LinkedHashMap, TreeMapなどがあります。 2. HashMap 1) HashMapとは? ハッシュマップとはハッシュテーブルを使ってマップを実装したデータ構造で、 Key値をハッシュ関数を通してデータの参照値が格納されているバーケット(bucket)のインデクスに変換し、バーケットのインデクスを用いてデータにアクセスします。 ※ 長所 - Key値でデータを検索するため、 検索速度が速いです。 ※ 短所 - バーケットの長さ調整が必要な場合、 処理速度の遅延が発生する可能背があります。 - データの格納時に配列やリストより多めのメモリーを使います。 - Key値がソートされてないです。 ※ 主に使っている所 - ユニークなKey値を利用したデータの活用が必要な場合 - データの入力・削除が頻繁な場合 2) データの挿入 put()メソッドを用いてデータの格納ができます。 putメソッドの引数としてKeyの値と、Value(格納する値)を渡してデータを格納します。 Map<String, String> map = new HashMap<String, String>(); map.put("HashMap-key-01", "HashMap-value-01"); map.put("HashMap-key-02", "HashMap-value-02"); map.put("HashMap-key-03", "HashMap-value-03"); map.put("HashMap-key-04", "HashMap-value-04"); map.put("HashMap-key-05", "HashMap-value-05"); 3) データの出力 get()メソッドとKey値を使う。 System.out.println(map.get("HashMap-key-02")); 全体データ出力(keySetメソッドを使う) for (String key : map.keySet()) { System.out.println(String.format("Using keySet key : [%s], value : [%s]", key, map.get(key))); } 全体データ出力(key値のIteratorを使う) Iterator<String> keys = map.keySet().iterator(); while(keys.hasNext()) { String key = keys.next(); System.out.println(String.format("Using Iterator key : [%s], value : [%s]", key, map.get(key))); } 全体データ出力 (entrySetメソッドを使う) for (Map.Entry<String, String> obj : map.entrySet()) { System.out.println(String.format("Using entrySet key : [%s], value : [%s]", obj.getKey(), obj.getValue())); } 4) データの更新 putを使う ※ 同じキーを用いてデータを格納すると値が上書きされ、更新が行われる map.put("HashMap-key-02", "HashMap-value-02_updated"); replaceメソッドを使う map.replace("HashMap-key-02", "HashMap-value-02_updated_new"); 5) データの削除 removeメソッドを使う map.remove("HashMap-key-02"); 全体データの削除 map.clear(); 3. LinkedHashMap 1) LinkedHashMapとは? リンクドハッシュマップはハッシュマップを継承して実装されたデータ構造で、 Key値の順序を保存するため、 Keyを順次ソートする必要がある場合使います。 ※ データのCRUD機能はHashMapのメソッドを共通で使えるため省略。 4. TreeMap 1) TreeMapとは? ツリーマップはツリー(木)構造基盤で実装されたマップです。 ※ 長所 - メモリー使用量がHashMapより少ないです。 - データのKey値がソートされています。 ※ 短所 - データの入力・削除時にHashMapより処理速度が遅いです。(TreeのNode再配置が行われる可能性があり) ※ データのCRUD機能はHashMapのメソッドを共通で使えるため省略。 ※ 例示コード https://github.com/leeyoungseung/algorithmBasic/blob/master/algorithm/src/basic/B_12_Map.java ※ 韓国語のポストは以下のURLで確認できます。 https://koiking.tistory.com/84?category=1068655
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[オブジェクト指向]某コーヒーショップの注文をイメージしてプログラムを書いてみた。

アウトプット用!! 第7回目は has-aの関係を意識してプログラムを行なっていく! (has-a)とはあるクラスが別のクラスをフィールドとして利用している関係のことです。 例えば、Hero型のクラスとSword型のクラスがあるとしてHeroクラスのメンバ変数にSwordクラスのデータが使えるようになるイメージです。よって勇者は剣を持っている(has-a)の関係が成り立つ。 今回作成したプログラムは(has-a)を意識して作成しました。 SetMenuクラスはMenuクラスを持っている(has-a)の関係が成り立つので、SetMenuクラスでMenuクラスのデータが使えるようになる。 早速コードをみていきましょう。 Main.java package ensyu; import java.text.SimpleDateFormat; import java.util.Date; public class Main { public static void main(String[] args) { //現在日時を取得 Date dateObj = new Date(); SimpleDateFormat format = new SimpleDateFormat( "HH" ); String display = format.format( dateObj ); int num = Integer.parseInt(display); //9時から10時はモーニングセットを注文 if(9 <= num && num <= 10) { Menu drink = new Menu("コーヒー", 350); Menu bread = new Menu("サンドイッチ",300); SetMenu MorningSet = new SetMenu("モーニングセット",drink,bread, 0.8); MorningSet.display(); //11時から13時まではバリューセットを注文 } else if(10 <= num && num <= 13 ) { Menu drink = new Menu("アメリカン", 300); Menu bread = new Menu("チョコクロ", 190); SetMenu ValueSet = new SetMenu("バリューセット",drink,bread); ValueSet.display(); //14時以降は通常メニューで注文 } else { Menu drink = new Menu("コーヒー", 350); Menu bread = new Menu("ザクザクドック", 390); NomalMenu Nomal = new NomalMenu("通常メニュー",drink,bread, 0.7); Nomal.display(); } Menu.java package ensyu; public class Menu { String name; int price; Menu(String name, int price) { this.name = name; this.price = price; } public void display() { System.out.println(name + ":" + price + "円"); } } SetMenu.java package ensyu; public class SetMenu { String name; Menu drink; Menu bread; double tax; SetMenu(String name, Menu drink, Menu bread, double rate) { this.name = name; this.drink = drink; this.bread = bread; this.tax = rate; } public void display() { System.out.println(name + ":" + (int)(100 - (100 * rate))"%引き"); System.out.println("---"); //Menu has-a SetMenu(メニューはセットメニュを持っている) drink.display(); bread.display(); System.out.println("---"); int price = (int)((drink.price + bread.price)*rate); System.out.println("セット価格:"+ price + "円"); } } NomalMenu.java package ensyu; public class NomalMenu { String name; Menu drink; Menu bread; NomalMenu(String name, Menu drink, Menu bread) { this.name = name; this.drink = drink; this.bread = bread; } public void display() { System.out.println(name); System.out.println("---"); drink.display(); bread.display(); System.out.println("---"); int price = drink.price + bread.price; System.out.println("合計金額は" + price + "円です"); } } 解説 main.java ①現在の時刻を取得   javaAPIで ②現在時刻を取得できたらif文で条件分岐を行う。  9時から10時まではモーニングセットを注文。  11時から13時まではバリューセットを注文。  14時以降は通常メニューを注文。 ③インスタンスを作成する  MenuインスタンスとSetMenuインスタンスとNomalインスタンスを生成する。  インスタンス生成時に()の引数が、コンストラクタが自動実行される際にパラメータとして渡される。  例えば、Menu drink = new Menu("コーヒ", 350);の場合  Menuクラスのコンストラクタに引数の値が渡されるイメージ。 SetMenu.java  main.javaでSetMenuインスタンスを生成する。生成時に引数にMenuインスタンスをセットして  SetMenuクラスのコンストラクタに引数の値が渡されるイメージ。  SetMenu has-a Menuが成り立つのでSetMenuクラスでMenuクラスのデータが使えるようになった。 処理結果 コンソール.java モーニングセット:20%引き --- コーヒー:350円 サンドイッチ:300円 --- セット価格:520円 *モーニングセットの場合20パーセント引きに、バリューセットの場合は30%引きに。通常の場合は割引なし。 以上です。  お疲れさまでした。  これからも楽しみながらプログラムがんばりたいと思います。  今回のコードはもっと簡潔に書けると思うので、もしよかったらご教授お願いいたします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javaに入門してみたらmainメソッドが気になり過ぎて前に進めなくなった話

はじめに IT業界の経験は10年以上あるものの、ずっとメインフレームコンピュータなどのレガシーな環境でCOBOLの開発をやってきて、最近はCOBOLすら書いていなくて完全にエクセルで資料作ってる人がこの記事を書いております。Java初心者が記事を書いておりますので間違いなどありましたら指摘頂けると幸いです。 何が起きたのか これまで個人開発でPythonを書いてきましたが、ふとOOPについて学んでみたくなったので、Javaを学んでみることにしました。まずは環境構築してHello Worldしてみたのですが、「mainメソッドはおまじない」という入門記事があったりして、本当にそれでいいのか?と気になって先に進めなくなり色々調べてみたという話です。 とりあえず環境構築してHello Worldまでやってみる JDKのインストール まずはJDK(Java Development Kit)をインストールするためにJDKのダウンロードページにいきます。 2022年1月時点の最新バージョン(Java SE Development Kit 17.0.1)をダウンロードしてインストールします。バージョンを確認します。 $java --version java 17.0.1 2021-10-19 LTS Java(TM) SE Runtime Environment (build 17.0.1+12-LTS-39) Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+12-LTS-39, mixed mode, sharing) VScodeにJavaのエクステンションをインストール 他の言語を書くのもVScodeを使っているのでエディタはVScodeを使います。VScodeのエクステンションでJavaを検索してJava Extention Packをインストールします。 Hello Worldやってみる VScodeでHello Worldしてみます。 HelloWorld.java public class HelloWorld{ public static void main(String[] args){ System.out.println("Hello World!!"); } } $ javac HelloWold.java $ java HelloWorld Hello World!! Hello Worldできました! Hello Worldできましたで終われない... とりあえず写経して書いてみましたが、 public static void main(String[] args) この1文はなんでしょうか。 Javaの入門書にもこれはおまじないで...とか書かれていたりしますが、下記の記事に分かりやすく書かれていました。 Javaの実行に欠かせないmainメソッド、その仕組みからしっかり解説 mainメソッドの条件は以下全てを満たしているもの アクセス修飾子はpublicである staticメソッドである メソッドの戻り値はvoidである メソッド名は“main”である(すべて小文字) メソッドの引数は、Stringの配列(あるいはStringの可変長引数)”のみ“である ※引数の変数名は何でもよい とりあえず自分でも動かして確認してみます。 1)アクセス修飾子はpublicである まず最初の単語はpublic以外不可ということなので以下の疑問を試してみました。 疑問その1 publicを削除したらダメなのか? static void main(String[] args) 結果 コンパイル 実行 結果 ○ エラー エラーメッセージ エラー: メイン・メソッドがクラスMainMethodで見つかりません。次のようにメイン・メソッドを定義してください。 public static void main(String[] args) 疑問その2 他のアクセス修飾子(例えばprivate)ではダメなのか? private static void main(String[] args) 結果 コンパイル 実行 結果 ○ エラー エラーメッセージ エラー: メイン・メソッドがクラスMainMethodで見つかりません。次のようにメイン・メソッドを定義してください。 public static void main(String[] args) 2)staticメソッドである static以外何があるのか良く理解していないのですが、これも削除したらどうなるかを試してみます。 疑問 staticを削除したらダメなのか? public void main(String[] args) 結果 コンパイル 実行 結果 ○ エラー エラーメッセージ エラー: メイン・メソッドがクラスMainMethodのstaticではありません。次のようにメイン・メソッドを定義してください。 public static void main(String[] args) 3)メソッドの戻り値はvoidである メソッドの戻り値の型はvoidが指定されていますが、これを別の型にしてみるとどうなるかを試してみます。 疑問 voidを別の型に変更したらダメなのか? public static int main(String[] args) 結果 コンパイル 実行 結果 エラー ー エラーメッセージ HelloWorld.java:4: エラー: return文が指定されていません } ^ エラー1個 4)メソッド名は“main”である(すべて小文字) メソッド名には"main"が指定されていますが、これを他のメソッド名にして試してみます。 疑問 メソッド名は“main”ではなく"hoge"に変更したらダメなのか? public static void hoge(String[] args) 結果 コンパイル 実行 結果 ○ エラー エラーメッセージ ラー: メイン・メソッドがクラスMainMethodで見つかりません。次のようにメイン・メソッドを定義してください。 public static void main(String[] args) “main”ではなく"Main"と最初を大文字にしてもエラーなるようです。 5)メソッドの引数は、Stringの配列(あるいはStringの可変長引数)”のみ“である ※引数の変数名は何でもよい Stringは配列でなければならないが、引数の名前は変えられるそうです。 疑問その1 "String[]"を“String”に変更したらダメなのか? public static void main(String args) 結果 コンパイル 実行 結果 ○ エラー エラーメッセージ ラー: メイン・メソッドがクラスMainMethodで見つかりません。次のようにメイン・メソッドを定義してください。 public static void main(String[] args) 疑問その2 "args"を“hoge”に変更したらダメなのか? public static void main(String[] hoge) 結果 コンパイル 実行 結果 ○ ○ これは通りました。引数の名前はargsである必要はないのは知りませんでした。 Stackoverflowは何と言ってるか stackoverflowでも調べてみました。 Why is the Java main method static? This is just convention. In fact, even the name main(), and the arguments passed in are purely convention. (DeepL翻訳) これは単なる慣習です。実際 main()という名前も 渡される引数も 純粋に慣例です。 When you run java.exe (or javaw.exe on Windows), what is really happening is a couple of Java Native Interface (JNI) calls. These calls load the DLL that is really the JVM (that's right - java.exe is NOT the JVM). JNI is the tool that we use when we have to bridge the virtual machine world, and the world of C, C++, etc... The reverse is also true - it is not possible (at least to my knowledge) to actually get a JVM running without using JNI. (DeepL翻訳) java.exe(Windowsではjavaw.exe)を実行するとき、実際に起こっているのは2つのJava Native Interface(JNI)呼び出しです。これらの呼び出しは、実際にJVMであるDLLをロードします(その通りです - java.exeはJVMではありません)。JNIは、仮想マシンの世界とCやC++などの世界との橋渡しをしなければならないときに使うツールです。逆もまた真なりで、JNIを使わずにJVMを実際に走らせることは(少なくとも私の知る限り)不可能なのです。(中略) So, long and short: the reason it is static is b/c that's convenient. The reason it's called 'main' is that it had to be something, and main() is what they did in the old days of C (and in those days, the name of the function was important). I suppose that java.exe could have allowed you to just specify a fully qualified main method name, instead of just the class (java com.mycompany.Foo.someSpecialMain) - but that just makes it harder on IDEs to auto-detect the 'launchable' classes in a project. (DeepL翻訳) 要するに、staticであるのは便利だからです。main'と呼ばれているのは、それが何かでなければならないからで、main()は昔のCの時代にはそうしていました(そしてその時代には関数の名前が重要だったのです)。java.exeでは、クラス名(java com.mycompany.Foo.someSpecialMain)だけでなく、完全修飾したメインメソッド名を指定できたのでしょうが、それではIDEがプロジェクト内の「起動可能」クラスを自動検出しにくくなるばかりです。 色々と理由があるもののconvention(慣習)であるということですね。(要約しすぎ。。) 結論 おまじないとして覚えるのが良さそう。。 ただ変えても動く部分と変えたら動かなくなる部分があるというのは勉強になりました。 Javaインストールの参考 まずは下記のYouTube(英語)でゼロから学んでいこうと思います。 Java Tutorial for Beginners 2020 Macでvisual studio codeでJavaの環境を作る方法は下記を参照しました。 How to Run Java in Visual Studio Code on Mac OS 2020
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javaに入門してみたらmainメソッドが気になり過ぎて前に進めなくなった

はじめに IT業界の経験は10年以上あるものの、ずっとメインフレームコンピュータなどのレガシーな環境でCOBOLの開発をやってきて、最近はCOBOLすら書いていなくて完全にエクセルで資料作ってる人がこの記事を書いております。Java初心者が記事を書いておりますので間違いなどありましたら指摘頂けると幸いです。 何が起きたのか これまで個人開発でPythonを書いてきましたが、ふとOOPについて学んでみたくなったので、Javaを学んでみることにしました。まずは環境構築してHello Worldしてみたのですが、「mainメソッドはおまじない」という入門記事があったりして、本当にそれでいいのか?と気になって先に進めなくなり色々調べてみたという話です。 とりあえず環境構築してHello Worldまでやってみる JDKのインストール まずはJDK(Java Development Kit)をインストールするためにJDKのダウンロードページにいきます。 2022年1月時点の最新バージョン(Java SE Development Kit 17.0.1)をダウンロードしてインストールします。バージョンを確認します。 $java --version java 17.0.1 2021-10-19 LTS Java(TM) SE Runtime Environment (build 17.0.1+12-LTS-39) Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+12-LTS-39, mixed mode, sharing) VScodeにJavaのエクステンションをインストール 他の言語を書くのもVScodeを使っているのでエディタはVScodeを使います。VScodeのエクステンションでJavaを検索してJava Extention Packをインストールします。 Hello Worldやってみる VScodeでHello Worldしてみます。 HelloWorld.java public class HelloWorld{ public static void main(String[] args){ System.out.println("Hello World!!"); } } $ javac HelloWold.java $ java HelloWorld Hello World!! Hello Worldできました! Hello Worldできましたで終われない... とりあえず写経して書いてみましたが、 public static void main(String[] args) この1文はなんでしょうか。 Javaの入門書にもこれはおまじないで...とか書かれていたりしますが、下記の記事に分かりやすく書かれていました。 Javaの実行に欠かせないmainメソッド、その仕組みからしっかり解説 mainメソッドの条件は以下全てを満たしているもの アクセス修飾子はpublicである staticメソッドである メソッドの戻り値はvoidである メソッド名は“main”である(すべて小文字) メソッドの引数は、Stringの配列(あるいはStringの可変長引数)”のみ“である ※引数の変数名は何でもよい とりあえず自分でも動かして確認してみます。 1)アクセス修飾子はpublicである まず最初の単語はpublic以外不可ということなので以下の疑問を試してみました。 疑問その1 publicを削除したらダメなのか? static void main(String[] args) 結果 コンパイル 実行 結果 ○ エラー エラーメッセージ エラー: メイン・メソッドがクラスMainMethodで見つかりません。次のようにメイン・メソッドを定義してください。 public static void main(String[] args) 疑問その2 他のアクセス修飾詞(例えばprivate)ではダメなのか? private static void main(String[] args) 結果 コンパイル 実行 結果 ○ エラー エラーメッセージ エラー: メイン・メソッドがクラスMainMethodで見つかりません。次のようにメイン・メソッドを定義してください。 public static void main(String[] args) 2)staticメソッドである static以外何があるのか良く理解していないのですが、これも削除したらどうなるかを試してみます。 疑問 staticを削除したらダメなのか? public void main(String[] args) 結果 コンパイル 実行 結果 ○ エラー エラーメッセージ エラー: メイン・メソッドがクラスMainMethodのstaticではありません。次のようにメイン・メソッドを定義してください。 public static void main(String[] args) 3)メソッドの戻り値はvoidである メソッドの戻り値の型はvoidが指定されていますが、これを別の型にしてみるとどうなるかを試してみます。 疑問 voidを別の型に変更したらダメなのか? public static int main(String[] args) 結果 コンパイル 実行 結果 エラー ー エラーメッセージ HelloWorld.java:4: エラー: return文が指定されていません } ^ エラー1個 4)メソッド名は“main”である(すべて小文字) メソッド名には"main"が指定されていますが、これを他のメソッド名にして試してみます。 疑問 メソッド名は“main”ではなく"hoge"に変更したらダメなのか? public static void hoge(String[] args) 結果 コンパイル 実行 結果 ○ エラー エラーメッセージ ラー: メイン・メソッドがクラスMainMethodで見つかりません。次のようにメイン・メソッドを定義してください。 public static void main(String[] args) “main”ではなく"Main"と最初を大文字にしてもエラーなるようです。 5)メソッドの引数は、Stringの配列(あるいはStringの可変長引数)”のみ“である ※引数の変数名は何でもよい Stringは配列でなければないが、引数の名前は変えられるそうです。 疑問その1 "String[]"を“String”に変更したらダメなのか? public static void main(String args) 結果 コンパイル 実行 結果 ○ エラー エラーメッセージ ラー: メイン・メソッドがクラスMainMethodで見つかりません。次のようにメイン・メソッドを定義してください。 public static void main(String[] args) 疑問その2 "args"を“hoge”に変更したらダメなのか? public static void main(String[] hoge) 結果 コンパイル 実行 結果 ○ ○ これは通りました。引数の名前はargsである必要はないのは知りませんでした。 Stackoverflowは何と言ってるか stackoverflowでも調べてみました。 Why is the Java main method static? This is just convention. In fact, even the name main(), and the arguments passed in are purely convention. (DeepL翻訳) これは単なる慣習です。実際 main()という名前も 渡される引数も 純粋に慣例です。 When you run java.exe (or javaw.exe on Windows), what is really happening is a couple of Java Native Interface (JNI) calls. These calls load the DLL that is really the JVM (that's right - java.exe is NOT the JVM). JNI is the tool that we use when we have to bridge the virtual machine world, and the world of C, C++, etc... The reverse is also true - it is not possible (at least to my knowledge) to actually get a JVM running without using JNI. (DeepL翻訳) java.exe(Windowsではjavaw.exe)を実行するとき、実際に起こっているのは2つのJava Native Interface(JNI)呼び出しです。これらの呼び出しは、実際にJVMであるDLLをロードします(その通りです - java.exeはJVMではありません)。JNIは、仮想マシンの世界とCやC++などの世界との橋渡しをしなければならないときに使うツールです。逆もまた真なりで、JNIを使わずにJVMを実際に走らせることは(少なくとも私の知る限り)不可能なのです。(中略) So, long and short: the reason it is static is b/c that's convenient. The reason it's called 'main' is that it had to be something, and main() is what they did in the old days of C (and in those days, the name of the function was important). I suppose that java.exe could have allowed you to just specify a fully qualified main method name, instead of just the class (java com.mycompany.Foo.someSpecialMain) - but that just makes it harder on IDEs to auto-detect the 'launchable' classes in a project. (DeepL翻訳) 要するに、staticであるのは便利だからです。main'と呼ばれているのは、それが何かでなければならないからで、main()は昔のCの時代にはそうしていました(そしてその時代には関数の名前が重要だったのです)。java.exeでは、クラス名(java com.mycompany.Foo.someSpecialMain)だけでなく、完全修飾したメインメソッド名を指定できたのでしょうが、それではIDEがプロジェクト内の「起動可能」クラスを自動検出しにくくなるばかりです。 色々と理由があるもののconvention(慣習)であるということですね。(要約しすぎ。。) 結論 おまじないとして覚えるのが良さそう。。 ただ変えても動く部分と変えたら動かなくなる部分があるというのは勉強になりました。 Javaインストールの参考 まずは下記のYouTube(英語)でゼロから学んでいこうと思います。 Java Tutorial for Beginners 2020 Macでvisual studio codeでJavaの環境を作る方法は下記を参照しました。 How to Run Java in Visual Studio Code on Mac OS 2020
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【個人的4選】サイバーセキュリティニュースまとめ(2021年12月)

はじめに この記事の目的 この記事は日々刻々と変化するサイバーセキュリティ関連のニュースの内、興味深いニュースを筆者の独断と偏見でピックアップしたものです。 日々の情報収集、セキュリティの勉強、セキュリティ全く関心のない経営層への啓蒙などに役立てていただけますと幸いです。 想定読者 セキュリティ関連の仕事に従事している人 セキュリティに関わらないけど、少しセキュリティに興味がある人 セキュリティに興味のある学生 サイバーセキュリティニュース 2021年12月は、4つのニュースをピックアップしました。 1位 Apache Log4j の脆弱性 1位はこれで異論のあるセキュリティ担当者はいないでしょう。 12/10頃に世界的に話題になった、Javaのログ出力ライブラリLog4jの脆弱性です。 多くのセキュリティ担当者がこの脆弱性に対応に忙殺されたのではないでしょうか。 概要 Javaベースのログ出力ライブラリLog4j2で深刻な脆弱性(CVE-2021-44228)を修正したバージョンが公開された。その後も修正が不完全であったことなどを理由に2件の脆弱性が修正された。 広く利用されているライブラリであるため影響を受ける対象が多く存在するとみられ、攻撃が容易であることから2014年のHeartbleed、Shellshock以来の危険性があるとみる向きもあり、The Apache Software Foundationも脆弱性の深刻度を最高(Critical)と評価している。 脆弱性に関連したスキャンや攻撃への悪用が報告されており、脆弱性の悪用による影響発生を考慮した対応が推奨されている。 引用 Log4jの深刻な脆弱性CVE-2021-44228についてまとめてみた コメント Log4jによる脆弱性は、CVSSスコア「10.0」となっており、かなり甚大な被害が及ぼされました。 一般に広く使われているため、影響範囲は計り知れず、個人的にはJavaを使用しているシステムの半分近くは使っているのではないかと懸念しております。 ※該当バージョンを使用しているかどうかを含めるともう少し少ないかもしれないですが。 幸い、日本の企業で、本脆弱性をついた重大なセキュリティインシデントは報告されていませんが(2022/1/10現在)今後も警戒が必要です。 ちなみに、ベルギー政府へサイバー攻撃があったとのニュースが流れたことがありましたが、続報はなさそうですね、、大事に至っていなければよいのですが、、、、 ベルギー国防省に「Apache Log4j」を悪用したサイバー攻撃 CISAが公表している、Log4jの影響が一覧になっているドキュメントもあります。自社サービス以外のIaaSやSaaSの確認も必須です。 参考 更新:Apache Log4j の脆弱性対策について(CVE-2021-44228) Apache Log4jにCVSSスコア「10.0」の脆弱性 国内で悪用を試みる通信も確認 2位 Emotet 11下旬から少しずつ話題に上ることが多かった悪名高きマルウェアEmotet。IPAが正式に活動再開を報告しています。 ビジネスマンなら誰でも使ったことがあるであろうアプリケーション、WordやExcel等からマルウェアに感染するため、完全に防ぐにはITリテラシーの向上が必須です。 概要 Emotetはメールの添付ファイルを主な感染経路とする不正プログラムで、過去にやり取りをしたメールに対する返信などを装ったメールに、パスワード付きZIP形式で圧縮された文書ファイルを添付する。この文書ファイルを開き、文書内のマクロを実行することで、PCにマルウェアが感染する。  11月にEmotetの活動再開が確認されて以降、手口を変化させながら12月現在でも攻撃が続いているという。同機構に少数ながらも企業から被害相談が寄せられていると、注意の徹底を呼び掛けている。 引用 マルウェア「Emotet」の新たな攻撃手法をIPAが公開。Excelファイルの悪用、偽PDF閲覧ソフトをダウンロードさせる手口にも注意を コメント 今回はPDFに偽造するEmotetが観測されているようで、手口も巧妙化されています。 セキュリティ部門によるテクノロジーでの対策だけでは完全に防ぐことが難しく、従業員への注意喚起、セキュリティ教育が必須です。 また、昨今話題になっているPPAPとも相性が悪いです。 PPAPにより、ファイルが暗号化されることで、Emotetのように外部と通信するようなマクロが組まれている悪質なファイルを、ウイルス検知ソフトが検知できません。 文科省が公表したように、BoxやSharePoint等のクラウドストレージによるファイル共有に切り替えていく必要がありそうです。 参考 復活したEmotet 偽のAdobeインスト―ラーで感染拡大を図る 「Emotet(エモテット)」と呼ばれるウイルスへの感染を狙うメールについて 3位 LINE Pay5万件顧客情報流出 12月に日本で起こったインシデントの内、一番衝撃を与えたニュースといえばこちらではないでしょうか。 概要 スマートフォン決済大手の「LINE Pay」は12月7日までに、国内外の約13万件の決済金額などの情報が漏えいし、インターネット上で一時閲覧できる状態になっていたと発表した。親会社の通信アプリ大手のLINEで2021年3月に中国の関連会社から利用者の情報が閲覧可能になっていたことが発覚し、データの運用指針を改定したばかり。見直したはずの新体制での流出に個人情報保護の信頼が揺らいでおり、改めて経営管理の在り方が問われる。 引用 LINE、指針改定でも情報漏洩 揺らぐ信頼 コメント 2021年3月に話題になった、LINEの利用者情報が中国の関連会社から閲覧可能だった件に加えて、LINEにとっては2021年2度目の停滞インシデントとなってしましました。 今回流出した情報は、氏名や住所、クレジットカード番号は含まれないが、特殊な解析をすると個人を特定できる可能性とのことです。 GitHubから流出したとの情報があります。 近年、開発者のリテラシー不足による、GitHubからの情報流出が頻発しているような気がします。 正しく使えば便利なツールですが、オープンな環境である分、危険と隣り合わせであることを自覚する必要があるでしょう。(自戒の念も込めて) GitHubに関しては、メルカリのブログに非常に良い記事がありますので、セキュリティ担当者のみならず、開発者も必読です。 GitHub上のsensitive dataを削除するための手順と道のり (参考) - LINE Pay、約13万人の決済情報が「GitHub」で公開状態に グループ会社従業員が無断アップロード - LINE、指針改定でも情報漏洩 揺らぐ信頼 4位 重要インフラ、サイバー防衛義務付け 4位はコチラです。日経新聞の一面になっていたので、一時話題になりました。 概要 政府は情報通信や電力など14分野の重要インフラ事業者にサイバー攻撃(総合・経済面きょうのことば)への備えを義務付ける。経営陣主導の体制整備や対処計画づくりを求める。サプライチェーン(供給網)で使用する機器の安全確保も要請する。2021年度中にも改定する重要インフラ行動計画に明記する。 コメント 近年増加するサイバー攻撃に備え、政府から重要インフラへ体制整備を義務付けることとなりそうです。 出所:情報通信研究機構のNICTER観測レポート こういった規定はセキュリティ担当としては、遵守しない基準が増えるため骨が折れる一方で、こういった義務があることにより、経営層へセキュリティ強化への説得材料にもなります。 実に5年ぶりの抜本的な改訂になるそうです。セキュリティ担当者はキャッチアップ必須です。※2022年度から施行 参考 重要インフラ、サイバー防衛義務付け 来年度から企業に対処計画 経営陣主導など柱 番外編 FISC安全対策基準改訂 このニュースは番外編です。2021年12月22日、FISCの安全対策基準がアップデートされました。 (まだ、筆者も改訂の差分を読めていませんが、、、)金融機関に携わっているセキュリティ担当者は必読です。 安全対策基準ってなに??という方はコチラ→(金融機関が情報システムを構築する際の安全対策基準「FISC安全対策基準」とは? 参考 「金融機関等コンピュータシステムの安全対策基準・解説書(第9版 令和3年12月版)【PDF版】」の訂正について 個人的好みによる良コラム ここからは、個人的に読んでよかった良コラムの紹介です。 主戦場はWebブラウザ 忍び寄る「見えないクライアントサイド攻撃」の実態 電話番号に届く認証番号を使った「2要素認証」はもはや安全ではない 今さら人に聞けないVPN入門…VPNの神話をはぎ取る エンドポイントにおける主要な3つのセキュリティ対策とは 最後に 最後まで読んでいただきありがとうございました。 ※記事の内容に誤りがありましたら、ご連絡ください。 また、Twitterでは(できるだけ毎日)セキュリティ関連のニュースを配信しています。よろしければのぞいてみてください。 Twitterアカウントはこちら ▼こんな感じ▼
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java文法】リスト(List)

こんにちは、コイキングです。 本記事では'リスト(List)'について、説明したいと思います。 1. リスト(List)とは? リストはJavaでデータ構造とデータを取り扱うためのコレクションフレームワークに属するインターフェースです。 配列のように順序があるデータを格納するためのデータ構造で、リストを実装しているクラスはArrayList, LinkedList, Vectorなどがあります。 2. ArrayList 1) アレイリスト(ArrayList)とは? 'ArrayListは長さが変更できる配列'のようなデータ構造です。 ArrayListのクラス内部を見れば配列を使いデータを格納していることが分かります。 ※ 長所 - 配列のようにインデクスを使い、速やかに要素にアクセスできます。 ※ 短所 - 長さが変わる際の処理に時間がかかる。  リストにデータを入れてみるとリストの内部のデータを格納する配列の長さを超える場合がある。この時長さを増やした新しい配列に既格納していたデータをコピーする処理が行われる。 - リストの各要素の削除処理に時間がかかる ※ 主に使われているところ - リストに格納するデータの量が一定的で、データの入力・削除が少ないところ。 - データのアクセス速度が重要なところ。 2) データの挿入 add()メソッドを使いデータをリストに格納できます。 List<String> list = new ArrayList<String>(); list.add("ArrayList-String01"); // Index 0 list.add("ArrayList-String02"); // Index 1 list.add("ArrayList-String03"); // Index 2 list.add("ArrayList-String04"); // Index 3 list.add("ArrayList-String05"); // Index 4 3) データの出力 インデクスを指定して出力 get()メソッドにインデクス番号を渡して、データにアクセス・出力できます。 System.out.println("Index 2番のデータ出力 : "+ list.get(2)); 全体データ出力(for-each) 拡張for文を使うと簡単に全体データが出力できます。 for (String str : list) { System.out.println("Using for-each : "+str); } 全体データ出力(for文とインデクス番号) for文とインデクス番号、get()メソッドを使い全体データを出力できます。 // ※ sizeメソッドにて、リストの長さが分かります。 for (int i=0; i<list.size(); i++) { System.out.println("Using for Index ["+i+"] : "+list.get(i)); } 全体データ出力(forEachメソッド) forEach()メソッドを使うと簡単に全体データが出力できます。 list.forEach(str -> { System.out.println("Using forEach() : "+str); }); 4) データ更新 set()メソッドにインデクス番号と更新する値を渡して、データを更新できます。 list.set(1, "ArrayList-String020202"); printList(list); 5) データ削除 インデクス番号を指定して削除 list.remove(1); printList(list); 値を探して削除 list.remove(list.get(2)); printList(list); 全ての要素を削除 list.clear(); printList(list); 3. LinkedList 1) リンクドリスト(LinkedList)とは? LinkedListはデータの格納を配列ではなく**'ノード(Node)'を使い実装したデータ構造で、ノードとノードが相互繋がっているような形でデータを格納します。 ※ ノード(Node)とは? 以前のノードの参照値と次のノードの参照値、格納するデータを込めているオブジェクトを言います。 ※ 長所 - データの入力・削除が速い ※ 短所 - データの検索に時間がかかる ※ 主に使われているところ - データのアクセス・検索より入力と削除が多い場合使います。 ※ データCRUDはArrayListと共通のメソッドを使いますので省略。 4. Vector 1) ベクター(Vector)とは? VectorはArrayListのように長さが変わる配列のようなデータ構造です。 性能自体がArrayListの方がよいため、Vectorはあまり使われておりません。 ArrayListとの差は**Vectorの場合Thread-safeし、ArrayListはそうではないため、コードをThread-safeに実装する必要がある場合は使いますが、 現在、ArrayList生成時に synchronizedList()を引数として生成すると ArrayListでもThread-safeなArrayListが生成できるため、使う理由はあまりないが、レガシーコードに使っている可能背があるため知っておくだけで良いかと思います。 // ※ 例示 : ArrayList arrayList = new ArrayList<>(Collections.synchronizedList(list)); ※ データCRUDはArrayListと共通のメソッドを使いますので省略。 ※ 例示コード https://github.com/leeyoungseung/algorithmBasic/blob/master/algorithm/src/basic/B_11_List.java ※ 韓国語のポストは以下のURLで確認できます。 https://koiking.tistory.com/83?category=1068655
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java文法】ラッパークラス

こんにちは、コイキングです。 本記事では'ラッパークラス'について、説明したいと思います。 1. ラッパー(Wrapper)クラスとは? ラッパークラスはプリミティブデータ型をクラス化したもので、 1) プリミティブ型の変数をインスタンスとして使う場合 2) 文字列 <-> 数字を相互変換する必要がある場合 などに使います。 2. プリミティブ型からラッパークラスのインスタンスに変換 プリミティブ型 -> ラッパークラスの変換はnew 演算子を使います。 // ※ Wrapperクラスの参照変数には'null'の代入ができます。 Integer wrapperInt = null; Long wrapperLong = null; Short wrapperShort = null; Byte wrapperByte = null; Double wrapperDouble = null; Float wrapperFloat = null; Character wrapperChar = null; Boolean wrapperBoolean = null; // new 演算子を使いプリミティブ型のリテラル値からラッパークラスのインスタンスに変換 wrapperInt = new Integer(100); wrapperLong = new Long(2000000L); wrapperShort = new Short((short) 10); wrapperByte = new Byte((byte) 1); wrapperDouble = new Double(2.85); wrapperFloat = new Float(0.25f); wrapperChar = new Character('c'); wrapperBoolean = new Boolean(false); System.out.println("int -> Int : " + wrapperInt); System.out.println("long -> Long : " + wrapperLong); System.out.println("short -> Short : " + wrapperShort); System.out.println("byte -> Byte : " + wrapperByte); System.out.println("double -> Double : " + wrapperDouble); System.out.println("float -> Float : " + wrapperFloat); System.out.println("char -> Character : " + wrapperChar); System.out.println("boolean -> Boolean : " + wrapperBoolean); new 演算子を使わず、直接値を代入する方式でも変換できます。 こちらの機能をオートボクシング(Auto Boxing)と言います。 wrapperInt = 100; wrapperLong = 2000000L; wrapperShort = 10; wrapperByte = 'a'; wrapperDouble = 2.85; wrapperFloat = 1.25f; wrapperChar = 'c'; wrapperBoolean = true; System.out.println("Auto Boxing int -> Int : " + wrapperInt); System.out.println("Auto Boxing long -> Long : " + wrapperLong); System.out.println("Auto Boxing short -> Short : " + wrapperShort); System.out.println("Auto Boxing byte -> Byte : " + wrapperByte); System.out.println("Auto Boxing double -> Double : " + wrapperDouble); System.out.println("Auto Boxing float -> Float : " + wrapperFloat); System.out.println("Auto Boxing char -> Character : " + wrapperChar); System.out.println("Auto Boxing boolean -> Boolean : " + wrapperBoolean); 3. ラッパークラスのインスタンスからプリミティブ型に変換 ラッパークラス -> プリミティブ型への変換は各ラッパークラスのxxxValue()メソッドを使って行います。 // xxxValue()メソッドを使い変換 int primitiveInt = wrapperInt.intValue(); long primitiveLong = wrapperLong.longValue(); short primitiveShort = wrapperShort.shortValue(); Byte primitiveByte = wrapperByte.byteValue(); double primitiveDouble = wrapperDouble.doubleValue(); float primitiveFloat = wrapperFloat.floatValue(); char primitiveChar = wrapperChar.charValue(); boolean primitiveBoolean = wrapperBoolean.booleanValue(); System.out.println("Int -> int : " + primitiveInt); System.out.println("Long -> long : " + primitiveLong); System.out.println("Short -> short : " + primitiveShort); System.out.println("Byte -> byte : " + primitiveByte); System.out.println("Double -> double : " + primitiveDouble); System.out.println("Float -> float : " + primitiveFloat); System.out.println("Character -> char : " + primitiveChar); System.out.println("Boolean -> boolean : " + primitiveBoolean); xxxValue()メソッドを使わず、ラッパークラスの参照変数を代入する方法でも変換できます。 こちらの機能をオートアンボクシング(Auto Unboxing)と言います。 primitiveInt = wrapperInt; primitiveLong = wrapperLong; primitiveShort = wrapperShort; primitiveByte = wrapperByte; primitiveDouble = wrapperDouble; primitiveFloat = wrapperFloat; primitiveChar = wrapperChar; primitiveBoolean = wrapperBoolean; System.out.println("Auto UnBoxing Int -> int : " + primitiveInt); System.out.println("Auto UnBoxing Long -> long : " + primitiveLong); System.out.println("Auto UnBoxing Short -> short : " + primitiveShort); System.out.println("Auto UnBoxing Byte -> byte : " + primitiveByte); System.out.println("Auto UnBoxing Double -> double : " + primitiveDouble); System.out.println("Auto UnBoxing Float -> float : " + primitiveFloat); System.out.println("Auto UnBoxing Character -> char : " + primitiveChar); System.out.println("Auto UnBoxing Boolean -> boolean : " + primitiveBoolean); 4. 文字列を数字に変換する 各ラッパークラスの'parseXxx()メソッド'を使い変換できます。 String intStr = "123"; int intFromStr = Integer.parseInt(intStr); String doubleStr = "3.15"; double doubleFromStr = Double.parseDouble(doubleStr); System.out.println("String -> Int : "+intFromStr); System.out.println("String -> Double : "+doubleFromStr); 5. 数字を文字列に変換する 各ラッパークラスの'toString()メソッド'を使い変換でき、'String.valueOf()メソッド'を用いて変換できます。 String strFromInt = Integer.toString(intFromStr); String strFromInt2 = String.valueOf(intFromStr); System.out.println("Int -> String using Integer.toString : "+strFromInt); System.out.println("Int -> String using String.valueOf : "+strFromInt2); String strFromDouble = Double.toString(doubleFromStr); String strFromDouble2 = String.valueOf(doubleFromStr); System.out.println("Double -> String using Integer.toString : "+strFromDouble); System.out.println("Double -> String using String.valueOf : "+strFromDouble2); ※ 例示コード https://github.com/leeyoungseung/algorithmBasic/blob/master/algorithm/src/basic/B_10_Wrapper.java ※ 韓国語のポストは以下のURLで確認できます。 https://koiking.tistory.com/82?category=1068655
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む