Problem
I have a few confusions about writing Java code, and I need some clarifications:
import java.util.Scanner;
public class NameAbbreviation {
private static String fullName;
private static Scanner nameInput;
public NameAbbreviation(String name) {
NameAbbreviation.fullName = name;
}
public char getInitialLetterOfFirstName() {
char initialletterOfFirstName = fullName.charAt(0);
//System.out.println(initialletterOfFirstName);
return initialletterOfFirstName;
}
public String getInitialLetterOfLastName() {
int space = fullName.lastIndexOf(" ");
String initialletterOfLastName = fullName.substring(space + 1,
space + 2);
//System.out.println(initialletterOfLastName);
return initialletterOfLastName;
}
public static void main(String[] args) {
nameInput = new Scanner(System.in);
String name = nameInput.nextLine();
NameAbbreviation na = new NameAbbreviation(name);
System.out.println(na.getInitialLetterOfFirstName() + " "
+ na.getInitialLetterOfLastName());
}
}
- I have class variables
fullName
andnameInput
. If I makenameInput
local, it shows: Resource leak: nameInput is never closed. So I just follow the Eclipse suggestion and make it a field. What should I need to follow? - I have 2 methods –
getInitialLetterOfFirstName()
andgetInitialLetterOfLastName()
, the return types of which arechar
andString
respectively. I could eventually make the return type asvoid
. What are the advantages or disadvantages if I havevoid
or specific return type? As both the way of code works, what do I need to follow or does it depend on how I am writing the code? -
Both the methods
getInitialLetterOfFirstName()
andgetInitialLetterOfLastName()
don’t have any parameters/arguments. I could eventually create the method with argument like:getInitialLetterOfFirstName(String name) { this.fullName = name; .......} getInitialLetterOfLastName(String name) { this.fullName = name; .......}
If I create the methods with arguments, I need to pass the value during the instantiation of the object. So I avoid it here, and prefer to have only once to pass the argument value.
Is there any rule to follow, like to make the methods with parameters or not, as here both are possible with or without argument methods?
What do I need to follow as good practice, code performance issues, etc.?
Solution
Objects
Java is, by definition, an Object-oriented language… but, that does not mean every program needs to follow those rules. This is an example program where there are no new objects that are relevant, and as a result, there’s no real need to go beyond just procedural routines. You have Scanner
, and String
, and those are objects enough.
Consequently, you can do everything as static methods/functions, and no need to create anything using new
.
Functions
Good code practices recommend a number of aspects to functions that would help here.
First up, functions should do one thing, and do that one thing well. By making functions simple, it makes it easier to reuse them, and combine them. Consider a simple function that gets the initial letter of any String:
public static String getInitial(String phrase) {
return phrase.substring(0, 1);
}
That function has a useful name, I have made it static because it does not rely on any instance data/fields, and it is a simple stateless function.
Now, we can reuse that in the main method. All we need to do is separate the first and last names….. and a simple enough way to do that is your lastIndexOf(" ")
call.
int lastspace = name.lastIndexOf(" ");
System.out.println(getInitial(name) + " " + getInitial(name.substring(lastspace + 1));
Now, there are a number of defensive problems in that code – what if the user does not input any space in their name, or the name is an empty string?
These things need to be fixed, and it makes the code more complicated. A common way to do these things is to split the data on multiple spaces, and output multiple initials, or an empty string if there are none….
For 0) Add documentation to your code
For 1)
try(Scanner scanner = new Scanner(System.in)){
//rest of your code
}
This will fix the memory leak. Doing that you can remove the private field scanner from NameAbbreviation
class.
2) When I see a method with name starting with “get” i’m expecting a return value. In your case, you need a return type Char or String.
3) I would also make the methods static :
public static String getXXX(String input)
Doing that you can
-
Make an empty private constructor
-
Remove the un-necessary constructor
-
Remove the private field
fullName
-
Use your utility class like
String xxx = NameAbbreviation.getXXX(scanner.nextLine())