如何避免'局部变量可能没有被初始化'? [英] How to avoid 'the local variable may not have been initialized'?

查看:319
本文介绍了如何避免'局部变量可能没有被初始化'?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  / *这是一个根据您选择的功能/选项计算互联网广告费率的程序。 
*
*
* /

import java.util.Scanner;

public class InternetAdvertising
{
public static void main(String [] args)
{
扫描仪in = new Scanner(System.in);

int numberOfWords;

//我将两个值分配给Eclipse,建议为
float textCost = 0;
float linkCost = 0;

float graphicCost;

//< = 25个字是每字$ 40的固定费用,基本费用为$ 3.00
final float TEXT_FLAT_FEE = 0.40F;
final float TEXT_BASE_FEE = 3.00F;

//< = 35个字是前25个字的$ .40,
//每个单词额外的$ .35,包括35个字,加上基本费用$ 3.00
final float LESS_OR_EQUAL_THAN_THIRTYFIVE = 0.35F;

//超过35个字是一个固定的费用$ 32.每个单词,没有基本费用
最终浮动MORE_THAN_THIRTYFIVE = 0.32F;


System.out.println(Welcome!);

System.out.print(输入广告中的字数);
numberOfWords = in.nextInt();

if(numberOfWords< = 25)
{
textCost = TEXT_BASE_FEE +(TEXT_FLAT_FEE * numberOfWords);
}

else if(numberOfWords< = 35)
{
textCost = TEXT_BASE_FEE +(TEXT_FLAT_FEE * 25)+(numberOfWords - 25)* LESS_OR_EQUAL_THAN_THIRTYFIVE;
}

else if(numberOfWords> 35)
{
textCost = numberOfWords * MORE_THAN_THIRTYFIVE;
}


String addLink,advancePay;
char link,advPay;

final float LINK_FLAT_FEE = 14.95F;
final float THREE_MONTH_ADV_DISCOUNT = 0.10F;

System.out.print(你想添加一个链接(y = yes或n = no)?);
addLink = in.next();

link = addLink.charAt(0);
link = Character.toLowerCase(link);

if(link =='y')
{
System.out.print(你想提前3个月支付+(y =是或n =否)?);
advancePay = in.next();

advPay = advancePay.charAt(0);
advPay = Character.toLowerCase(advPay);

switch(advPay)
{
case'y':

linkCost =(3 * LINK_FLAT_FEE) - (3 * LINK_FLAT_FEE)* THREE_MONTH_ADV_DISCOUNT;

break;

case'n':

linkCost = LINK_FLAT_FEE;

break;
}
}

else
{
linkCost = 0;
}


String addGraphic;
char图形;

System.out.print(你想添加图形/图片+(S =小,M =中,L =大或N =无)?
addGraphic = in.next();

graphic = addGraphic.charAt(0);
graphic = Character.toUpperCase(graphic);
graphic = Character.toLowerCase(graphic);
开关(图形)
{
case's':

graphicCost = 19.07F;

break;

case'm':

graphicCost = 24.76F;

break;

case'l':

graphicCost = 29.33F;

break;

默认值:
graphicCost = 0;
}


float gst,totalBeforeGst,totalAfterGst;

final float GST_RATE = 0.05F;

totalBeforeGst = textCost + linkCost + graphicCost; // textCost& linkCost不会初始化

gst = totalBeforeGst * GST_RATE;

totalAfterGst = totalBeforeGst +(totalBeforeGst * GST_RATE);


System.out.printf(\t\t%-16s%11s\\\
,类别,成本);
System.out.printf(\t\t%-16s%11.2f\\\
,Text,textCost); // linkCost不会初始化
System.out.printf(\t\t%-16s%11.2f\\\
,Link,linkCost); // textCost不会初始化
System.out.printf(\t\t%-16s%11.2f\\\
,Graphic,graphicCost);
System.out.printf(\t\t%-16s%11.2f\\\
,Total,totalBeforeGst);
System.out.printf(\t\t%-16s%11.2f\\\
,GST,gst);
System.out.printf(\t\t%-16s%11.2f\\\
,Total with GST,totalAfterGst);
}
}

我几乎完成了这个代码,Eclipse建议我将0值分配给 textCost linkCost 。有没有其他方法来解决这个问题。如果我没有分配0个值,则会得到一个错误(局部变量XXX可能未被初始化)。有人可以向我解释为什么会发生这种情况,即使我有两个变量分配方程?



谢谢。



编辑:我做过的建议,只有当我需要它时才声明变量。我还添加了一些意见。

解决方案

在我深入了解代码之前,有三个建议:




