JAVA SE面向对象编程之final

Posted xingshouzhan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA SE面向对象编程之final相关的知识,希望对你有一定的参考价值。

1.final修饰那些量

  a.修饰类(不能与abstract同时使用;final修饰的类不能有子类)

  b.修饰方法(不能与abstract同时使用;可以和static修饰类方法;访问修饰符可以为private,但是无意义;final方法不能重写)

  c.实例变量(获得初始值后不能重新赋值。可以定义时就给赋值,也初始化代码块赋值,也可以构造数赋值不能不赋值,赋值后也不能重新赋值)

  d.类变量(获得初始值后不能重新赋值。可以定义时就给赋值,也初始化代码块赋值不能不赋值,赋值后也不能重新赋值)

  e.形参(不能再在方法里面赋值)

  f.局部变量(程序不会给局部变量赋初始值,final修饰局部变量可以定义时就给赋值,或者定义后赋值)

  g.修饰引用变量,只保证引用变量地址不变,内部值可以改变

 

2.final还未赋初值时不能直接访问,但可以用方法访问

public class FinalErrorTest
{
    // 定义一个final修饰的实例变量
    // 系统不会对final成员变量进行默认初始化
    final int age;
    {
        // age没有初始化,所以此处代码将引起错误。
//        System.out.println(age);
        printAge();
        age = 6;
        System.out.println(age);
    }
    public void printAge(){
        System.out.println(age);
    }
    public static void main(String[] args)
    {
        new FinalErrorTest();
    }
}

 

3.无论final修饰的是类变量,实例变量还是局部变量,若定义该变量时直接赋值,值在编译阶段能确定下来,则这个final修饰的变量就是一个直接量(宏替换)

  如果是表达式赋值,表达式中是基本的算术表达式或者字符串连接,这种final变量也将会成为一个直接量

若无final修饰

public class FinalReplaceTest {
    public static void main(String[] args)
    {
        String a="testa";
        System.out.println(a);
    }
}

使用javap -c查看反编译结果

final修饰,定义时赋值,且值在编译期能确定

public class FinalReplaceTest {
    public static void main(String[] args)
    {
        final String a="testa";
        System.out.println(a);
    }
}

使用javap -c查看反编译结果

下面也会进行宏替换

public class FinalReplaceTest {
    public static void main(String[] args)
    {
        final int a = 5 + 2;
        final double b = 1.2 / 3;
        final String str = "疯狂" + "Java";
        final String book = "疯狂Java讲义:" + 99.0;
    }
}

 

4.不可变类,指创建类的实例后,实例的实例变量不可以改变(8中包装类和java.lang.String为不可变类)

  a.实例变量使用final和private修饰(final修饰,无法修改;一般实例变量使用private,进行封装)

    b.提供代参构造器,来初始化实例变量(初始化实例变量的一种方法)

  c.为该变量提供getter方法,不提供setter方法(没方法修改)

  e.如有必要,重写hascode()和equals()方法

 

5.缓存实例的不可变类

 

题目

1.判断用字母标识的地方那些那些赋值是正确的,那些事错误的

public class FinalLocalVariableTest
{
    public void test(final int a)
    {
         a = 5; //a
    }
    public static void main(String[] args)
    {
        final String str = "hello"; //b
        str = "Java";//c
        final double d;//d
        d = 5.6;//e
        d = 3.4;//f
    }
}

 

2.引用变量赋值

class Person
{
    private int age;
    public Person(){}
    // 有参数的构造器
    public Person(int age)
    {
        this.age = age;
    }
    // 省略age的setter和getter方法
    // age的setter和getter方法
    public void setAge(int age)
    {
        this.age = age;
    }
    public int getAge()
    {
        return this.age;
    }
}
public class FinalReferenceTest
{
    public static void main(String[] args)
    {
        // final修饰数组变量,iArr是一个引用变量
        final int[] iArr = {5, 6, 12, 9};
        System.out.println(Arrays.toString(iArr));
        // 对数组元素进行排序,合法
        Arrays.sort(iArr);
        System.out.println(Arrays.toString(iArr));
        // 对数组元素赋值,合法
        iArr[2] = -8;
        System.out.println(Arrays.toString(iArr));
        // 下面语句对iArr重新赋值,非法
        // iArr = null;
        // final修饰Person变量,p是一个引用变量
        final Person p = new Person(45);
        // 改变Person对象的age实例变量,合法
        p.setAge(23);
        System.out.println(p.getAge());
        // 下面语句对p重新赋值,非法
        // p = null;
    }
}

 

3写出下面程序的运行结果

public class FinalReplaceTest {
    public static void main(String[] args)
    {
        String a ="疯狂JAVA";
        String b="疯狂";
        String c="JAVA";
        String d = b+c;
        System.out.println(a == d);
        final String e="疯狂";
        final String f="JAVA";
        String g = e+f;
        System.out.println(a ==g);
        System.out.println(b==e);
    }
}

 

4.判断下面程序是否会报错

public class FinalMethodTest {
        public final void test(){}
}
class Sub extends FinalMethodTest{
    public void test(){}
}

 

5.判断下面程序是否会报错

public class FinalMethodTest {
        private final void test(){}
}
class Sub extends FinalMethodTest{
    public void test(){}
}

 

6.写一个存在两个实例变量(分别为String firstName,String lastName ),类名称为MyName的不可变类

 

7.写一个存在两个实例变量(分别为Integer age,MyName myname),类名称为Person的不可变类

 

8.编写一个缓存部分实例的不可变类

 

9.详细说明final可以修饰那些量(参考总结1)

 

答案:

1.错误    正确    错误    正确   正确   错误

3.false true true

4.会报错

5.不会报错

 

以上是关于JAVA SE面向对象编程之final的主要内容,如果未能解决你的问题,请参考以下文章

Scala 面向对象编程之继承

一脚踩进java之基础篇19——面向对象 (final,static关键字)

一脚踩进java之基础篇19——面向对象 (final,static关键字)

重学Java面向对象 之 final

JavaSE入门学习22:Java面向对象之final关键字

面向对象编程——final关键字