13

I'm programming in Java. I have added comments to every method to explain what they're supposed to do (according to the assignment). I have added what I know to the stub of Password.java (which I created after researching a javadoc provided by the school). My question is not about several functions, I know there are mistakes in testWord and setWord, but I'll handle that myself. My question is about this line:

public static final java.lang.String INITIAL;

This line is provided by the school, so I gotta assume that it is correct, I cant find any documentation anywhere about the constant field value INITIAL, so if anyone could provide me with info on that that would be amazing (eg. how is is handled? what does it store? if anything? type?). Also Im getting an error on this line in Eclipse:

The blank final field INITIAL may not have been initialized

Why is this error here? Thanks in advance about the comments.

FYI the code from Password.java:

package ss.week1;

public class Password extends java.lang.Object {

// ------------------ Instance variables ----------------

/**
 * The standard initial password.
 */

public static final java.lang.String INITIAL;

// ------------------ Constructor ------------------------

/**
 * Constructs a Password with the initial word provided in INITIAL.
 */

public Password() {

}

/**
 * Tests if a given string is an acceptable password. Not acceptable: A word
 * with less than 6 characters or a word that contains a space.
 * 
 * @param suggestion
 * @return true If suggestion is acceptable
 */

// ------------------ Queries --------------------------

public boolean acceptable(java.lang.String suggestion) {
    if (suggestion.length() >= 6 && !suggestion.contains(" ")) {
        return true;
    } else {
        return false;
    }
}

/**
 * Tests if a given word is equal to the current password.
 * 
 * @param test Word that should be tested
 * @return true If test is equal to the current password
 */

public boolean testWord(java.lang.String test) {
    if (test == INITIAL) {
        return true;
    } else {
        return false;
    }
}

/**
 * Changes this password.
 * 
 * @param oldpass The current password
 * @param newpass The new password
 * @return true if oldpass is equal to the current password and that newpass is an acceptable password
 */

public boolean setWord(java.lang.String oldpass, java.lang.String newpass) {
    if (testWord(oldpass) && acceptable(newpass)) {
        return true;
    } else {
        return false;
    }
}
}
Daryl Bennett
  • 462
  • 10
  • 22
Koen
  • 461
  • 2
  • 5
  • 16
  • You don't need to type the full path for classes in `java.lang`. eg. `public static final String INITIAL` is perfectly fine (and preferred). – Roddy of the Frozen Peas Nov 14 '14 at 17:24
  • thats how our school gave it to us, I thought that was easier but hey, what do I know ;) thanks for your comment. – Koen Nov 14 '14 at 19:39
  • You can also have a final field that you initialise in the constructor via a passed final input parameter, but when you make reference to it within a Predicate it flags it as an error, when it isn't. I wonder if that's not a compiler bug/false positive. You end up having to inline the predicate and duplicate if you want to use it in both a findFirst() and forEach() scenario – JGFMK May 03 '20 at 17:50
  • I later thought of a work around for that by implementing a method that wraps and gets the Predicate, then, in the filter() call the get Predicate. Then I could use that in both my findFirst()/forEach() scenarios. – JGFMK May 04 '20 at 08:53

3 Answers3

31

The error is exactly what the compiler says it is - you've got a final field, but nothing setting it.

Final fields need to be assigned to exactly once. You're not assigning to it at all. We don't know what the field is meant to represent beyond the documentation ("The standard initial password") - presumably there is some default password which you're meant to know. You should assign that value to the field, e.g.

public static final String INITIAL = "defaultpassword";

Additionally: you don't need to write java.lang.String; just use the short name (String). It's very rarely a good idea to use fully-qualified names within your code; just import the types you're using, and be aware that everything in java.lang is imported automatically.

Additionally: don't compare strings using ==; use .equals instead.

Additionally: any time you have code like this:

if (condition) {
    return true;
} else {
    return false;
}

you can just write:

return condition;

For example, your acceptable method can be written as:

public boolean acceptable(String suggestion) {
    return suggestion.length() >= 6 && !suggestion.contains(" ");
}
Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    thanks, that should get me started, I will implement all of the above, all are helpfull and for my skill level, very nice, thanks again! 1 question remains, can I use the setWord method? it should set the password, which is the public static final String INITIAL, to a password given to this method. – Koen Nov 14 '14 at 19:36
  • @Koen Once your final variable is initialized, its value cannot be changed. So once you set `INITIAL = `, you can't later re-assign a new value to `INITIAL`. You may want to consider having `INITIAL` hold a default value, and then have a regular (non-final) String hold the currently set value, which is `INITIAL` to begin with, but can be changed to another value later on via `setWord` or another method. – Roddy of the Frozen Peas Nov 14 '14 at 20:09
  • I figured it out, thanks ! Implemented like this: public static final java.lang.String INITIAL = "Initial"; private String wachtwoord; public Password() { wachtwoord = INITIAL; } – Koen Nov 14 '14 at 20:19
  • A general hint (for people like me): Check if you don't need to install LOMBOK. – Adam Libuša Sep 20 '19 at 11:12
0

You never assign any value to your constant variable at all because constant variable needs to be assigned once

public static final java.lang.String INITIAL;

change to

For example:

public static final java.lang.String INITIAL ="initial";

Declaring a Variable as a Constant

In declaring variables I showed that it’s easy to assign a value to a int variable:

int numberOfHoursInADay = 24; We know this value is never going to change in the real world so we make sure it doesn’t in the program. This is done by adding the keyword modifier final:

final int NUMBER_OF_HOURS_IN_A_DAY = 24;

In addition to the final keyword you should have noticed that the case of the variable name has changed to be uppercase as per the standard Java naming convention. This makes it far easier to spot which variables are constants in your code.

If we now try and change the value of NUMBER_OF_HOURS_IN_A_DAY:

final int NUMBER_OF_HOURS_IN_A_DAY = 24; NUMBER_OF_HOURS_IN_A_DAY = 36; we will get the following error from the compiler:

cannot assign a value to final variable NUMBER_OF_HOURS_IN_A_DAY The same goes for any of the other primitive data type variables. To make them into constants just add the final keyword to their declaration.

Source and Read More

Another error:

if (test == INITIAL) {

You must use equals() to compare two strings

why?

equals() compare againts the content which what you are looking for

== compare the reference if references are looking at the same location

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
0

I don't see anywhere in the provided Password.java where the static final INITIAL is being assigned. That must be the problem here.

glaze
  • 56
  • 2