  • 尽可能晚地声明变量,以便更容易理解代码。

  • 重构这个巨大的方法 - 这是不可思议的巨大这一刻。

  • 使常量 static final 字段。它们与该方法的任何特定调用无关,因此不应该是本地变量。



现在关于实际问题,最简单的方法是确保每个可能的流实际上分配一个值或抛出一个异常。因此,对于 textCost ,将代码更改为:

  if(numberOfWords< ; = 25)
{
textCost = TEXT_BASE_FEE +(TEXT_FLAT_FEE * numberOfWords);
}
else if(numberOfWords< = 35)
{
textCost = TEXT_BASE_FEE +(TEXT_FLAT_FEE * 25)+(numberOfWords - 25)*
LESS_OR_EQUAL_THAN_THIRTYFIVE;
}
else //注 - 无条件。
{
textCost = numberOfWords * MORE_THAN_THIRTYFIVE;
}

对于 linkCost 将switch语句更改为:

  switch(advPay)
{
case'y'
linkCost =(3 * LINK_FLAT_FEE) -
(3 * LINK_FLAT_FEE)* THREE_MONTH_ADV_DISCOUNT;
break;
case'n':
linkCost = LINK_FLAT_FEE;
break;
default:
throw new异常(指定的无效值+ advPay);
}

现在您可能不想在此处抛出异常。你可能想再次循环,或者像这样的事情。您可能不要只想使用裸露的异常 - 但您应该考虑您所做的确切的异常类型想要使用。



总是可以这样做。编译器确定确定赋值的规则相对简单。如果您真的无法更改代码以使编译器快乐如此,您可以分配一个虚拟的初始值。尽管如此,我建议尽量避免这种情况。在第一种情况下,值总是被分配 - 但是在第二种情况下,当 advPay 不是时,您确实不是 'y'或'n'可能导致以后难以诊断的问题。编译器错误有助于您发现这种问题。



同样,我强烈建议您重构这种方法。我怀疑你会发现很容易理解,为什么在每个方法中只有大约10行代码被理解时,以及当每个变量在第一次使用之前或之前被声明时,为什么没有明确地分配。 p>

编辑:



好的,从根本上重构的代码如下。我不会声称它是世界上最好的代码,但是:




  • 它更可测试。您可以轻松地为其每个部分编写单元测试。 printAllCosts 不是很容易测试,但是你可能有一个超负荷,它花费了一个 Writer 打印到 - 帮助。

  • 计算的每一位都是合乎逻辑的。链接和图形具有一小组可能的值 - Java枚举在这里是一个很自然的契合。 (我知道他们可能超出了你目前的技能水平,但很高兴看到可用的内容。)

  • 我不再使用二进制浮点数,因为他们不适合数字。相反,我正在使用整数数,并转换为 BigDecimal 以进行显示。有关更多信息,请参阅我关于 .NET浮点数的文章 - 它与Java真正相关

  • 广告本身现在封装在一个类中。您可以随时随地添加更多信息。

  • 代码在一个包中。诚然,这一切都在一个文件中(这就是为什么只有 EntryPoint 类是public),但这只是为了堆栈溢出,我不必打开Eclipse

  • 有JavaDoc解释发生了什么 - 至少对于几种方法。 (我可能会添加一些更多的真实代码,我在这里用完了。)

  • 我们验证用户输入,除了单词计数,我们在单一程序,应该是合理可测试的。我们可以假设每当我们要求输入时,我们都有一些有效的东西。

  • EntryPoint 有点吓人。它不觉得可怕的OO - 但我发现这通常是一个程序的切入点。请注意,这里与费用无关 - 基本上只是用户界面。



有这里的代码比以前更多 - 但是(IMO)的可读性和可维护性更高。

