質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

1回答

677閲覧

ラムダ式から参照されるローカル変数は、finalまたは事実上のfinalである必要があります

K.M.PEANUTS

総合スコア40

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2022/01/17 14:04

編集2022/01/17 23:52

java

1package calcvm; 2 3import java.io.*; 4import java.util.*; 5 6import com.vaadin.flow.component.button.Button; 7import com.vaadin.flow.component.html.H2; 8import com.vaadin.flow.component.html.Label; 9import com.vaadin.flow.component.orderedlayout.HorizontalLayout; 10import com.vaadin.flow.component.orderedlayout.VerticalLayout; 11import com.vaadin.flow.component.textfield.TextField; 12import com.vaadin.flow.router.PageTitle; 13import com.vaadin.flow.router.Route; 14import com.vaadin.flow.router.RouteAlias; 15 16@PageTitle("Calc VM") 17@Route(value = "calcvm") 18@RouteAlias(value = "") 19 20public class CalcVMView extends VerticalLayout { 21 22 public CalcVMView() { 23 // 中置記法入力 24 TextField infixExpr = new TextField(); 25 infixExpr.setWidth("400px"); 26 Button translateButton = new Button("変換"); 27 Button generateButton = new Button("生成"); 28 Button executeButton = new Button("実行"); 29 30 // 後置記法出力 31 32 33 translateButton.addClickListener(e -> { 34 String str = infixExpr.getValue(); //strに中置記法の式を代入 35 Node tree = new Node(str); 36 37 //二分木に格納する 38 tree.parse(); 39 40 String str2 = tree.getExpression(""); //str2に後置記法の式を代入 41 Label postfixOut = new Label(); 42 postfixOut.setText(str2); 43 String[] data2 = str2.split(","); //カンマ区切りでdata2に格納する 44 45 46 }); 47 48 // スタックマシン命令列 49 VerticalLayout vmInsns = new VerticalLayout(); 50 int lg = str2.length(); 51 String[] strArray = str2.split(""); 52 generateButton.addClickListener(e -> { 53 vmInsns.removeAll(); 54 55 for(String s: strArray) { 56 switch (s) { 57 case "+":vmInsns.add(new Label("add")); 58 break; 59 case "-":vmInsns.add(new Label("sub")); 60 break; 61 case "*":vmInsns.add(new Label("mul")); 62 break; 63 case "/":vmInsns.add(new Label("div")); 64 break; 65 default: vmInsns.add(new Label("push " + s)); 66 } 67 } 68 vmInsns.add( 69 new Label("wrt"), 70 new Label("halt") 71 ); 72 73 }); 74 75 // 実行結果 76 Label result = new Label(); 77 executeButton.addClickListener(e -> { 78 result.setText(Integer.valueOf(out(data2)).toString()); 79 }); 80 81 add( 82 new HorizontalLayout(infixExpr, translateButton, generateButton, executeButton), 83 new H2("後置記法"), 84 postfixOut, 85 new H2("スタックマシン命令列"), 86 vmInsns, 87 new H2("実行結果"), 88 result 89 ); 90 } 91 92 public static int out(String[] data) { 93 //スタック 94 Stack<Integer> stack = new Stack<Integer>(); 95 96 Cal cal = new Cal(); 97 98 for(int i=0; i<data.length; i++) { 99 if(data[i].equals("+")) { 100 stack.add(cal.add(stack.pop(), stack.pop())); 101 continue; 102 } else if(data[i].equals("-")) { 103 stack.add(cal.sub(stack.pop(), stack.pop())); 104 continue; 105 } else if(data[i].equals("*")) { 106 stack.add(cal.mul(stack.pop(), stack.pop())); 107 continue; 108 } else if(data[i].equals("/")) { 109 stack.add(cal.div(stack.pop(), stack.pop())); 110 continue; 111 } else { 112 stack.push(Integer.parseInt(data[i])); 113 } 114 } 115 return stack.pop(); 116 } 117} 118 119

問題点①(解決済み??)

後置記法を出力部分のtranslateButton.addClickListener(e -> { }の中身の変数str,Node,str2,data2等で、『ラムダ式から参照されるローカル変数は、finalまたは事実上のfinalである必要があります』というエラーが出ます。どのように変更すれば良いか教えてください。

問題点②

問題点①を踏まえて、変数の定義を全てラムダ式の中にしました。すると今度はstr2,data2,postfixOutのみが『シンボルを見つけられません』というエラーになります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2022/01/17 14:23

ラムダ式によりそのように表示されたということであれば、無名クラスの書き方に変えてみては如何でしょうか。
jimbe

2022/01/17 14:39

先回りになりますが、 「内部クラスからアクセス可能なローカル変数が final でなければならない理由」 https://happynow.hateblo.jp/entry/20120512/1336826316 という記事や記事内リンクをご理解頂けると良いかと思います。
guest

回答1

0

エラーメッセージのとおりです。ラムダに渡す変数は、finalとして宣言するか、もしくは最初1回代入してそれ以降書き換えない(これが「事実上のfinal」です)必要があります。

特に、ラムダの中から外側のローカル変数に代入することはできません。

投稿2022/01/17 14:21

maisumakun

総合スコア145123

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問