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.
Related
Firstly, I would like to briefly define a state to make sure we're on the same page. (please correct me if I'm wrong, or if you have anything to add)
Mutable variables/objects in the class.
Likely to be used in other classes, therefore creating a reference.
I've heard the main use of static in classes is for utility classes, which basically just provide global access to common methods -- and when states need to be stored, you should use a Singleton. However, I do not understand exactly why states are BAD for static classes? (Please correct me if this ideology is wrong)
While declaring a class as final , we cannot Inheritance this class , my question is why ? - from the java internals perspective.
I assume that the same principle apply to methods and instance as well.
is it somehow related to the class loader as well ? who is actually stopping me from override it?
There's nothing related to the JVM or internals (not really sure what exaclty you mean by that), it's a compile issue simply because you're breaking the rules.
If I think myself as a Java compiler, after parsing the tokens in your code I'm just going to look around for logical errors (semantic analysis) e.g. a circular inheritance scheme. The moment I see someone's attempt at extending a final class, I'm gonna go bazooka. That's it. No need to wake up the big bosses, the JVM or any other internals because the program cannot be correctly compiled in the first place.
If you want to know how the compiler works the way it does internally, think that while the compiler parses your code, it creates and fills some structures internal to itself for the purpose of error-checking and bytecode-translation. Also imagine in a simplified scenario that the final keyword attached to a class just sets a field in one of these structures attached to your class. After syntactic analysis, the compiler goes on with "logical" (semantic) analysis and checks (among other things) if some lunatic tries extending a final class. Even a brute search in an inheritance graph can pull that off. If a class is final and still has children, halt and notify the lunatic. The issue won't get more internal than the compiler.
It is nothing to do with Java internals.
The purpose of declaring a class to be final it to prevent it from being subclassed.
My question was what happening "underground" while declaring final ...
Well ... when a class is declared as final a flag is set in the class file to say this. If you then attempt to load a class that purports to be a subclass of a final class, the classloader will throw a VerifyError exception. The checks are done in the ClassLoader.defineClass(...) methods ... which are also final, so that normal programs can't interfere with them.
This aspect of classfile verification needs to be watertight for Java security reasons. If it wasn't then you could probably cause mayhem in a Java security sandbox by tricking trusted code into using (say) a mutable subtype of String.
The Java compiler also checks that you don't extend a final class, but you could subvert that by (for example) creating ".class" files by hand. Hence the need for load-time checks ...
Who is actually stopping me from override it?
Actually, it is the classloader. See above.
Let's look at it elementally, When you declare a variable as final, you did that because you don't want the value of that variable be changed for any reason afterwards, Right?.
Okay, under the assumption that you agree to that. The same principle is also applicable to classes.
Let's look at it this way: Why will you ever want to inherit a class? Probably because you want get access to the properties of the class and her behaviors (methods), Right? Once you have inherited these properties and behaviors you have the right the modify the accessible behavior to suite your precise need without having to re-implement all other behaviors. This is the value and power of in inheritance.
Hence, declaring a class as final implies that you don't want anyone to modify any behavior of the class. You tries to state that who so ever that will want use your class should use it as IS.
Therefore, any attempt to modify a final class is illogical and should be considered as error.
Eg.
Imaging if someone should be able to inherit your final Authentication class and modifying the actual authentication behavior (method). This should be a security bridge as it might compromise your reasons for setting the class as final.
Hence, it is a design practice.
I hope that make some sense?
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.
Is it really impossible to hide some classes in a jar file?
I wanted not to allow direct instantiation of the classes to keep it more flexible. Only the factory (or a facade) should be visible of this jar.
Is there any other way than solve this problem than creating two projects?
(Two projects: the first one contains the classes (implementation) and the other one references to the first one and contains the factory; later only the second one will be referenced)
I'm understanding you're not looking to hide the actual classes, just prevent their construction outside a factory class. This I think can be quite easily achieved by using package private (default) visibility in the class constructors. The only limitation is that you'll need to have the classes and the factory in the same package so in a medium to large codebase things may get unnecessarily complex.
If I understand your question correctly, you would like to make sure that users of your library are forced to use your factory to instantiate their objects rather than using the constructors themselves.
As I see it there are two possibilities, one of which is silly but usable in few, specific cases, and the other one is the most practical and probably most commonly used way of doing it.
You could make all your classes into
private inner classes of the
factory. This would work if you had
one factory per class, but is hardly
workable if you have a lot of
different classes being managed
through one factory.
You could use the protected access modifier to
restrict access to your class
constructors. This is common
practice when using the factory
pattern.
I think you will have either compiler failure or warning if your public factory method try to return something which is "hidden".
No, you can not hide a public class without reimplementing your own ClassLoader or using OSGi or anything similar.
What you can do is to separate interface api from the implementation, e.g. have one project which contains only the interfaces and another porject which contains the implmentations. However, you still cannot hide the implementation classes.
Obfuscation can help you somehow.
With standard classloaders and plain old jar files, this is not possible. OSGi has this concept of making visible only some packages to another bundle(i.e. separation of public api and internal implementation).
If you are using eclipse, you may enforce such rules with this
If I understand you correctly when you say "not to allow direct instantiation of the classes to keep it more flexible", a properly executed facade pattern will handle this.
Restrict the constructors of all the classes you want to hide to package scope. Open the facade class to public scope.
http://mindprod.com/jgloss/packagescope.html
"If you have a variable or method in
your class that you don’t want clients
of your class directly accessing,
don’t give it a public, protected or
private declaration. Due to an
oversight in the design of Java, you
can’t explicitly declare the default
“package” accessibility. Other members
of the package will be able to see it,
but classes outside the package that
inherit from yours, won’t. The
protected accessibility attribute
offers slightly more visibibily. A
protected method is visible to
inheriting classes, even not part of
the same package. A package scope
(default) method is not. That is the
only difference between protected and
package scope. "
There are two solutions to your question that don't involve keeping all classes in the same package.
The first is to use the Friend Accessor/Friend Package pattern described in (Practical API Design, Tulach 2008).
The second is to use OSGi. There is an article here explaining how OSGi accomplishes this.
Related Questions: 1, 2, 3, and 4.
You can do such magics with a custom class loader but:
the correct separation will be available only in a project staffed with your class loader;
it's really doubtful that the effort to create such loader is worthy.
In such situations I would do something similar to what we may see in the standard Java. E.g.you see javax.xml.stream.XMLInputFactory but somewhere you have com.sun.xml.internal.stream.XMLInputFactoryImpl. It is perfectly compilable if you write:
new com.sun.xml.internal.stream.XMLInputFactoryImpl()
though you will hardly do it :-) With a system property you may control the actual implementation that is being loaded. To me such approach is fine in many situations.
I hope I have understood your question correctly ;)
Cheers!
I realise that this is a very basic question, but it is one which has always bothered me. As I understand things, if you declare a field private in Java then it is not visible outside of that class. If it is protected then it is available to inherited classes and anything in the same package (correct me if either of those definitions is incorrect).
Does this mean it is not possible to declare a field that is accessible to only inherited classes and not other non-inherited classes in the same package?
I appreciate that there are ways around this, but are there instances when you would want to have this sort of behaviour?
Obviously the above question applies to methods as well as fields.
Many thanks.
See: http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html
Package > Subclasses, you can never have a field only visible by subclasses but not by classes from the same package.
Basically:
private: Accessible only by the class.
public: Accessible by any class.
protected: Accessible by the class, all inherited classes and the classes of the current package (edited).
no scope defined: Accessible by all classes of the current package.
more information here.
Yes, Java's protected access is a little bit odd in that way. I can't immediately see why it's desirable at all. Personally it doesn't bother me for fields as I don't like non-private fields anyway (other than constants) but the same is true for other members.
.NET doesn't have the concept of package/namespace access visibility at all, but it has an alternative which is assembly (think "jar file" - not exactly the same, but close). Frankly I'd like to have namespace and deployment-unit visibility options, but it seems I'm doomed to disappointment...