 包广告; 

import java.util.Scanner;
import java.math.BigDecimal;

/ **广告的图形风格。 * /
enum图形
{
NONE(0),
SMALL(1907),
MEDIUM(2476),
LARGE(2933);

private final int cost;

private Graphic(int cost)
{
this.cost = cost;
}

/ **返回以分为单位的成本。 * /
public int getCost()
{
return cost;
}
}

/ **广告的链接支付计划。 * /
枚举LinkPlan
{
NONE(0),
PREPAID(1495),// 1个月
POSTPAID(1495 * 3 - (1495 * 3) / 10); //前3个月10%的折扣

私人最终int成本;

private LinkPlan(int cost)
{
this.cost = cost;
}

/ **返回以分为单位的成本。 * /
public int getCost()
{
return cost;
}
}

类广告
{
private final int wordCount;
私人终端LinkPlan linkPlan;
私人最终图形图形;

public Advertisement(int wordCount,LinkPlan linkPlan,Graphic graphic)
{
this.wordCount = wordCount;
this.linkPlan = linkPlan;
this.graphic = graphic;
}

/ **
*返回广告中的单词费用,以美分为单位。
*
*最多25个字,每单位费用为40c,基础费
*为3.00美元。
*
*对于26-35个单词,前25个单词的费用如前所述,
*,但单词费用降至35c,单词26-35。
*
*对于超过35个字,每单位费用为32c,没有
*基础费用。
* /
public int getWordCost()
{
if(wordCount> 35)
{
return 32 * wordCount;
}
//一律支付固定费用,最多25个字,40美分,
//,其余则为35美分。
返回300 + Math.min(wordCount,25)* 40
+ Math.min(wordCount - 25,0)* 35;
}

/ **
*显示与此广告相关的费用。
* /
public void printAllCosts()
{
System.out.printf(\t\t%-16s%11s\\\
,Category ,成本);
printCost(Text,getWordCost());
printCost(Link,linkPlan.getCost());
printCost(Graphic,graphic.getCost());
int total = getWordCost()+ linkPlan.getCost()+ graphic.getCost();
printCost(Total,total);
int gst = total / 20;
printCost(GST,gst);
printCost(Total with GST,total + gst);
}

private void printCost(String category,int cents)
{
BigDecimal dollars = new BigDecimal(cents).scaleByPowerOfTen(-2);
System.out.printf(\t\t%-16s%11.2f\\\
,category,dollars);
}
}

/ **
*程序的入口点 - 用户输入,构建
*广告,并显示其成本。
* /
public class EntryPoint
{
public static void main(String [] args)
{
扫描仪扫描仪=新的扫描仪);

System.out.println(欢迎!);
int wordCount = readWordCount(scanner);
LinkPlan linkPlan = readLinkPlan(scanner);
图形图形= readGraphic(扫描仪);

广告广告=新广告(wordCount,linkPlan,图形);
advert.printAllCosts();
}

private static int readWordCount(扫描仪扫描仪)
{
System.out.print(输入广告中的字数);
//可以在这里添加验证码
return scanner.nextInt();
}

私有静态LinkPlan readLinkPlan(扫描仪扫描仪)
{
System.out.print(你想添加一个链接(y = yes或n =否)?);
char addLink = readSingleCharacter(scanner,yn);
LinkPlan linkPlan;
if(addLink =='n')
{
return LinkPlan.NONE;
}
System.out.print(你想提前3个月支付+
(y = yes或n = no)?);
char advancePay = readSingleCharacter(scanner,yn);
return advancePay =='y'? LinkPlan.PREPAID:LinkPlan.POSTPAID;
}

私人静态图形readGraphic(扫描仪扫描仪)
{
System.out.print(你想添加图形/图片?+
(s = small,m = medium,l = large或n = None)?);
char graphic = readSingleCharacter(scanner,smln);
开关(图形)
{
case's':return Graphic.SMALL;
case'm':return Graphic.MEDIUM;
case'l':return Graphic.LARGE;
case'n':return Graphic.NONE;
default:
throw new IllegalStateException(Unexpected state; graphic =+
graphic);
}
}

private static char readSingleCharacter(扫描仪扫描器,
String validOptions)
{
while(true)
{
String input = scanner.next();
if(input.length()!= 1 ||!validOptions.contains(input))
{
System.out.print(无效值,请重试:);
继续;
}
return input.charAt(0);
}
}
}


/*This is a program that calculates Internet advertising rates based on what features/options you choose.
 * 
 *  
 */

import java.util.Scanner;

