美文网首页
[Java][Final]

[Java][Final]

作者: lgy_gg | 来源:发表于2017-11-16 10:39 被阅读0次

1.final的作用

final的作用是使被修饰的目标无法改变。final可以修饰变量,方法和类。

2.final修饰参数

Student对象

public class Student
{

    private int id;
    private String name;
    private int age;
    public int getId()
    {
        return id;
    }
    public void setId(int id)
    {
        this.id = id;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public int getAge()
    {
        return age;
    }
    public void setAge(int age)
    {
        this.age = age;
    }
    
    @Override
    public String toString()
    {
        return "name:"+this.name+" age:"+this.age;
    }
}

测试例子

/**
 * @author LGY
 * @time 2017-11-9
 * @action 
 * Java编程思想第四版140页是这么描述的,“对应基本类型,final使数值恒定不变,对应对象引用,final使引用恒定不变。
 * 一旦引用被初始化指向一个对象,就无法再把他改为指向另一个对象。然而对象其自身却是可以被修改的。
 * Java并未提供使任何对象恒定不变的途径(但是可以自己编写类以取得使对象恒定不变的效果)。这一限制同样适用于数组,它也是对象”
 * 
 * 对应上面这句话,我肯可以理解一旦final修饰了引用指向了一个对象,那么这个引用就不能在指向其他对象了,但是这个对象的成员变量和成员方法却是可以修改的。
 * 如果想让这个对象成员变量和成员方法都不能被修改,就需要使成员变量和成员方法被final修饰,这样就能实现让对象恒定不变的效果。
 * 这里也提到了数组也是一个对象,所以数组也是这个情况。
 * 
 * student本身指向的对象在初始化之后不能修改,但是指向的这个对象的字段可以修改
 */
public class Test2 extends Activity
{
    private final int i = 5;
    private final Integer it = 5;
    private final String string = "hello";
    private final Student student = new Student();
    private final String[] array= {"aa","bb","cc"};
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        sendData(i, it);
        Log.i("lgy", "after i:"+i+" it:"+it);
        
        sendDataTestString(string);
        Log.i("lgy", "after String:"+string);
        
        student.setAge(18);
        student.setName("lgy");
        student.setId(1);
        sendDataTestObject(student);
        Log.i("lgy", "after student:"+student.toString());
        
        
        sendDataTestArray(array);
        Log.i("lgy",array[0]+array[1]+array[2]);
    }
    private void sendData(int i,Integer it)
    {
        i++;
        it++;
        Log.i("lgy", "i:"+i+" it:"+it);
    }
    
    private void sendDataTestString(String str)
    {
        str = str+" JAVA";
        Log.i("lgy", "String:"+str);
    }
    
    private void sendDataTestObject(Student student)
    {
        student.setAge(24);
        student.setName("LGY");
        Log.i("lgy", "student:"+student.toString());
    }
    
    private void sendDataTestArray(String[] array)
    {
        String temp = "";
        for (int i = 0; i < array.length; i++)
        {
            array[i] = "ddd"+i;
        }
        for (int i = 0; i < array.length; i++)
        {
            temp = temp+array[i];
        }
        Log.i("lgy",temp);
        //这里由于array是参数的引用,也指向this.array指向的对象,但是他并没有被final修饰,所以可以改变它指向的对象,这个参数生命周期是在这个方法执行完成后就消亡了
        //所以如果我再给array初始化,那么这个引用就会指向另一个对象,那么修改array将不会改变this.array的值
        String[] strings= {"jj","jj","jj"};
        array = strings;
        temp = "";
        for (int i = 0; i < array.length; i++)
        {
            temp = temp+this.array[i];
        }
        Log.i("lgy",temp);
        //报错The final field Test2.array cannot be assigned,验证了一旦引用被初始化指向一个对象,就无法再把他改为指向另一个对象
//      String[] strings2= {"jj","jj","jj"};
//      this.array = strings;
    }
}

/*11-16 10:01:19.946: I/lgy(14797): i:6 it:6
11-16 10:01:19.946: I/lgy(14797): after i:5 it:5
11-16 10:01:19.946: I/lgy(14797): String:hello JAVA
11-16 10:01:19.946: I/lgy(14797): after String:hello
11-16 10:01:19.946: I/lgy(14797): student:name:LGY age:24
11-16 10:01:19.946: I/lgy(14797): after student:name:LGY age:24
11-16 10:01:19.946: I/lgy(14797): ddd0ddd1ddd2
11-16 10:01:19.946: I/lgy(14797): ddd0ddd1ddd2
11-16 10:01:19.946: I/lgy(14797): ddd0ddd1ddd2*/

3.final修饰方法

public class Person
{
    private String name;
    private int age;
    private int id;
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public int getAge()
    {
        return age;
    }
    public void setAge(int age)
    {
        this.age = age;
    }
    public int getId()
    {
        return id;
    }
    public final void setId(int id)
    {
        this.id = id;
    }
}

测试例子

/**
 * @author LGY
 * @time 2017-11-14
 * @action 
 * 下面这段话摘自《Java编程思想》第四版第143页:
 * 
 * “使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义.
 * 第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。
 * 但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。“
 * 因此,只有需要防任何继承类修改该方法的情况下,才考虑使用final.
 */
public class Student extends Person
{

    @Override
    public int getId()
    {
        return super.getId();
    }
    //因为在父类Person中将setId
//  public void setId(int id)
//  {
//      this.id = id;
//  }
}

4.final修饰类

public final class Person
{
    private String name;
    private int age;
    private int id;
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public int getAge()
    {
        return age;
    }
    public void setAge(int age)
    {
        this.age = age;
    }
    public int getId()
    {
        return id;
    }
    public void setId(int id)
    {
        this.id = id;
    }
}

测试例子

/**
 * @author LGY
 * @time 2017-11-14
 * @action 
 * 当用final修饰一个类时,表明这个类不能被继承。
 * final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。
 * 可以看出,下面的类无法继承Person
 */
//public class Test extends Person
//{
//
//}

5.源码地址

http://download.csdn.net/download/lgywsdy/10120946

6.参考文章

https://www.cnblogs.com/dolphin0520/p/3736238.html

相关文章

网友评论

      本文标题:[Java][Final]

      本文链接:https://www.haomeiwen.com/subject/arqfvxtx.html