Java return 引用还是对象? Return 之前最后?
Java return reference or object? Return before finally?
让我们考虑一个测试class
import java.util.Date;
public class TestClass {
public String finallyHappensBeforeReturn(){
try{
return "Important Message";
}finally{
finallyHappensBeforeReturn();
}
}
public String unaffectedReference(){
String message = "Important msg";
try{
return message;
}finally{
message = " meaning of life";
}
}
public Container modifiedReference(){
Container c = new Container();
c.set("Important msg");
try{
return c;
}finally{
c.set("Meaning of life");
}
}
public void timer(){
try{
System.out.println("Try time = " + new Date().getTime());
}finally{
System.out.println("Finally time = " + new Date().getTime());
}
}
class Container{
String s;
void set(String s){
this.s = s;
}
String get(){
return s;
}
}
}
如果我们创建一个main方法如下:
public static void main(String[] args){
TestClass instance = new TestClass();
instance.timer();
}
我们可以清楚地看到表明 try 在 finally 之前发生的输出,正如我们所期望的那样。打印时间对我们大多数人来说有点毫无意义,因为在我和大多数其他机器上,该方法将在不到一毫秒的时间内执行,但 none 我认为 Id 包含它的时间越少。
如果我们将 main 更改为
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.unaffectedReference());
}
我们得到 "Important msg" 打印,这表明 unaffectedReference() return 是对字符串文字 "Imporant msg" 的引用,我们将它打印到控制台,只有在那之后指针才会改变指向字符串对象 "Meaning of life"。到目前为止说得通。
但是,如果我们将 main 更改为
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.modifiedReference().get());
}
我们得到 "Meaning of life"。请注意,我们不保留对 Container modifiedReference() return 的引用。所以,如果是
public static void main(String[] args){
TestClass instance = new TestClass();
Container container = instance.modifiedReference();
System.out.println(container.get());
}
这是有道理的。 modifierReference() return 是一个引用,然后进入 finally{},将对象更改为引用,嗯,引用 - 然后才打印值。那里发生什么了?最终在 System.out.print() 之前但在 return 之后执行?这怎么可能?
最后一个例子 -
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.finallyHappensBeforeReturn());
}
在这种情况下,我们得到一个 WhosebugError,这也表明最终发生在 return 之前。请注意 "Important Message" 在抛出异常之前从未打印过。
所以,问题是哪个先出现 - 最后还是 return?
与在什么之后执行什么没有太大关系(它是 try、catch、return、finally - finally 在 return 之后运行,但实际上在方法之前 returns,所以它在技术上可以修改 return 值 - 你不应该那样做)。最基本的是要知道 String 是不可变的。
public String unaffectedReference(){
String message = "Important msg";
try{
return message;
}finally{
message = " meaning of life";
}
}
这将 return "Important msg",然后将消息(在方法中)更改为“生命的意义”。但是 return 值是对字符串 "Important message" 而不是 "message" 的引用。例如,如果 String 不是不可变的并且您要执行 message.setValue(" meaning of life"),那么这将被打印出来。
public Container modifiedReference(){
Container c = new Container();
c.set("Important msg");
try{
return c;
}finally{
c.set("Meaning of life");
}
}
...您的 return 值是对 Container 对象的引用,更改此 Container 对象内部的内容会修改 return 值,当然,因为您是 return对象和此对象被修改。
让我们考虑一个测试class
import java.util.Date;
public class TestClass {
public String finallyHappensBeforeReturn(){
try{
return "Important Message";
}finally{
finallyHappensBeforeReturn();
}
}
public String unaffectedReference(){
String message = "Important msg";
try{
return message;
}finally{
message = " meaning of life";
}
}
public Container modifiedReference(){
Container c = new Container();
c.set("Important msg");
try{
return c;
}finally{
c.set("Meaning of life");
}
}
public void timer(){
try{
System.out.println("Try time = " + new Date().getTime());
}finally{
System.out.println("Finally time = " + new Date().getTime());
}
}
class Container{
String s;
void set(String s){
this.s = s;
}
String get(){
return s;
}
}
}
如果我们创建一个main方法如下:
public static void main(String[] args){
TestClass instance = new TestClass();
instance.timer();
}
我们可以清楚地看到表明 try 在 finally 之前发生的输出,正如我们所期望的那样。打印时间对我们大多数人来说有点毫无意义,因为在我和大多数其他机器上,该方法将在不到一毫秒的时间内执行,但 none 我认为 Id 包含它的时间越少。
如果我们将 main 更改为
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.unaffectedReference());
}
我们得到 "Important msg" 打印,这表明 unaffectedReference() return 是对字符串文字 "Imporant msg" 的引用,我们将它打印到控制台,只有在那之后指针才会改变指向字符串对象 "Meaning of life"。到目前为止说得通。
但是,如果我们将 main 更改为
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.modifiedReference().get());
}
我们得到 "Meaning of life"。请注意,我们不保留对 Container modifiedReference() return 的引用。所以,如果是
public static void main(String[] args){
TestClass instance = new TestClass();
Container container = instance.modifiedReference();
System.out.println(container.get());
}
这是有道理的。 modifierReference() return 是一个引用,然后进入 finally{},将对象更改为引用,嗯,引用 - 然后才打印值。那里发生什么了?最终在 System.out.print() 之前但在 return 之后执行?这怎么可能?
最后一个例子 -
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.finallyHappensBeforeReturn());
}
在这种情况下,我们得到一个 WhosebugError,这也表明最终发生在 return 之前。请注意 "Important Message" 在抛出异常之前从未打印过。
所以,问题是哪个先出现 - 最后还是 return?
与在什么之后执行什么没有太大关系(它是 try、catch、return、finally - finally 在 return 之后运行,但实际上在方法之前 returns,所以它在技术上可以修改 return 值 - 你不应该那样做)。最基本的是要知道 String 是不可变的。
public String unaffectedReference(){
String message = "Important msg";
try{
return message;
}finally{
message = " meaning of life";
}
}
这将 return "Important msg",然后将消息(在方法中)更改为“生命的意义”。但是 return 值是对字符串 "Important message" 而不是 "message" 的引用。例如,如果 String 不是不可变的并且您要执行 message.setValue(" meaning of life"),那么这将被打印出来。
public Container modifiedReference(){
Container c = new Container();
c.set("Important msg");
try{
return c;
}finally{
c.set("Meaning of life");
}
}
...您的 return 值是对 Container 对象的引用,更改此 Container 对象内部的内容会修改 return 值,当然,因为您是 return对象和此对象被修改。