public class InternetAdvertising 
{
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);

        int numberOfWords;      

        //I assigned 0 values to both as Eclipse suggested
        float textCost = 0;
        float linkCost = 0;     

        float graphicCost;

        //<=25 words is a flat fee of $.40 per word plus Base fee of $3.00 
        final float TEXT_FLAT_FEE = 0.40F;
        final float TEXT_BASE_FEE = 3.00F;

        //<=35 words is $.40 for the first 25 words and 
        //an additional $.35 per word up to and including 35 words plus Base fee of $3.00 
        final float LESS_OR_EQUAL_THAN_THIRTYFIVE = 0.35F;

        //Over 35 words is a flat fee of $.32 per word with no base fee
        final float MORE_THAN_THIRTYFIVE = 0.32F;


        System.out.println("Welcome!");

        System.out.print("Enter the number of words in your ad: ");
        numberOfWords = in.nextInt();

        if (numberOfWords <= 25)
        {
            textCost = TEXT_BASE_FEE + (TEXT_FLAT_FEE * numberOfWords);
        }

        else if (numberOfWords <= 35)
        {
            textCost = TEXT_BASE_FEE + (TEXT_FLAT_FEE * 25) + (numberOfWords - 25) * LESS_OR_EQUAL_THAN_THIRTYFIVE;
        }

        else if (numberOfWords > 35)
        {
            textCost = numberOfWords * MORE_THAN_THIRTYFIVE;
        }


        String addLink, advancePay;
        char link, advPay;

        final float LINK_FLAT_FEE = 14.95F;
        final float THREE_MONTH_ADV_DISCOUNT = 0.10F;

        System.out.print("Would you like to add a link (y = yes or n = no)? ");
        addLink = in.next();

        link = addLink.charAt(0);
        link = Character.toLowerCase(link); 

        if (link == 'y')
        {
            System.out.print("Would you like to pay 3 months in advance " + "(y = yes or n = no)? ");
            advancePay = in.next();

            advPay = advancePay.charAt(0);
            advPay = Character.toLowerCase(advPay);

            switch (advPay)
            {
                case 'y':

                    linkCost = (3 * LINK_FLAT_FEE) - (3 * LINK_FLAT_FEE) * THREE_MONTH_ADV_DISCOUNT;

                    break;

                case 'n':

                    linkCost = LINK_FLAT_FEE;

                    break;
            }               
        }

        else
        {
            linkCost = 0;
        }


        String addGraphic;
        char graphic;

        System.out.print("Would you like to add graphics/pictures" + "(S = Small, M = Medium, L = Large or N = None)? ");
        addGraphic = in.next();

        graphic = addGraphic.charAt(0);
        graphic = Character.toUpperCase(graphic);
        graphic = Character.toLowerCase(graphic);       
        switch (graphic)
        {
            case 's':

                graphicCost = 19.07F;

                break;

            case 'm':

                graphicCost = 24.76F;

                break;

            case 'l':

                graphicCost = 29.33F;

                break;

            default:
                graphicCost = 0;
        }


        float gst, totalBeforeGst, totalAfterGst;

        final float GST_RATE = 0.05F;

        totalBeforeGst = textCost + linkCost + graphicCost; //textCost & linkCost would not initialize

        gst = totalBeforeGst * GST_RATE;

        totalAfterGst = totalBeforeGst + (totalBeforeGst * GST_RATE);


        System.out.printf("\t\t%-16s %11s\n", "Category", "Cost");
        System.out.printf("\t\t%-16s %11.2f\n", "Text", textCost);  //linkCost would not initialize
        System.out.printf("\t\t%-16s %11.2f\n", "Link", linkCost);  //textCost would not initialize 
        System.out.printf("\t\t%-16s %11.2f\n", "Graphic", graphicCost);
        System.out.printf("\t\t%-16s %11.2f\n", "Total", totalBeforeGst);
        System.out.printf("\t\t%-16s %11.2f\n", "GST", gst);
        System.out.printf("\t\t%-16s %11.2f\n", "Total with GST", totalAfterGst);
    }   
}

I'm almost done with this code and Eclipse suggests that I assign 0 values to textCost and linkCost. Is there any other way to go around this problem. If I don't assign 0 values they get an error (The local variable XXX may not have been initialized). Can someone explain to me why this happens even though I have both variables assigned with equations?

Thanks.

