20210615のJavaに関する記事は5件です。

staticについて

staticについて JavaSilverSE11の勉強中、staticに関する問題を解いて、インスタンス変数と特徴が異なり、ややこしいと感じる点があったのでstaticについて調べてまとめてみました。 staticメンバとは? staticメンバは、staticキーワードが付けられたフィールドやメソッドのことです。 クラスに対して静的(static)に存在するメンバであるため、staticメンバは静的メンバとも呼ばれます。 インスタンスメンバとの違い まずは異なる点をインスタンスメンバとstaticメンバの定義をもとにコードを通して紹介します。 class Sample { int instanceNumber; static int staticNumber; void instanceMethod() { System.out.println("instanceMethod()" + instanceNumber); } static void staticMethod() { System.out.println("staticMethod()" + staticNumber); } } 上記のinstanceNumberはインスタンス変数、staticNumberはstatic変数です。 また、instanceMethod()はインスタンスメソッド、staticMethod()はstaticメソッドです。 インスタンスメンバとstaticメンバの違いは一見staticの有無だけのように見えますが、それだけではありません。 インスタンスメンバとstaticメンバの違いはメモリの保存場所もあります。 例えば、インスタンスメンバは1つのクラスから3つのインスタンスを生成すれば「インスタンスメンバの数×3つ分」の領域が確保されるなど、 インスタンスメンバはクラスのインスタンス(オブジェクト)ごとに確保されます。 一方、staticメンバは例え複数インスタンスを生成してもstaticメンバの数1つ分の領域が確保されるだけです。 なぜならstaticメンバはクラス単位で領域が確保されるからです。 staticメンバの呼び出し方 staticフィールドやstaticメソッドの呼び出し方について紹介します。 【staticフィールドの呼び出し方】 クラス名.staticフィールド名 【staticメソッドの呼び出し方】 クラス名.staticメソッド名() staticメンバはクラス単位で領域が確保されているため、クラス名を記述します。 これは、staticメンバはクラスが読み込まれた時点でメモリ上に展開されるからです。 staticのメリット staticを使用することで以下のメリットがあります。 newを書くことなく、手軽に呼び出せる。 多くインスタンスを生成することを防ぎ、開発者の負担を減らすことが出来ます。 メモリの消費を抑える。 インスタンスの生成は多くメモリを消費しますが、staticはインスタンスを生成しないため メモリの消費を抑えることが出来ます。 staticの注意点 staticには様々な制約があり、使用時には注意が必要です。 まず以下のコードを見てください。 public class Sample { String instanceTmp; static int staticNumber; public static void staticMethod() { Sample.staticNumber = (int)(Math.random() * 1000); System.out.println(this.instanceTmp); //エラー発生 } } 上記コードの処理はコメント記載部分でエラーとなります。 staticMethod()はstaticメソッドであるため、Sampleクラスのインスタンスが存在しない状況でも呼び出される場合があります。 Sampleクラスのインスタンスが存在しない状況でstaticMethod()の処理をすると、「this.instanceTmp」をうまく処理出来なくなります。 そのため、staticメソッド内では、staticメンバしか利用できないことに注意してください。 まとめ staticには以下の特徴があります。特徴をしっかり把握し、インスタンスメンバと使い分けることが大切になってきます。 ・フィールドやメソッドにstaticをつけて宣言するとstaticメンバ(静的メンバ)として扱われる。 ・staticメンバはクラス内に領域が確保される。 ・インスタンスを生成しなくても利用できる。 ・staticメソッド内では、staticメンバしか利用できない。 参考文献 [https://www.sejuku.net/blog/22426] [https://hrzine.jp/article/detail/48]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

karateでREST APIのテストをする。REST-Assuredとのソース比較も

はじめに Web UIとREST APIのテストフレームワークを探しているときにkarateという、とても興味のそそられるフレームワークを見つけたので使い方や便利なところをまとめます。 環境 IntelliJ:2020.1.3 Java:11 Gradle:7.0 環境作成 IntelliJのインストール 公式のホームページからインストーラーをダウンロードしてインストールしてください。 プロジェクトの作成 ファイルタブ > 新規 > プロジェクト を選択してプロジェクト作成ウィンドウを開いてください。 Gradle > Java を選択してJavaプロジェクトの作成 これでプロジェクトの作成が完了しました。 必要なライブラリの追加 build.gradleにコンパイル時のkarateの追加とJUnit platform を使う設定をします。 dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' } を下のように修正してください。 test { useJUnitPlatform() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' testCompile 'com.intuit.karate:karate-junit5:1.0.1' testImplementation('org.junit.jupiter:junit-jupiter') } スクリプトパスの追加 featureファイルを読み込ませるために、テストパスの場所を追加します。 sourceSets { test { resources { srcDir file('src/test/java') exclude '**/*.java' } } } テストソースの作成 karateは、テスティングフレームワークと組み合わせて使用します。今回はJUnit5と組み合わせます。 基本的にJUnitがJavaファイルを認識して、Javaファイルからテスト内容の書かれているfeatureを読み取りテストを実行します。 Javaファイルの作成 JUnitから読み込まれるJavaファイルを作成します。 package com.karate.api; import com.intuit.karate.junit5.Karate; // JUnitに読み込ませる関数を定義 class PetsTest { @Karate.Test Karate petsTest() { // pets.featureを読み取るように定義 return Karate.run("pets").relativeTo(getClass()); } } featureファイルの作成 実際のテストコードをfeatureファイルに記載していきます。ファイルの場所は上のクラスファイルと同じディレクトリにしてください。今回は例としてhttp://localhost:8081/Petsのテストをしています。 Feature: sample karate test script # ここにテスト対象のURLを指定 Background: * url 'http://localhost:8081' Scenario: pets get request # urlのパスを指定 Given path 'Pets' # GETメソッドを定義 When method get # 戻り値がhttpステータス200であることのチェック Then status 200 # 戻り値のデータのチェック And match $ == [{"name":"pochi", "age": 2, "kind": "dog"}] Scenario: pets get request add param Given path 'Pets' # queryパラメータの設定。/Pets?kind=cat&name=tama And param kind = 'cat' And param name = 'tama' When method get Then status 200 And match $ == [{"name":"tama", "age": 4, "kind": "cat"}] Given path 'Pets' # queryパラメータの設定。/Pets?kind=dog&name=tama And param kind = 'dog' And param name = 'tama' When method get Then status 200 And match $ == [{"name":"tama", "age": 2, "kind": "dog"}] Scenario: pets post request Given path 'Pets' # リクエストボディの設定 And request [{"name":"pochi", "age": 2, "kind": "dog"}] # POSTメソッドを定義 When method post Then status 200 And match $ == [{"name":"pochi", "age": 2, "kind": "dog"}] テストの実行 この2つでテストのソースを書くことが出来ました。 さっそく実行してみます。実行はgradleコマンドからもできますが、せっかくなのでIntelliJのGUIからやってみます。 Gradleウィンドウの表示 Gradleウィンドウが表示されていないときは、Gradleと書かれたところをクリックしてください。 テストの実行 Gradleウィンドウが表示されたらVertificationを開いてtestを選択してください。ここでtestがなかったり、エラーが出た場合はGradleの更新ボタンを押してください。 テストの結果確認 テストが正常に終了すると下のコンソールにpassと出るのでそれを確認します。 テストの個別結果の表示 上の例だとすべてのテスト結果が1つにまとめられていてわかりにくい場合もあるので、別の方法を紹介します。 IntelliJ上でソースやフォルダを右クリックして実行を選択するだけです。そうすることで下のように個別結果が表示されます。 さらに、プロジェクトルート/target/karate-reports配下にレポートが出力されています。 REST-Assuredとのソースの比較 REST APIのテストライブラリで有名なものとしてはREST-Assuredがあります。これとkarateを比較してみて、karateがわかりやすいのか確認してみます。 それぞれのソースコード REST-Assured RestAssured.baseURI = "http://localhost:8081"; given() .when() .get("/Pets") .then() .statusCode(200) .body("name", equalTo("pochi")) .body("age", equalTo(2)) .body("kind", equalTo("dog")); karate Feature: sample karate test script Background: * url 'http://localhost:8081' Scenario: pets get request Given path 'Pets' When method get Then status 200 And match $ == [{"name":"pochi", "age": 2, "kind": "dog"}] 感想 REST-Assuredは9行、karateは8行と書く量としてはそれほど変わりませんでした。ソースの見やすさとしてはJavaになれている人はREST-Assuredの方が見やすいのかなと思います。Javaになれていない人やインタフェースしか決めていない人にとってはkarateの方が見やすいのかなと思います。 REST-Assuredは関数の指定方法がJavaっぽい上に、いかにもプログラミングという見た目をしているのでJavaになれていない人にとっては取っつきにくいかと思います。一方でkarateは定義ファイルを記載するような見た目なのである程度システムを知っている人ならば取っつきやすいかと思います。 独自関数の使用 ここまでまとめて、featureとJavaでファイルが違うのでJavaで書いた独自関数を使用しにくいので純粋なJavaを使用したライブラリの方が良いという人もいるかもしれません。そこらへんもkarateは考慮していて簡単にJava関数をfeatureファイル内で使用することができます。 Javaでの独自関数の作成 例としてDBにQueryを発行する関数を作成します。 package karate; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; public class DbUtils { private final JdbcTemplate jdbc; public DbUtils() { ResourceBundle bundle = ResourceBundle.getBundle("application"); DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl(bundle.getString("spring.datasource.url")); dataSource.setUsername(bundle.getString("spring.datasource.username")); dataSource.setPassword(bundle.getString("spring.datasource.password")); jdbc = new JdbcTemplate(dataSource); } public Object readValue(String query) { return jdbc.queryForObject(query, Object.class); } public Map<String, Object> readRow(String query) { return jdbc.queryForMap(query); } public List<Map<String, Object>> readRows(String query) { return jdbc.queryForList(query); } } featureからのJava関数の呼び出し 例としてDBにQueryを発行する関数を作成します。 Background: * url 'http://localhost:8081' # 読み取るJavaのファイルを読み込む。karateフォルダ内のDbUtilファイルを読み込む * def DbUtils = Java.type('karate.DbUtils') # インスタンスを生成する * def db = new DbUtils() Scenario: pets post request Given path 'Pets' And request [{"name":"pochi", "age": 2, "kind": "dog"}] * def post_petId = response.id # SQL発行してDBから情報取得 * def pets = db.readRows('SELECT * FROM Pets WHERE id="' + post_petId + '"') # DBとリクエストしたデータの比較 And assert pets[0].name == "pochi" And assert pets[0].kind == "dog" 終わりに 開発をするときは、ある程度Javaのことを理解しているのでkarateをREST APIのテストだけに使う場合は、そこまでメリットを感じないです。どちらかと言うと個々の機能だけを抽出して使用するのではなく、REST API・モック・UIと複数のテストにkarateを導入することで総合的に学習コストを下げたり、ソース間の統一を図りきれいなソースにするというところを期待するのかなと思います。他にも人の入れ替えが多く、Javaに対する知識が少ない人が入ってくる可能性の高いプロジェクトだとテスト作成の人手としてJavaの知識がない人も考慮にいれることができるため、導入する意味はあるのかと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SpringMVCを使って、画面遷移させる手順

SpringMVCを使って、画面遷移させる 【この記事を読むと分かること】 ➀JSPでリンクをつけられるようになる("spring:url"の利用) ②Controllerクラスを作成できるようになる ➂SpringMVCを用いて画面遷移ができるようになる 今回は、ControllerとViewのみを対象とした説明をします。 SpringMVCの基本となる「DaoxAOP」から知りたいという方は、別記事をご覧ください。(近日中に公開予定) 【目指すべき完成形】 リンク「次へ」をクリックすると、画面が変わります。 【手順】 ➀実際に表示する画面(View)のJSPを作る。 ②Controllerクラスを作る ➂コントローラでフォワードする。 【詳しい説明】 ➀実際に表示する画面(View)のJSPを作る。 今回は、リンク「次へ」を表示するJSPと、遷移後の画面を表示するJSPの2つが必要なので、新規作成をします。 今回は、それぞれnext.jsp、after.jspとします。 ★JSPでリンクをつける(spring:urlの利用) spring:url var=”任意の変数名”  value=”コンテキスト名を除くパス” ➀Taglib宣言をする 「spring:~」は、Springのカスタムタグです。 そのため、使う前にTaglib宣言が必要です。 ②任意の変数名にパスを入れる valueに入っているパスを、varで設定した変数に入ることで、他のタグで生成されたURLをEL式で参照できるようになります。 Valueに指定した、「遷移した先のパス」は自分で好きなものを設定できます。 ただし、ここで指定したパスは、ControllerクラスのHandlerメソッドでリクエストマッピングを指定する際に指定するパスと同一のものでなければいけません。 ➂EL式でリンクにする 変数のHTMLと同じように、「a href=”★”」の★に、先ほどの変数を入れます。 この際、EL式を用いることに注意しましょう! ②Controllerクラスを作る クラス宣言の前に「@Controllerアノテーション」をつけて、Controllerクラスとして機能させます。 Controllerクラスとは、リクエストを処理するクラスです。 MVCのCに当たる「Handlerメソッド」が定義されているクラスですね。 ApplicationContextに設定されると、Controllerクラスとして機能できるようになります。 ApplicationContextに設定するためには、@Controllerをつけなければなりません。 クラス宣言の前に「@Controller」と入力します。 ➂Controllerクラスで表示させたいJSPをフォワードする。 フォワードするために使うのは、Handlerメソッドです。 Handlerメソッドは、Controllerクラスと共にMVCのCに当たるControllerの役割を担います。 実質的には、HandlerメソッドがControllerです。 Handlerメソッドの定義方法は、基本的に普通のメソッド定義の形と同じですが、デフォルトのような型があります。 public String メソッド名(){ //処理内容 return “遷移先のView名”; } ちなみに、最後の「遷移先のView名」とは、遷移する先のJSPファイル名から「.jsp」を抜いた文字が入ります。 今回でいうと、JSPファイルが「next.jsp」なので、「next」がView名になります。 このように定義したメソッドを、Handlerメソッドにするには、メソッド定義の前にリクエストマッピングを指定する必要があります。 リクエストマッピングとは、Spring MVC のコントローラに付与して、リクエストURLに対して、どのメソッドが処理を実行するか定義するアノテーションのことです。 リクエストマッピングは、3種類あります。 @RequestMapping…GETとPOSTの両方を行える @GetMapping…GETのみを行う @PostMapping…POSTのみを行う リクエストマッピングは、あくまでも機能をバージョンアップしているだけに過ぎません。 そのため、リクエストマッピングをつけただけでは遷移先がわからないままなので、パスを指定してあげましょう。 指定方法は、各アノテーションの後ろに、先ほどのJSPと同様に「コンテキスト名を除くパス」を入れるだけです。 はじめの表示JSPは、”/”でOKです。 今回の場合、初めにnext.jspを表示したいので、 @RequestMapping(”/”)とします ※コンテキスト名を除くパスについて 一番初めに表示される画面(今回はnext.jsp)に関しては、基本的に「”/”」になりますが、実は自分で決めることもできます。 パス指定は、JSPの説明部分でも記載したように、たとえば、「/aaa」であっても、JSPとControllerで同じパスを指定していれば問題ありません。 初心者の私も、「この”/”はどこから来たんだ?」と、非常に理解の苦しんだ点でしたので、補足いたしました。(この「/」はコンテキストルートですね) アノテーションをつけて定義したら、フォワードの完成です。 ちなみに、フォワードではなく、リダイレクトをしたい時には、最後に返す時にreturn “redirect:view名”;に変えればOKです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScriptでJavaのorElseと同じ挙動を実装する

はじめに JavaScriptでメソッドチェーンを書いた際にundefinedを参照しエラーになることがあるので、JavaのOptionalのorElseの挙動を実装。 const hoge = undefined; // "errorType": "TypeError", // "errorMessage": "Cannot read property 'fuga' of undefined" // エラーになる const fuga = hoge.fuga.fuga; コード const hoge = undefined; // undefinedだった場合、空文字が入る。  const fuga = hoge?.fuga?.fuga || ''; || は前の式がfalse(undefined)だった場合、後ろの値が代入されます。 ?.という書き方はオプショナルチェイニングというものです。 オプショナルチェイニングoptional chaining演算子 ?. は、接続されたオブジェクトチェーンの深くに位置するプロパティの値を、チェーン内の各参照が正しいかどうかを明示的に確認せずに読み込むことを可能にします。 ?. 演算子の機能は . チェーン演算子と似ていますが、参照が nullish (null または undefined) の場合にエラーとなるのではなく、式が短絡され undefined が返されるところが異なります。 関数呼び出しで使用すると、与えられた関数が存在しない場合、 undefined を返します。 おわりに JavaScriptでメソッドチェーンで書いた際にundefined参照で落ちるということがなくなり、デフォルト値を返却できるようになります。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

隣接リスト Java編

 隣接リストをJavaで実装しようとすると、案外手間だった。  訂正すると滅茶苦茶手間だった。Javaは可変長配列の扱いが難しい……。  まともな資料もないし……もしかしてJavaで組むこと自体が想定されてないモデルだったりするのだろうか。 コード import java.util.Scanner; import java.util.ArrayList; import java.util.Collections; public class Main { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); ArrayList<ArrayList<Integer>> al = new ArrayList<ArrayList<Integer>>(); //ArrayListを二次元に for(int i=0; i<n; i++){ ArrayList<Integer> ar = new ArrayList<Integer>(); //外側のListに添え字を作るために al.add(ar); //N回、入れ物のArrayListを作っておく } for(int i=0; i<m; i++){ int a = sc.nextInt()-1; int b = sc.nextInt()-1; al.get(a).add(b); //外側Listの添え字をgetして、中のListにbをaddする al.get(b).add(a); //同様のことをする。隣接リストなので数字を入れ替える } for(int i=0; i<n; i++){ Collections.sort(al.get(i)); //外側リストの添え字ごとに中身をソートして for(int j=0; j<al.get(i).size(); j++){ System.out.print(al.get(i).get(j)); //表示 } System.out.println(""); } } } 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む