Currently, my "main() class" file looks a bit like the following code. Rather than clutter up this example code with //comments for discussion, I have simply labelled four code lines with numbers (1 to 4), and these numbers refer to questions that appear after the code. Thank you.
// package myPackage; // **1**
import myOtherPackage.*;
class mainProject{ // **2**
// **3**
private int myVar;
mainProject(){
myVar = 0;
}
public static void main(String args[]){
// Keep main() looking fairly simple?
// Perhaps just have some "essentials" here, such as error handling?
new mainProject().start(); // **4**
}
private void start(){
// The project gets going here..
}
}
1 Unlike other class files in my project, I have not assigned a package name for my "main() class" file. Is this a bad design choice?
2 Is there a good naming convention for the "main class"? Is it helpful to incorporate the word "main" in to this class name? Would something roughly like "mainProject" be a good idea?
3 Various coding constructs can appear inside the main class file. For example, local variables, constructors, the main() method, and local methods. Do they have a "best order" in which they appear in this file?
4 Is it worthwhile to keep the main() method looking fairly "lean and simple"? In this example, I have just called a local private method called start(), which is intended to get the project started.
Ok, here is how I do it in my professional projects.
For 1. every class should have a package. Main or no main makes no difference. Package is the way java organizes your classes at runtime in form of namespaces. So if you stop giving packages then you may end up with two class files with same name in the same folder or jar and when that happens, JVM picks the first class it finds by the name on the classpath. That may not exactly be the one you want.
For 2. main (speciallypublic static void main(String[] args) is a specific and standard signature that Java needs. Any runnable program, a program that produces an output and can be executed needs a main method with this signature. I will try to explain the signature and that maybe will help you understand why it's like that.
It's public because you want the JVM runtime code to execute the method. Using private or protected won't allow the JVM code to see your method.
It's static because without static the JVM code would need an instance of your class to actually access the method. Remember that static methods and fields can be accessed by just using the class name. However non static members need a valid live object to reach them.
It's void because main does not return anything to its caller. It's like any method having a void return type.
And it's called main because the Java creators thought to give it that name. JVM runtime code which executes this method needs to know about the name of your method which will kick off the execution. Now, if I name it anything then it's impossible for the JVM code to make a wild guess. So name standardization called for a standard name and Java creators stuck to main.
String[] is actually a string array containing the command line arguments that you pass to your program. args is the name of the argument and ironically this is the only thing that you can change to any name you want.
For naming the main class, I usually prefer the names like MyProjectLauncher or MyProjectBootstrap where myProject is the name of your project like tomcat or bigben or anything you like.
For 3. standard convention is:
public class MyClass{
//private members
//protected members
//constructors
//private methods
//protected methods
//public methods
//hashcode and equals
//toString overrides
}
You can pick what you need and drop what you need. Public methods also include the getters and setter for your variables if you use them.
For 4. When designing classes you need to keep in mind scalability and manageability of code. It's very common to have a main class and a few classes at start of the project and then when they grow into oversized kangaroos of thousands of lines then refactor code to adjust it. What you should do is create classes based on functionality, service helpers or actions. Keep main separate in a different class. Just use main to initialize a few things, parse command line options and delegate to start or initialize method which does the remaining things to kick off your program.
Hope this helps.
1 yes you should always use packages. But dont use camelcase in them... So myotherpackage rather than myOtherpackage.
2 yes, it is good convention to incorporate the word main, e.g. MyApplicationMain. Remember class names start with a caps letter.
3 yes, the common order would be statics, members, constructors, methods, much like you have already
4 yes! This enables better testing and you should not use a static context for any longer than you need to.
If you add a package and take on board my tips for caps letters, i think what you have above is absolutely fine.
Usually, it is good to define your own packages in order to avoid naming clashes with any other classes on your classpath. This also applies to the main class. Imagine what would happen if somewhere else in your dependencies there is a class whose creator used the same approach of leaving it in the default package. So yes, put iinto a package.
The naming is left at your latitude, but Java coding conventions definitely urge you to capitalize the name of the class. So, Main or MainProject or EntryPoint would be better choices.
I think you refer to fields and methods as members of the class. Please note that local variables and local methods have a totally different meaning (they're not members of the class itself). The usual ordering is static fields, instance fields, static methods constructors, instance methods. I don't think there is a strong convention, but these are the habits.
It is worthwhile keeping any method clean and simple ;)
ALWAYS use a package. No matter what. This is your namespace!
Don't use camelCase in your package names.
Avoid to import whole packages.*, better import a single package.Clazz.
Class names should ALWAYS be UpperCaseAndCamelCase.
Leave a space between the class or method name and the opening braket {, it improves readability.
The rest seems to be ok. It is more or less a matter of pragmatism. Your code has to fulfill the purpose it was written for and also needs to be testable and readable (by others).
All these criteria will form a ruleset for you or your team.
What if someone else has a main class with the same name? Its better to place it in a package for all but the simplest test programs.
Incorporating "Main" in the class name is a good idea because it quickly tells the reader the purpose of the class, but "mainClass" should be "MainClass" according to java language conventions
The usual order is variables, constructors, and methods in whatever order is reasonable
Yes, keep the main method small and easily readable. The logic in it should mostly just be related to parameters passed to the program, and even that should be factored out when it gets to be too large.
1 packages should definitely be used. It is better for maintenance purposes, if your project gets larger with time then there could be exact same syntax for main used. the package name should be meaningful as well and provide concise containment for relevant functionality classes.
2 yes, it is good to include the word main in the class name and should start with capital letter.
3 commonly the order is variables, constructors, methods.
4 keep the main concise and simple. the lesser code it has the better as you already have done.
Related
First, please take a look at the following code.
package test;
class c_hi {
public static void method_hi(){
System.out.println("hi");
}
}
class c_bye {
public void method_hi(){
System.out.println("bye");
}
}
public class test {
public static void main(String[] args){
c_hi.method_hi();
c_bye c_hi = new c_bye();
c_hi.method_hi();
}
}
I've been using Java for several years, and I understand the general rules for naming class names and variable names.
However, I got a very interesting question. If the name of the reference variable of the "c_bye" class is "c_hi" (a class named "c_hi" already exists),
I can't access "method_hi" of class "c_hi" from inside class "test".
Of course, I know that this problem can be prevented or circumvented by not overlapping class names and variable names, package separation, and FQCN etc.
Apart from the usual way of avoiding duplicate names, is there a more grammatical way to solve this problem? Please tell me your opinion. (Or, I would appreciate any documentation, links, or other questions on Stack Overflow that I can refer to.)
This code works the same for both JDK versions 8 and 15.
This should "fix" the problem:
test.c_hi.method_hi(); // Using the fully qualified class name.
However, the correct solution would be:
Don't ignore Java style rules. The rules say Java method name should start with a lowercase letter, and a class name should start with an uppercase letter.
Avoid using the same name for a static method and an instance method.
(You actually can't do this in some cases. For example, if c_bye extends c_hi then you get a compilation error about an instance method not being allowed to override a static method.)
Don't attempt to call a static method using an instance variable. Use the class name. (Which cannot be confused with a variable name if you follow the style rules!)
It is legal Java to do that, but it tends to fool the reader into thinking that the method is an instance method and/or that there is dynamic dispatching of static methods happening.
For what it is worth the rules for name resolution are fully specified in the JLS. (See this answer for the JLS text and reference.) The implications are a bit complicated for edge cases like the one you are talking about, but the name resolution rules are not Java version specific, AFAIK.
Java is not designed to "play nice" when people willfully ignore the style rules.
The Java Language Specification deals with that. here the first paragraph of JLS 6.4.2 Obscuring:
A simple name may occur in contexts where it may potentially be interpreted as the name of a variable, a type, or a package. In these situations, the rules of §6.5.2 specify that a variable will be chosen in preference to a type, and that a type will be chosen in preference to a package. Thus, it is may sometimes be impossible to refer to a type or package via its simple name, even though its declaration is in scope and not shadowed. We say that such a declaration is obscured.
As you already mentioned, FQN must be used instead of the simple name.
I am currently learning Java and, while making a project, I created some methods that do not suit logically in any given class but are useful in the whole context of the project.
The best example I have is a method that splits camelCase worlds like this:
splitCamelCase -> Split Camel Case.
I have thought about creating a new abstract class called Toolbox and storing those methods there, but I wonder if there is any convention or best practice regarding this topic.
It's not uncommon to have utility classes (commonly named SomethingUtils) when it just doesn't make sense to put a method in an existing class.
There's nothing inherently wrong with it, but if you find yourself having a lot of methods or utility classes, then your design might be a bit off and you're programming in a more procedural than object oriented way.
As mentioned in comments, you don't make it an abstract class. It's a class filled with static methods working entirely on the parameters passed to them.
As kayaman sir has said if you are having too many utility classes and method it means that you code is more procedural rather than object oriented.
Nut if you still want to have a class which is just used to provide some utility then you can have such a class in java , just put some static method in them.
One of the best example of such a class is java.lang.Math.
for example following code will work
class MyUtilityClass
{
private MyUtilityClass()
{
// no object creation will be allowed
}
// make as many static methods you want
}
You can create your ToolBox Class and then you declare it as a package. After that you can import your ToolBox at the beginning of classes you want to use the methods from that ToolBox.
As I develop my software, I tend to find myself creating a whole ton of ThingyHelper.java, FooHelper.java, BarHelper.java etc. I counted, and in the current project that I am working on, there are something like over 40 classes that look something like this:
public final class FoobarHelper {
// Prevent instantiation
private FoobarHelper() {throw new AssertionError();}
public static void doSomething() {}
public static int foobar() {}
// And many more
}
My question is this: Is it a good idea to merge all these classes into a huge Helper.java class? Looking around, there seems to be nothing written on this topic. My view is:
I should do it, because:
I don't have to remember which helper class is it in. (Was it FooHelper, or BarHelper?)
Just convenience. I don't have to decide if the new helper method deserves its own helper class, or if it fits into one of the existing 40 helper classes.
If I make a new helper method, and decided it deserves its own helper class, I will probably spend the rest of my day "hey, won't foobar() be better off in this new class?"
If #3 is true, other programmers would be like "where on earth did foobar() go? Its not in FoobarHelper!"
Is there a convention for helper classes, or if not, would it be a terrible idea?
I argue that your problem is not the fact that you have too many of those classes, it is that you need these classes altogether.
It is the core idea of object-orientation to merge functionality and data into objects which then represent your program flow. Without knowing your application, your utility classes suggest that you use inanimate bean classes which are then handled by a layer of service functions. This is a sign of procedural programming and nothing you want to implement with Java.
Besides that, there is no reason to merge your utility methods. So I would answer no to your question. There are some legitimate uses of utility classes such as Java's Math, Collections classes (those would also suite better as object methods but the language limits / limited this sort of definition) and you might just have encountered one of them. Note how Java decided to group such utility methods by their semantics. It makes sense to define utility methods in one name space such that your IDE can help you to pick a function when you only type the class (which does not represent a true class but rather a function namespace in this context). In the end, it is about finding a balance. If you have a single utility method per class, it is difficult for others to locate these methods as they need to know about the class's name. If there is only one utility class, it might be problematic to locate a function of all those offered. Think about the utility class as a form of navigation helper (name space) and decide after what you find intuitive.
Why does the main method have to be put into a class? I understand the main ideas of OOP but I cannot get why the main program is defined within a class. Will such a class instantiated somewhere? I mean there is no code outside the class. What is a reason to define a class and never use objects of this class?
The Java Virtual Machine (JVM) has to start the application somewhere. As Java does not have a concept of “things outside of a class” the method that is called by the JVM has to be in a class. And because it is static, no instance of that class is created yet.
While it's true that java has no concept of methods outside of classes, it would be pretty easy to allow developers to skip all the broilerplate of actually writing out the class definition and simply let people write the main function directly, if they wanted too.
But back when people were developing java, people were more dogmatic about OO then they are now, and that probably played a big part. Think of it as an example of Opinionated software
It has one useful feature though, which that you can main functions to any class and launch them as programs. It's handy for testing specific features of those classes when you're working on them. If main() had to be in a separate file, and not part of a class, that would make things difficult. What if you want more then one main() function? What if you wanted to write functions to be called by main outside of the class? Would they go in a global namespace? Would multiple main() functions collide?
Not like those problems are impossible to solve, but other then a little extra typing, which can be especially annoying for newbies the current solution isn't too bad, especially since IDEs will generate the basic class structure when you create a new file.
It does simplify the design of the virtual machine. Since virtual machine already knows how to run a static method of a class then it can treat the main method just as any other static method.
If you put the main method in any other construct other than a class then the VM has to be modified to know about another construct complicating things even more.
When the Java language was designed, the notion that everything must be an object was a point of dogmatism. (though they left in a few primitive types). These days you could perhaps design a language that uses a closure -- even one outside any class -- instead.
What #Bombe said. I would add that to OO purists, the fact that the entry class is not instantiated is a misstep. The reason is the static main prevents someone from writing a family of main classes that share the same main() method written using a template method pattern.
If Java had been written to instantiate the main class and invoke the main method, users would have enjoyed the benefits of inheritance and interfaces.
As we know main is the entry point for the JVM to start. And in java there is nothing except classes and interfaces. So we have to have a main method in the class that too it should be a public class. and the main should always be public static, because it should be accessible for JVM to start and static because it starts without creating any objects
The main reason is so that multiple classes can have a main method. So a codebase can have many "entry points" and one just uses the class to specify which one is called. Also, this is inline with the OO design where (almost) everything is an object.
Main in java is a static method, therefore the class it's in doesn't need to be instantiated into an object, the class simply needs to be loaded.
That's simply how Java was designed: (almost) everything is an object, and code can only exist as part of a class.
Since the main() is static, it being called does not automatically lead to an instantiation of the class. However, it's perfectly possible (and quite common, at least in small Swing programs and Applets) to have the class that contains the main() be an otherwise normal class that is instantiated and used like any other class.
I went to this interview for a software developer position and they gave me a test with some corner-case-code situations, with usually 4 options to choose.
One of the questions had an enum declared outside the class scope, I promptly checked the "does not compile" answer and went ahead with the other questions.
It was something like:
enum Colors {BLUE,RED,GREEN}
class Test {
//other code, not really important with my question
}
This code actually compiles.
Besides the fact that an interview like this (might or) might not be useful to find out if one is a good developer, what worries me is: why would I declare an enum like this? Why I can only do this with enum?
I did some testing and found out that it is visible inside the class, but not to other classes.
Sidenote: I scored really poor :P. I got the max on the theory but near the lowest possibile on the corner-case-code situations. I don't think I'll get the job.
It's not just enums. Enums are just special kinds of classes. In general you can have multiple classes declared in one file (as long as no two of them are public).
No, without an access modifier, the enum is package-private. This means it can only be used by classes in the same package. And you can't only do this with an enum, classes can also be made package-private.
More info: http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html
Sometimes this idiom can be sensible - for example, imagine you have an UploadHandler class (or something like that) which can return a status from an upload. It seems quite feasible to me to implement this status as an enum - and since the enum (e.g. UploadStatus) clearly "belongs" to the UploadHandler class, it seems fine to declare it in the same source file. (This does assume of course that it only needs to be package-private - if it's truly public it would need to be declared in its own file, which would probably make sense if it's not an internal thing any more).
As it happens, in this case I would probably make it a static inner class to make the relationship more explicit. But declaring multiple classes in the same source file isn't always bad and can sometimes help readability by setting the expectation that this is a borderline-trivial, subsidiary class. (By the same token, I don't think classes like this should do anything particularly complex or unexpected.)
It compiles actually, on my Eclipse ! ;-)
Several classes are allowed to be in the same file. The limitation is that a public class has to be defined in a file that has the same name.
It's visibility is 'package', so it should be visible in other classes in the same package too.
What can I do with that enum?
You can do anything you want with the above limitations...
Note : although you had it wrong, you shouldn't feel too bad, because it's not really a good practice either. In our CheckStyle configuration, outer classes in the same file like this are treated as errors !!
An enum specifies a list of constant values that can be assigned to a particular type.
It can be either inside or outside of the class.