EDIT: I did as suggested and declared the variables only when I'm going to need it. I also added some comments.

解决方案

Three suggestions before I delve any deeper into the code:

  • Declare variables as late as you can to make it easier to understand the code.
  • Refactor this giant method - it's unreadably huge at the moment.
  • Make the constants static final fields. They're not related to any particular call to the method, so they shouldn't be local variables.

Now as to the actual question, the simplest way is to make sure that every possible flow actually does assign a value or throw an exception. So for textCost, change your code to:

if (numberOfWords <= 25)
{
    textCost = TEXT_BASE_FEE + (TEXT_FLAT_FEE * numberOfWords);
}
else if (numberOfWords <= 35)
{
    textCost = TEXT_BASE_FEE + (TEXT_FLAT_FEE * 25) + (numberOfWords - 25) * 
               LESS_OR_EQUAL_THAN_THIRTYFIVE;
}
else // Note - no condition.
{
    textCost = numberOfWords * MORE_THAN_THIRTYFIVE;
}

For linkCost, change your switch statement to something like:

switch (advPay)
{
    case 'y':
        linkCost = (3 * LINK_FLAT_FEE) - 
                   (3 * LINK_FLAT_FEE) * THREE_MONTH_ADV_DISCOUNT;
        break;
    case 'n':
        linkCost = LINK_FLAT_FEE;
        break;
    default:
        throw new Exception("Invalid value specified: " + advPay);
}

Now you may not want to throw an exception here. You might want to loop round again, or something like that. You probably don't want to use just bare Exception - but you should think about the exact exception type you do want to use.

It's not always possible to do this. The rules by the compiler to determine definite assignment are relatively straightforward. In cases where you really can't change the code to make the compiler happy like this, you can just assign a dummy initial value. I'd recommend trying to avoid this wherever possible though. In your first case, the value really would always be assigned - but in the second case you really weren't giving a value when advPay was neither 'y' nor 'n' which could lead to a hard-to-diagnose problem later on. The compiler error helps you spot this sort of problem.

Again though, I strongly suggest you refactor this method. I suspect you'll find it a lot easier to understand why things aren't definitely assigned when there's only about 10 lines of code to reason about in each method, and when each variable is declared just before or at its first use.

EDIT:

Okay, the radically refactored code is below. I'm not going to claim it's the best code in the world, but:

  • It's more testable. You could easily write unit tests for each part of it. printAllCosts isn't terribly easily testable, but you could have an overload which took a Writer to print to - that would help.
  • Each bit of calculation is in a logical place. Links and graphics have a small set of possible values - Java enums are a natural fit here. (I'm aware they may well be beyond your current skill level, but it's good to see what will be available.)
  • I'm not using binary floating point numbers any more, because they're inappropriate for numbers. Instead, I'm using an integer number of cents everywhere and converting to BigDecimal for display purposes. See my article on .NET floating point for more information - it's all relevant to Java really.
  • The advert itself is now encapsulated in a class. You could add a lot more information here as and when you needed to.
  • The code is in a package. Admittedly it's all in one file at the moment (which is why only the EntryPoint class is public) but that's just for the sake of Stack Overflow and me not having to open up Eclipse.
  • There's JavaDoc explaining what's going on - at least for a few methods. (I would probably add some more in real code. I'm running out of time here.)
  • We validate user input, except for the word count - and we perform that validation in a single routine, which should be reasonably testable. We can then assume that whenever we've asked for input, we've got something valid.
  • The number of static methods in EntryPoint is slightly alarming. It doesn't feel terribly OO - but I find that's often the way around the entry point to a program. Note that there's nothing to do with fees in there - it's just the user interface, basically.

There's more code here than there was before - but it's (IMO) much more readable and maintainable code.

package advertising;

import java.util.Scanner;
import java.math.BigDecimal;

/** The graphic style of an advert. */
enum Graphic
{
    NONE(0),
    SMALL(1907),
    MEDIUM(2476),
    LARGE(2933);

    private final int cost;

    private Graphic(int cost)
    {
        this.cost = cost;
    }

    /** Returns the cost in cents. */
    public int getCost()
    {
        return cost;
    }
}

/** The link payment plan for an advert. */
enum LinkPlan
{
    NONE(0),
    PREPAID(1495), // 1 month
    POSTPAID(1495 * 3 - (1495 * 3) / 10); // 10% discount for 3 months up-front

    private final int cost;

    private LinkPlan(int cost)
    {
        this.cost = cost;
    }

    /** Returns the cost in cents. */
    public int getCost()
    {
        return cost;
    }
}

class Advertisement
{
    private final int wordCount;
    private final LinkPlan linkPlan;
    private final Graphic graphic;

    public Advertisement(int wordCount, LinkPlan linkPlan, Graphic graphic)
    {
        this.wordCount = wordCount;
        this.linkPlan = linkPlan;
        this.graphic = graphic;
    }

    /**
     * Returns the fee for the words in the advert, in cents.
     * 
     * For up to 25 words, there's a flat fee of 40c per word and a base fee
     * of $3.00.
     * 
     * For 26-35 words inclusive, the fee for the first 25 words is as before,
     * but the per-word fee goes down to 35c for words 26-35.
     * 
     * For more than 35 words, there's a flat fee of 32c per word, and no
     * base fee.     
     */
    public int getWordCost()
    {
        if (wordCount > 35)
        {
            return 32 * wordCount;
        }
        // Apply flat fee always, then up to 25 words at 40 cents,
        // then the rest at 35 cents.
        return 300 + Math.min(wordCount, 25) * 40
                   + Math.min(wordCount - 25, 0) * 35;        
    }

    /**
     * Displays the costs associated with this advert.
     */
    public void printAllCosts()
    {
        System.out.printf("\t\t%-16s %11s\n", "Category", "Cost");
        printCost("Text", getWordCost());
        printCost("Link", linkPlan.getCost());
        printCost("Graphic", graphic.getCost());
        int total = getWordCost() + linkPlan.getCost() + graphic.getCost();
        printCost("Total", total);
        int gst = total / 20;
        printCost("GST", gst);
        printCost("Total with GST", total + gst);
    }

    private void printCost(String category, int cents)
    {
        BigDecimal dollars = new BigDecimal(cents).scaleByPowerOfTen(-2);
        System.out.printf("\t\t%-16s %11.2f\n", category, dollars);
    }
}

/**
 * The entry point for the program - takes user input, builds an 
 * Advertisement, and displays its cost.
 */
public class EntryPoint
{
    public static void main(String[] args)
    {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Welcome!");
        int wordCount = readWordCount(scanner);
        LinkPlan linkPlan = readLinkPlan(scanner);
        Graphic graphic = readGraphic(scanner);

        Advertisement advert = new Advertisement(wordCount, linkPlan, graphic);
        advert.printAllCosts();
    }

    private static int readWordCount(Scanner scanner)
    {
        System.out.print("Enter the number of words in your ad: ");
        // Could add validation code in here
        return scanner.nextInt();
    }

    private static LinkPlan readLinkPlan(Scanner scanner)
    {
        System.out.print("Would you like to add a link (y = yes or n = no)? ");
        char addLink = readSingleCharacter(scanner, "yn");
        LinkPlan linkPlan;
        if (addLink == 'n')
        {
            return LinkPlan.NONE;
        }
        System.out.print("Would you like to pay 3 months in advance " +
                         "(y = yes or n = no)? ");
        char advancePay = readSingleCharacter(scanner, "yn");
        return advancePay == 'y' ? LinkPlan.PREPAID : LinkPlan.POSTPAID;
    }

    private static Graphic readGraphic(Scanner scanner)
    {
        System.out.print("Would you like to add graphics/pictures? " +
            "(s = small, m = medium, l = large or n = None)? ");
        char graphic = readSingleCharacter(scanner, "smln");
        switch (graphic)
        {
            case 's': return Graphic.SMALL;
            case 'm': return Graphic.MEDIUM;
            case 'l': return Graphic.LARGE;
            case 'n': return Graphic.NONE;
            default:
                throw new IllegalStateException("Unexpected state; graphic=" +
                                                graphic);
        }
    }

    private static char readSingleCharacter(Scanner scanner,
                                            String validOptions)
    {
        while(true)
        {
            String input = scanner.next();
            if (input.length() != 1 || !validOptions.contains(input))
            {
                System.out.print("Invalid value. Please try again: ");
                continue;
            }
            return input.charAt(0);
        }
    }
}

这篇关于如何避免'局部变量可能没有被初始化'?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