Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 9 of 9

Thread: Conditions and 'might not have been initialized' error.

  1. #1
    Member
    Join Date
    Oct 2011
    Posts
    46
    My Mood
    Asleep
    Thanks
    4
    Thanked 0 Times in 0 Posts

    Default Conditions and 'might not have been initialized' error.

    I am making a program for my Java class. after thinking I have initialized the variable known as af and making some conditions, I get the error that af might not have been initialized. What am I missing that I keep getting this error? (All other variables have been initialized and assigned). Here is a section of my script.

            double af;
     
            ...
     
            if(choice == 0){
                af = 1.0;
            }
            else if(choice == 1){
                af = 1.3;
            }
            else if(choice == 2 && (genderChar=='m'||genderChar=='M')){
                af = 1.6;
            }
            else if(choice == 2 && (genderChar=='f'||genderChar=='F')){
                af = 1.5;
            }
            else if(choice == 3 && (genderChar=='m'||genderChar=='M')){
                af = 1.7;
            }
            else if(choice == 3 && (genderChar =='f'||genderChar=='F')){
                af = 1.6;
            }
            else if(choice == 4 && (genderChar =='m'||genderChar=='M')){
                af = 2.1;
            }
            else if(choice == 4 && (genderChar =='f'||genderChar=='F')){
                af = 1.9;
            }
            else if(choice == 5 && (genderChar =='m'||genderChar=='M')){
                af = 2.4;
            }
            else if(choice == 5 && (genderChar =='f'||genderChar=='F')){
                af = 2.2;
            }
            else{
                System.out.println("Invalid Entry");
            }
     
            tdee = bmr * af;


  2. #2
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Conditions and 'might not have been initialized' error.

    It's doing code path analysis. There's a path through your code where you access the value of af and it may not ever have been assigned. Try walking through your code in your mind - you'll soon spot it.

  3. #3
    Member
    Join Date
    Jun 2011
    Posts
    56
    Thanks
    2
    Thanked 7 Times in 6 Posts

    Default Re: Conditions and 'might not have been initialized' error.

    Local variables should always be initialized.
    double af = 0.

  4. #4
    Member
    Join Date
    Oct 2011
    Posts
    46
    My Mood
    Asleep
    Thanks
    4
    Thanked 0 Times in 0 Posts

    Default Re: Conditions and 'might not have been initialized' error.

    Solved. I forgot to mention I didn't assign af a value. So assigning 0 to it makes the output correct after all the math, thanks.

  5. #5
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Conditions and 'might not have been initialized' error.

    I'm glad you got working code in the end, but your solution is a "belt and braces" kludge. The compiler analyses your code to warn you of routes through your code where your variables may be used before they are initialised. All you needed to do was to assign af in your 'else' clause. By initialising it 'just in case' you assign af *twice* every time the input data is valid.

  6. #6
    Member
    Join Date
    Jun 2011
    Posts
    56
    Thanks
    2
    Thanked 7 Times in 6 Posts

    Default Re: Conditions and 'might not have been initialized' error.

    Actully it is better to initialize every time. The java compiler is weak in detecting all paths unless you make it so obvious
    public class Test {
    	public static final int get() {
    		return 0;
    	}
    	public static void main(String args[]) {
    		int x;
    		int b = 0;
    		if(b == 0)
    			x = 1;
    		if(get() == 0)
    			x = 2;
    		//if(true)
    		//	x = 3;
    		x++;
    	}
    }
    It still thinks x is unitialized. Making b final solves it. But again if I return a final int from a function it misses it.
    Ofcourse "else" solves everything. But what if we don't want to initialize when all else fails ?

    Edit:
    Also initialization is not as costly as assignment so your 2x is probably inaccurate. One way of optimizing c++ code is to prefer initialization over assignment as the former calls the copy constructor directly instead of a constructor + assignment.
    Last edited by dabdi; October 1st, 2011 at 07:02 PM.

  7. #7
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Conditions and 'might not have been initialized' error.

    if I return a final int from a function
    There's no such thing as a 'final int', only a final variable or a final method. A final method is one that cannot be overridden, not one that guarantees its return value. I'd say javac is defensibly treating methods as black boxes: your method returns *any* int, not a specific one, for the purposes of code path analysis.

    initialization is not as costly as assignment so your 2x is probably inaccurate
    I think this is probably only valid in older languages like COBOL with separate data / program text, in which the compiler produces an initialised 'memory image' and every variable has 'module scope'. In practically any language where variables have scope that starts with their declaration, what declaration of a variable will do is to reserve some labelled space, initialisation (setting the value in that space) being exactly the same as assignment. Besides - my '2x' refers to what the program 'says', which is indisputably assigning the variable twice for all valid inputs. It's a logical duplication.

    The only way I could imagine initialisation (assignment on declaration) being a special case is in the case (this case) were a variable is being initialised to a literal which already occupies space in the program text. I have strong doubt that Java works that way - a doubt dispelling authoritative explanation will always be welcome.

    I see the motivation for your rule-of-thumb: it might save a weak programmer from a weak compiler. Javac's code path analysis is good though, I think we should be encouraging new programmers to take full advantage of that kind of correctness checking, and help them right correct code rather than weak-compiler-safe code.

    I was going to suggest a half-way house between 'always initialise' and 'cover all paths', but decided it's probably the worst option of all: to use a function to assign the value. That would at least cause the compiler to complain at the point the integer is being assigned: the great problem with a missed code path is that the compiler complains where the variable is first *used*. Initialisation and use could be separated by reams of code, so it's no wonder new programmers are confused.

    Here's some quick code that compares what I think are the available options. There's one in there which - as far as I know - is not available, and that's the 'anonymous inline function'. I wish I could write Java like that! Does that work in any other language?

    package com.javaprogrammingforums.domyhomework;
     
    public class AlwaysInitialise
    {
      public static void main(String[] args)
      {
        int theInt;
     
        // clearly broken, needs else
        if (Math.random() < 0.5)
          theInt = 0;
        else if (Math.random() > 0.5)
          theInt = 1;
        /* omitting the else gives 'variable theInt might not have been initialized' */
        else
          theInt = -1;
        /* */
        // compiler complains here if theInt is not initialised, which is
        // bad because use and initialisation might be greatly separated.
        System.out.println("theInt is " + theInt);
        // assign-on-initialisation and re-assign on valid inputs *sniff*
        int anotherInt = -1;
        if (Math.random() < 0.5)
          anotherInt = 0; // RE-assignment
        else if (Math.random() > 0.5)
          anotherInt = 1; // RE-assignment
        // assign with method 'missing return statement' error more obvious
        // but this method is ugly - a method that's only used once?
        int yetAnotherInt = yetAnotherIntAssignment();
        // what's ideal (I think) is an 'anonymous inline function':
        // in which even local variables can be declare to assist in 
        // the initialisation of myIdealInt, but their scope would be
        // limited here. Of course, the same effect can be obtained
        // by enclosing the first method in { }. The only putative
        // benefit is a change of compiler message from 'might not'
        // to 'missing return statement'.
        /* will not compile
        int myIdealInt = int
         {
          if (Math.random() < 0.5)
            return 0;
          else if (Math.random() > 0.5)
            return 1;
          return -1; // omit this line for 'missing return statement'
         }
        */
        // here's my second guess (first was to use java.lang.Number,
        // but there are a lot of abstract methods to implement) at
        // an inline instantiation with local error message:
        abstract class IntegerKludge
        { public abstract int intValue(); }
        int myKludgeInt = new IntegerKludge()
         {
           public int intValue()
          {
            if (Math.random() < 0.5)
              return 0;
            else if (Math.random() > 0.5)
              return 1;
            return -1; // omit this line for 'missing return statement'
          }
         }.intValue();
        // myKludgeInt is guaranteed assigned before use.
      }
      private static int yetAnotherIntAssignment()
      {
        if (Math.random() < 0.5)
          return 0;
        if (Math.random() > 0.5)
          return 1;
        return -1; // omit this line for 'missing return statement'
      }
    }

  8. #8
    Member
    Join Date
    Jun 2011
    Posts
    56
    Thanks
    2
    Thanked 7 Times in 6 Posts

    Default Re: Conditions and 'might not have been initialized' error.

    Quote Originally Posted by Sean4u View Post
    There's no such thing as a 'final int', only a final variable or a final method. A final method is one that cannot be overridden, not one that guarantees its return value.
    Right. I still miss that const and final are not really the same thing.

    I see the motivation for your rule-of-thumb: it might save a weak programmer from a weak compiler. Javac's code path analysis is good though, I think we should be encouraging new programmers to take full advantage of that kind of correctness checking, and help them right correct code rather than weak-compiler-safe code.
    Initialization do not have to be expensive. Initialization of local objects to null is a good solution.
    A similar question was asked here recently as to why instance variables are initialized to null, but not local variables.Why not do the same for local variables as well? It seems a good rule of thumb to follow
    public class Test {
    	static String y;
    	public static void main(String args[]) {
    		String x; //String x = null is better.
    		int b = 0;
    		if(b == 0)
    			x = "";
                    //x not initialized 
    		System.out.println(x);
                    //y is intialized to null by default
    		System.out.println(y);
    	}
    }
    Last edited by dabdi; October 2nd, 2011 at 11:01 AM.

  9. #9
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Conditions and 'might not have been initialized' error.

    why instance variables are initialized to null, but not local variables
    That's a good question - my guess is that it's that way due to the expense of doing code path analysis for a class against inline code. If you declare a class with an uninitialised public member variable, javac would have to do code path analysis on the class every time it was used. Compromises are never fully satisfying for everyone!

    I'd never really been conscious before that variables were initialised in classes and not in local code, and I use that declare-uninitialised, complicated-initialisation-block pattern a lot. I think I might be on auto-pilot while I'm writing local code.

Similar Threads

  1. Loop conditions not working
    By bmxershane in forum What's Wrong With My Code?
    Replies: 4
    Last Post: May 1st, 2011, 03:25 AM
  2. variable might not have been initialized
    By SV25 in forum Java Theory & Questions
    Replies: 1
    Last Post: April 25th, 2011, 11:58 AM
  3. Hangman help. Comparing arrays and conditions.
    By javanewbie1 in forum What's Wrong With My Code?
    Replies: 2
    Last Post: January 18th, 2011, 09:26 AM
  4. Variable might not have been initialized?
    By n56 in forum What's Wrong With My Code?
    Replies: 5
    Last Post: November 30th, 2010, 03:03 PM
  5. Replies: 3
    Last Post: April 20th, 2009, 09:35 AM