aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes A funny question,see it!! Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "A funny question,see it!!" Watch "A funny question,see it!!" New topic
Author

A funny question,see it!!

Tony Ge
Greenhorn

Joined: Sep 05, 2001
Posts: 20
class TestFinal{
final int f; //-----2
TestFinal(){
return ;//----4
}
public static void main(String[] args)
{
TestFinal t = new TestFinal();
System.out.println("Final int f = " + t.f);
}
}
the line 2 declare a final variable!!the coding can compile and print : Final int f=0.
but if u remove line 2: return;
then the coding can not compile and the compile error is like so: varibale f may not be initialize!
who can explain it??/
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371
while looking for your reply I found two links
first is http://domino.watson.ibm.com/syssftpr/JavaTech/Jikes.nsf/Named/JikesProblem360

As per above link above program should genrate compile error but mine compiler is compiling fine.
secone link is
http://forum.java.sun.com/thread.jsp?forum=31&thread=229533
this link discuss the same problem but no solutions


"Thanks to Indian media who has over the period of time swiped out intellectual taste from mass Indian population." - Chetan Parekh
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371
what I could I find in JLS, it says that constructors and void method can return with no expression.
I think when a constructor forcefully return then compiler assign default values to member varibles(including final). It might be a shortcut to initialize all final variables to default value.
Hope someone will pay attention to your problem too.
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371
or it could be a unreported bug ??
as I searched in java bug DB but could not find anything like this... or if someone has time then can go through more than 3000 bugs report.
[ March 21, 2002: Message edited by: Ravish Kumar ]
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
I seems that the abrupt completion of the constructor caused by return, prevented the check that final instance fields are assigned within each constructor.


SCJP2. Please Indent your code using UBB Code
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
but some kind of assignment must have taken place since the value of f is 0 when printed.


SCJP 5, SCJD, SCBCD, SCWCD, SCDJWS, IBM XML
[Blog] [Blogroll] [My Reviews] My Linked In
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
Moreover, if you modify the code like this:

then the compiler complains about the fact that f might not have been initialized. What does this tell you?
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371
but jose ..
agree that abrupt completion is there ..
but how final is being assigned the value?
OR compiler first assigned the values to all members and then check for 'final' keyword and force programmer to initialize it.
In this case we can assume that bcoz of abrupt completion compiler is not checking for 'final'.
One more from JLS:
What does it mean :
A return statement with no Expression attempts to transfer control to the invoker of the method or constructor that contains it
TIA
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
What does it mean :
A return statement with no Expression attempts to transfer control to the invoker of the method or constructor that contains it

It means that whenever a return statement is encountered, the current execution block is abandonned and the control is passed to the invoker. In this case, when return is encountered in the constructor, the control is passed on to the method main() for further processing.
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371
Thanks Val,
now
Originally posted by Valentin Crettaz:
then the compiler complains about the fact that f might not have been initialized. What does this tell you?

I think in try/catch block is same as constructor without 'return' as compiler will assume that Exception can be thrown before 'return' statement and will give the SAME error. (though there is only 'return' stmt present here)
CMIW
TIA
[ March 21, 2002: Message edited by: Ravish Kumar ]
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
do not believe me, find the truth. --Ravish Kumar
I'll try and do that
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371
Originally posted by Valentin Crettaz:
I'll try and do that

Do tell us the truth, I will then find it in my way
I visited around 200 pages to look bug in java bug DB and in Sun.java forum. wasted/invested 4 hrs. in this ...but now I have some work.. so find the truth..
I do not beleive in you too..
(sometimes I do beleive in you )
I will find truth in my way
Guy Allard
Ranch Hand

Joined: Nov 24, 2000
Posts: 776
Hi Guys - I see the following results on all my systems:
1) The code from Tony either compiles and runs or fails to compile exactly as he described.
2) The code from Ravish compiles and runs.
My Systems are:
1) Redhat Linux
a) JDK Build 1.3.1_01
b) JDK Build 1.4.0-b92
2) Windows XP
a) JDK Build 1.4.0-b92
Are these compilers/JREs out of spec? Or do the specs leave something unsaid?
I cannot decide.
Regards, Guy
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
One thing you guys have to be aware of is that compilers are required to conform to the Java Language Specification. That does not mean that they do on all points. Every implementation has a little trick or hack here and there which makes it more or less uncompliant with the spec on certain (very few, but still) points. You have to accept that a compiler is man-made, and thus, not perfect. That's why you have to make sure that the JLS be the last authority ruling on the Java realm. This is sad but this is the way it is. There are so many compilers out there, I wish that all of them implement the spec correctly, but....
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371
so is this bug ??
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
Sun's definition of "Bug":

Bug: Some feature of the product you have selected does not perform to the spec.
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
Hello again
JLS 12.5: When creating a new instance enough space is taken for all the fields declared in the proper class and its super classes, even the hidden ones. After that (or at the same time) default values are given. Later constructor is invoked. With jdb is possible to check that t is cero before super() is called in the constructor. I don't think we should consider this as an assigment because an access to print t just after super() compiles in an error.
The example of Ravish is the same as the first one because the if statement completes abruptly given that its contained statement does it similarly.
This is a bug
that is very similar. Also in the evaluation of the related mantioned bug (4063938)can be read:

It is easy to construct situations where the definite
assignment checking results simply don't make sense unless static initializers
(and instance initializers) can complete normally.
Guy Allard
Ranch Hand

Joined: Nov 24, 2000
Posts: 776
Very interesting thread.
But what is really important is "write once run anywhere".
I have actually done a couple of small non-GUI projects that were written, compiled, and tested on Win98, binary uploaded the .class files to a OS/390 mainframe, and they ran.
G.
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371
check this another blank final bug :roll:
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371
Originally posted by Jose Botella:
It is easy to construct situations where the definite assignment checking results simply don't make sense unless static initializers
(and instance initializers) can complete normally.

In general, there may not
be a textually-apparent successor to the initializer, thus it is necessary to
report that the first initializer cannot return normally, not that the second
is unreachable.


FROM:bug
that is very similar. Also in the evaluation of the related mantioned bug (4063938)can be read:

so what does it mean?
---
simply don't make sense unless static initializers
(and instance initializers) can complete normally.

----
What I understood that if there is abrupt completion of static initializers
(and instance initializers) [can we include construtor also??] then definitly assigned value is not checked.
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371

output is :
in init finla this.f 0
finla this.f 0
finla this.f 56
finla this.f 56
Final int f = 56
Press any key to continue . . .
Can you guys see that for final var f there are two values(0 and 56) have been printed here.
final var is assigned TWO times
any reason??
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5371
Now let me put my conclusion I might be wrong as I am not expert in JLS.
I think it is a bug.
First we will see what JLS says (correct me if I am wrong) I am not pasting whole stuff as it will become lengthy.
4.5.4 final Variables
  • A final variable may only be assigned to once.
  • A blank final is a final variable whose declaration lacks an initializer
    14.16 The return Statement
  • A return statement with no Expression must be contained in the body of a method that is declared, using the keyword void, not to return any value (�8.4), or in the body of a constructor (�8.8).
  • To be precise, a return statement with no Expression always completes abruptly, the reason being a return with no value.
    16.2.12 break, continue, return, and throw Statements
  • V is [un]assigned after any break, continue, return, or throw statement.
  • Because a break, continue, return, or throw statement never completes normally.
    16.8 Definite Assignment, Constructors, and Instance Initializers

  • Let C be a class, and let V be a blank final non-static member field of C, declared in C. Then:
  • V is definitely unassigned (and moreover is not definitely assigned) before the leftmost instance initializer or instance variable initializer of C.
  • V is [un]assigned before an instance initializer or instance variable initializer of C other than the leftmost iff V is [un]assigned after the preceding instance initializer or instance variable initializer of C.
    from 16.2.12: The following rules hold within the constructors of class C:
  • V is definitely assigned (and moreover is not definitely unassigned) after an alternate constructor invocation.
  • V is definitely unassigned (and moreover is not definitely assigned) before an explicit or implicit superclass constructor invocation.


  • Now let us see our code

    In this code constructor has a 'return' so constructor returns abruptly [JLS 14.16, JLS 16.2.12].
    Now from JLS 16.2.12 "V is [un]assigned after any break, continue, return, or throw statement." now as var f was definitly unassigned before invocation of constructor AND construtor completes abruptly, var 'f'should be definitely unassigned after execution of construtor. But it is printing default value 0.
    As per JLS 16.2.12 "V is definitely assigned (and moreover is not definitely unassigned) after an alternate constructor invocation.".
    So I think compiler should flag an error if there is return statement in construtor AND final varibale is not defined to comply with 16.2.12. In this way final varuable will be definelty assigned value before return with no expression statement.
    Jose Botella
    Ranch Hand

    Joined: Jul 03, 2001
    Posts: 2120
    This is from the metioned bug 4064281

    A reachable statement analysis is implicitly performed by the definite
    assignment analysis, which essentially loses all information about the
    variables after a statement that cannot complete normally.

    Also what is telling us this? JLS 16.2.12

    * By convention, we say that V is [un]assigned after any break, continue, return, or throw statement. The notion that a variable is "[un]assigned after" a statement or expression really means "is [un]assigned after the statement or expression completes normally". Because a break, continue, return, or throw statement never completes normally, it vacuously satisfies this notion.

    Its telling us nothing about the un/assignment state of a blank field after a sentence that completes abrutly.
    In that case the behaviour maybe is not a bug, but each compiler treats this point in its own way because the JLS seems not to specify what must be done.
    This seems a bit of java fiction.

    [ March 22, 2002: Message edited by: Jose Botella ]
    [ March 22, 2002: Message edited by: Jose Botella ]
    R K Singh
    Ranch Hand

    Joined: Oct 15, 2001
    Posts: 5371
    Originally posted by Jose Botella:
    Its telling us nothing about the un/assignment state of a blank field after a sentence that completes abrutly.

    But JLS says this also :
    An even more peculiar consequence of this definition is that "V is definitely unassigned after break;" is always true! Because a break statement never completes normally, it is vacuously true that V has not been assigned a value if the break statement completes normally.

    It also says if V is variable then V is definetely unassigned after execution of X statement if it is definetely unassigned before execution of X.
    Here in case of construtor return, final var 'f' is definetly unassigned before return hence it should be definetly unassigned after return.
    More over if return is completed abruptly then it is for sure that f is not assigned hence it should be definetly unaasigned.
    From JLS:
    In all, there are four possibilities for a variable V after a statement or expression has been executed:
  • V is definitely assigned and is not definitely unassigned.(The flow analysis rules prove that an assignment to V has occurred.)
  • V is definitely unassigned and is not definitely assigned.(The flow analysis rules prove that an assignment to V has not occurred.)
  • V is not definitely assigned and is not definitely unassigned.(The rules cannot prove whether or not an assignment to V has occurred.)
  • V is definitely assigned and is definitely unassigned.(It is impossible for the statement or expression to complete normally.)



  • Will anyonme plz explain point no. 3 ??
    As I think, there is something messy in point no. 3.(The rules cannot prove whether or not an assignment to V has occurred.)
    TIA
    [ March 25, 2002: Message edited by: Ravish Kumar ]
    Jose Botella
    Ranch Hand

    Joined: Jul 03, 2001
    Posts: 2120

    quote riginally posted by Jose Botella:
    Its telling us nothing about the un/assignment state of a blank field after a sentence that completes abrutly.
    But JLS says this also :
    quote: An even more peculiar consequence of this definition is that "V is definitely unassigned after break;" is always true! Because a break statement never completes normally, it is vacuously true that V has not been assigned a value if the break statement completes normally

    The problem is that JLS also says the following:

    A peculiar consequence of this definition is that "V is definitely assigned after break;" is always true! Because a break statement never completes normally, it is vacuously true that V has been assigned a value if the break statement completes normally.

    The only conclusion that I can extract is that the concepts definitely [un]assigned are not applicabe after a statement that completes abruptely.
    Also

    It also says if V is variable then V is definetely unassigned after execution of X statement if it is definetely unassigned before execution of X.
    Here in case of construtor return, final var 'f' is definetly unassigned before return hence it should be definetly unassigned after return.
    More over if return is completed abruptly then it is for sure that f is not assigned hence it should be definetly unaasigned.

    If that were the case why is Tony's code compiling?
    Now

    3 V is not definitely assigned and is not definitely unassigned.(The rules cannot prove whether or not an assignment to V has occurred.)

    V is not definitely assigned == at least there is a path of execution that doesn't assign the variable.
    V is not definitely unassigned == at least there is a path of execution that assigns the variable.
    The rules can not prove the variable is definitely assigned or not because it depends of the path of execution.
    I would mind being corrected if I am wrong
    [ March 25, 2002: Message edited by: Jose Botella ]
    R K Singh
    Ranch Hand

    Joined: Oct 15, 2001
    Posts: 5371
    ------------------------------------------------
    Originally posted by Jose Botella:
    The problem is that JLS also says the following:

    A peculiar consequence of this definition is that "V is definitely assigned after break;" is always true! Because a break statement never completes normally, it is vacuously true that V has been assigned a value if the break statement completes normally.

    ------------------------------------------------
    No, JLS says that :
    Page No. 410-411 in PDF format:

    Similarly, the statement �V is definitely unassigned after X � (where V is a vari-able
    and X is a statement or expression) means �V is definitely unassigned after X if X completes normally�. An even more peculiar consequence of this definition is that �V is definitely unassigned after break;� is always true! Because a break statement never completes normally

    Hence compiler should flag error as it is a programming error and does not confirm JLS2.0.
    Correct Me If You Can
    John Shaw
    Greenhorn

    Joined: Mar 29, 2002
    Posts: 1
    Hello, all!
    I'm new to Java but I was going over the original problem here and I would like to offer my thoughts as to why removing the return in line 4 causes the compile-time error.
    If a variable is declared final and the default constructor initializes the state of all members in the object, would it not make sense that the compiler would not allow a final variable to be uninitialized because of an empty construct body? In other words, the return is needed in the construct to at least initialize the final variable? Or am I totally wrong because the construct is explicit and the final variable is a class member and one has nothing to do with the other?
    Or do I need to take up knitting instead of Java?
    R K Singh
    Ranch Hand

    Joined: Oct 15, 2001
    Posts: 5371
    Let us wait and watch for SUN's answer.
    Valentin Crettaz
    Gold Digger
    Sheriff

    Joined: Aug 26, 2001
    Posts: 7610
    The "evaluation" provided by the bug reviewer is not very helpful... :roll:
    R K Singh
    Ranch Hand

    Joined: Oct 15, 2001
    Posts: 5371
    Hi Val
    I found the truth...
    It is a BUG !
    when compiling with JDK1.2.2
    ==================================================
    D:\JavaTp>C:\jdk1.2.2\bin\javac.exe TestFinal.java
    TestFinal.java:2: Blank final variable 'f' may not have
    been initialized. It must
    be assigned a value in an initializer, or in every
    constructor.
    final int f ; //-----1
    ^
    1 error
    ============================================
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: A funny question,see it!!