为什么我需要在第4行的int empAge之前添加final关键字?

时间:2016-12-29 12:00:08

标签: java class nested

import java.util.*;

class Employee {
    public void evaluateStatus(String empID, int empAge) {
        final int age = 40;
        class Rank {
            public char getRank (String empID) {
                System.out.print("\n\tGetting rank of employee: "+empID);
                if (empAge >= 40 && empAge <= 60)
                    return 'B';
                else if (empAge >= 61)
                    return 'A';
                else
                    return 'C';
            }
        }

        if (empAge >= age) {
            Rank objRank = new Rank();
            char rank = objRank.getRank(empID);
            if (rank == 'A' || rank == 'B' || rank == 'C') {
                System.out.print("\n\tEmployee rank is: "+ rank);
                System.out.print("\n\tStatus: Eligible for upgrade.");
            } else {
                System.out.print("\n\tStatus: not eligible for upgrade.");
            }
        } else {
            System.out.print("\n\tStatus: not eligible for upgrade.");
        }
    }

    public static void main(String[] args) {
        if (args.length == 2) {
            Employee objEmp1 = new Employee();
            objEmp1.evaluateStatus(args[0], Integer.parseInt(args[1]));
        } else {
            System.out.print("\n\tError!");
        }
    }
}

我收到以下错误:

Y:\student\Desktop\Atif>javac Employee.java

Employee.java:13: error: local variable empAge is accessed from within inner class; needs to be declared final
                                if (empAge >= 40 && empAge <= 60)
                                    ^ Employee.java:13: error: local variable empAge is accessed from within inner class; needs to be declared final
                                if (empAge >= 40 && empAge <= 60)
                                                    ^ Employee.java:15: error: local variable empAge is accessed from within inner class; needs to be declared final
                                else if (empAge >= 61)  
                                    ^ 3 errors

2 个答案:

答案 0 :(得分:2)

答案几乎是因为JLS 8.1.3这样说:

  

[...]

     

使用了任何局部变量,形式参数或异常参数但是   未在内部类中声明必须声明为final。

     

[...]

在这种特殊情况下,empAge是您的formal parameter。由于它在内部类中使用,但是在方法Employee#evaluateStatus中声明,因此必须将其声明为final。 但是,你永远不会重新分配empAge宣称它为final不会造成任何伤害。

作为旁注:

由于您的班级Rank基本上只包含一个方法,我宁愿在static char getRank()范围内将其声明为Employee,如果您不打算使用Rank类本身。

答案 1 :(得分:0)

您的代码无法使用1.7版进行编译,但将使用1.8进行编译。 Java 1.7的内存管理与1.8

不同

方法局部变量分配在堆栈中,而类变量分配在中。

现在,当你想在中使用方法局部变量时 内部类,你需要将它提升到堆,因为它在类中被使用,最终的变量被分配在堆中,这就是你需要声明它最终的原因

现在为什么我们根本需要将变量从堆栈升级到堆?

原因:执行方法后堆栈的范围不再存在,但方法本地内部类的范围可以传播到方法之外。我修改了你的代码,其中方法局部内部类的范围在方法 getRank()

之外传播

您的代码(已修改):

interface SuperRank{
     public char getRank(String empID);
}

class Employee
{
    public SuperRank getRank(String empID, final int empAge){
//      final int age = 40;
        class Rank implements SuperRank
        {
            public char getRank (String empID)
            {
                System.out.print("\n\tGetting rank of employee: "+empID);
                if (empAge >= 40 && empAge <= 60)
                    return 'B';
                else if (empAge >= 61)
                    return 'A';
                else
                    return 'C';
            }
        }
        return new Rank();

    }
    public void evaluateStatus(String empID, int empAge)
    {
        SuperRank rank = getRank(empID,empAge);
        char rankChar = rank.getRank(empID);
        if (rankChar == 'A' || rankChar == 'B' || rankChar == 'C')
        {
            System.out.print("\n\tEmployee rank is: "+ rankChar);
            System.out.print("\n\tStatus: Eligible for upgrade.");
        }
        else 
        {
            System.out.print("\n\tStatus: not eligible for upgrade.");
        }
    }

    public static void main(String[] args)
    {
        if (args.length == 2)
        {
            Employee objEmp1 = new Employee();
            objEmp1.evaluateStatus(args[0], Integer.parseInt(args[1]));
        }
        else
        {
            System.out.print("\n\tError!");
        }
    }
}