日期:2014-05-20  浏览次数:20602 次

请问方法的参数如果是fianl的对象,有什么作用,为什么这样定义?
class   TTT  
{
void   change1(M   a)
{
              a.i=10;
System.out.println( "Hello   World! "+a.i);
}
void   change2(final   M   a)
{
              a.i=20;
System.out.println( "Hello   World! "+a.i);
}
}
change2中的参数是fianl类型的有什么用呢?
fianl修饰引用类型,表示此引用不可以指向其它对象,而并不是对象的值不可改变,因此上面的change1和change2中都可以改变a对象的属性。那么,讲参数用fianl修饰可以带来什么好处呢?

------解决方案--------------------
提示LZ:研究一下内部类、匿名内部类^_^
------解决方案--------------------
首先,final表示一个变量一旦初始化以后,值就不能再被更改。
对于参数设为final是一样的。要知道的是,参数的值是在实际调用的时候给的,所以在函数体中不能更改参数的值。
change2的参数为final M a,那么a在函数change2中不能再被赋予其他值,也就是说,你不能写类似于a = new M()之类的语句。但是对于a所指向的对象,当然是可以更改值的,因为尽管这样,a的值(可以看成是对象的地址)并未变化。
------解决方案--------------------
To pczhouji(咱也进城了):

这个跟内部类、匿名类似乎没什么关系吧?
------解决方案--------------------
final使得被修饰的变量 "不变 ",但是由于对象型变量的本质是“引用”,使得“不变”也有了两种含义:引用本身的不变,和引用指向的对象不变。

  引用本身的不变:

final StringBuffer a=new StringBuffer( "immutable ");
final StringBuffer b=new StringBuffer( "not immutable ");
a=b;//编译期错误

  引用指向的对象不变:

final StringBuffer a=new StringBuffer( "immutable ");
a.append( " broken! "); //编译通过

  可见,final只对引用的“值”(也即它所指向的那个对象的内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化,final是不负责的。这很类似==操作符:==操作符只负责引用的“值”相等,至于这个地址所指向的对象内容是否相等,==操作符是不管的。

  理解final问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向固定对象,不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改,一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final,意图使得它“永远不变”。其实那是徒劳的。
------解决方案--------------------
1.final用在域中时,表示为常量,即运行时变量不可修改.
2.用在方法前时,如public final methodName...指定了子类对此方法不可重写,
一般在abstract类中多用,
3.用来限定传入的参数,就是楼上所说的在ni名内部类,比如你给一个启动线程ni名内部类要传入参数,则必须是final型.
一下就想起这么多,供你参考.
________________________________________________
www.NetJava.cn 领先的.Net&Java技术推广者.
------解决方案--------------------
关系大大滴有,请注意LZ已经强调他不明白的是final出现在形参之前。
------解决方案--------------------
引用指向的对象不变:

final StringBuffer a=new StringBuffer( "immutable ");
a.append( " broken! "); //编译通过

==========
final修饰对象 仅仅是饮用不变 不是只想的对象不变

你给的例子 对象的内容变化了 赫赫

引用确实没有变 但是内容却是变化了
------解决方案--------------------
6.8.2 final方法
之所以要使用final方法,可能是出于对两方面理由的考虑。第一个是为方法“上锁”,防止任何继承类改变它的本来含义。设计程序时,若希望一个方法的行为在继承期间保持不变,而且不可被覆盖或改写,就可以采取这种做法。
采用final方法的第二个理由是程序执行的效率。将一个方法设成final后,编译器就可以把对那个方法的所有调用都置入“嵌入”调用里。只要编译器发现一个final方法调用,就会(根据它自己的判断)忽略为执行方法调用机制而采取的常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除堆栈自变量;最后对返回值进行处理)。相反,它会用方法主体内实际代码的一个副本来替换方法调用。这样做可避免方法调用时的系统开销。当然,若方法体积太大,那么程序也会变得雍肿,可能受到到不到嵌入代码所带来的任何性能提升。因为任何提升都被花在方法内部的时间抵消了。Java编译器能自动侦测这些情况,并颇为“明智”地决定是否嵌入一个final方法。然而,最好还是不要完全相信编译器能正确地作出所有判断。通常,只有在方法的代码量非常少,或者想明确禁止方法被覆盖的时候,才应考虑将一个方法设为final。
类内所有private方法都自动成为final。由于我们不能访问一个private方法,所以它绝对不会被其他方法覆盖(若强行这样做,编译器会给出错误提示)。可为一个private方法添加final指示符,但却不能为那个方法提供任何额外的含义。

------解决方案--------------------
final表示不可修改的
上面说了很多了
------解决方案--------------------