Naming of classes that may collide with java.lang.* - java

Since java.lang.* classes are implicitly imported into every source file, this makes it harder for a developer to use these class names in their own namespaces. For example, someone may want to create a Compiler class, since it is a common name and java.lang.Compiler is a rarely used. By doing so, the developer would have to use its fully qualified name, like com.my.organization.my.very.long.package.name.Compiler, every time, which does not improve code readability. Explicitly importing this class would be very confusing, and changing the name to something more specific is not always an option, because Compiler might be instead an interface for generic anything-to-anything compiler. Thus, in some cases the only option is to add a prefix or a suffix to distinguish the name. Another example I can imagine is a forum application, which may have classes like Author, Post, and yes - Thread. Adding anything to Thread would clearly distinguish it from functionally similar classes. Are there any conventions on class naming in such cases? The least intrusive option I personally see is adding a trailing underscore, like Thread_.

I've generally been able to come up with names that avoided being so generic they conflicted, but even in those situations where you can't, provided your code is in a package, the unqualified name will be the package's class, not the java.lang one:
stuff/Compiler.java:
package stuff;
public class Compiler {
public static long value = 42L;
}
stuff/Foo.java:
package stuff;
public class Foo {
public static void main(String[] args) {
System.out.println(Compiler.value); // <== Compiler is stuff.Compiler
}
}
Running that (java stuff/Foo) prints 42.

Related

What are auxiliary classes?

I know these questions may sound stupid, but in Java, what are Auxiliary classes, how does some one write one, and how does the compiler know that something is an Auxiliary class?
Edit:
The reason I ask this is because the compiler is generating a warning regarding an object in an external library, and I want to know why.
Edit 2:
Here is the compiler warning for those who want it:
warning: auxiliary class Pattern in jregex/Pattern.java should not be accessed from outside its own source file
As descried in Java specification here, you can specify more than one class in one .java file. The class which name matches .java file name will be the main class which can be declared public and be visible to other classes. All other classes in the file therefore are "auxilary" classes. Auxilary class can NOT be declared public and (as #trashgod rightfully pointed out) therefore they only be declared with package-private access. For instance for AClass.java file:
public class AClass {
private AuxilaryClass a;
}
class AuxilaryClass {
private int b;
}
AuxilaryClass class can't be public and is not visible outside this AClass.java file.
However, using auxilary classes considered extremely bad style and against Java Code Convention. Please use separate or inner classes if really needed.
Edit: The term "Auxilary" is not Oracle/Sun official terminology. It has been introduced (or used) here: http://www.youtube.com/watch?v=miTM9rY3He0 and/or here: http://doc.sumy.ua/prog/java/langref/ch05_03.htm
An auxiliary class isn't any kind of official or technical thing as far as I know. Someone might describe a class as auxiliary if it were addressing a secondary concern, or something, but the compiler doesn't have any idea what an auxiliary class is, and neither do I.
In general, if you have error messages from the computer, please paste them in their entirety. If you think the compiler is upset about an auxiliary class, paste the error message: someone else will be able to make sense of it, whereas currently it's being filtered through some kind of confusion that's made you think auxiliary classes are a real thing!

Disable enforcement of "The public type xyz must be defined in its own file"

Noob java question.
For my project, I have a class model defined in XML file, which I then transform into a model. For example:
<model>
<class name="abc"><field>one</field><field>two</field></class>
<class name="xyz"><field>f1</field><field>f2/field></class>
</model>
and this gets transformed into:
public class abc {
String _one;
String _two;
public String get_one() {
return _one;
}
... and so on you get an idea
Obviously, it would be a nuisance to transform each class into its own .java file. It would be much more manageable to pile them up in a single .java file. However, java has this requitement that each class must be defined in its own file, and the file name must match class name. Otherwise, compiler will show error: The public type XYZ must be defined in its own file
It's likely possible to define it like this:
public class ModelContainer {
public class abc {
...
}
public class xyz {
...
}
}
Is there another way? Ideally, I'm looking for a compiler switch or something of that kind, which would disable the requirement to have each class in its own file. I am using Eclipse if that makes any difference
If you're ok with using inner classes then yes, this will work but you'll have to obtain an instance of the outer class each time you want to instantiate an inner class:
public class ModelContainer {
public class abc {
...
}
public class xyz {
...
}
}
Also you can declare the nested classes as static, so it won't be necessary to instantiate the outer class first:
public class ModelContainer {
public static class abc {
...
}
public static class xyz {
...
}
}
Take a look at this post for additional details.
Interestingly enough, it's not actually a language requirement to have each top-level class in its own .java file:
If and only if packages are stored in a file system (ยง7.2), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:
The type is referred to by code in other compilation units of the package in which the type is declared.
The type is declared public (and therefore is potentially accessible from code in other packages).
That said, since the compiler may enforce such a requirement, all portable code should conform to the practice.
Regarding your specific case, you should consider the one-top-level-class-per-file rule to be a language requirement. The usual approach is in fact to generate a separate .java file for each class (there are a number of annoying aspects to using nested classes, even static ones), but you could work around this by using nested classes if you have a better reason than not closing and opening files.
An alternate, but slightly more-sophisticated approach would be to skip creating Java source at all. You could use a bytecode library such as Javassist or ASM to create class files directly. Essentially, you would be compiling your XML declaration to executable code.
If you are creating simple value objects as shown, this would be pretty easy.
You seem to have a problem with generating large numbers of files, so you could write the class files directly into a JAR file (using the ZIP I/O classes) and generate your synthetic classes as a single library file.
(You might wish to mark these classes as synthetic, although the XML declaration could be considered source code, meaning that they are not technically synthetic.)
The compiler switch you want doesn't exist. Ensuring that each class is in a correctly-named file - and in the correct place in the directory hierarchy, assuming you're organizing your classes in packages - is always enforced by the Java compiler. Most Java devs wouldn't dream of turning this off, as this way of organizing one's source code is considered good practice. (Therefore Java devs have minor nightmares when attempting to navigate large, unruly projects in languages like C# that don't enforce this restriction.)
The only classes that don't need to obey this constraint are anonymous or inner classes, but your application shouldn't consist mostly of these.

"Module" functionality in Java?

In Vb.net, we have something called a "Module" that provides a global scope whereby static functions in the module is visible throughout the entire project.
Is there such a functionality in Java ? (i.e. adding static methods that are available to multiple packages/files/classes without having the need to import .* )
Ok I am aware this is a functionality that would cause alot of debate, but really the point of this thread is not to debate about this functionality.
To answer literally, no, there's no real "global" in Java. But you don't need to import, particularly not import .*.
The code below illustrates that an import is not required but it's only really part of the answer.
package org.example.pkg.foo;
public class Foo {
public static void doSomething();
}
package org.example.pkg.bar;
public class Bar {
public void bar() {
org.example.pkg.foo.Foo.doSomething();
}
}
In Java, types, such as classes and interfaces, are defined in terms of the ClassLoader which loaded them. You can have multiple class loaders, which implies that multiple copies of the same class can be loaded. The obvious extension of this is that multiple classes with the same qualified name (package + class) can be loaded, and there's no inherent requirement that they are related.
OSGi is an example of this, where each bundle has it's own class loader, and as a result you can have multiple versions of the same class loaded at the same time.
How does this relate to the question? Well, without accurately identifying the class you want to reference it's not possible to accurately identify the method or member you want to reference. The import, or FQN referencing does that.
No, don't think so. Static imports can make it a bit less painful/verbose to use such methods, but it's generally advised to be careful with them.
Not without the import. You can declare public static methods that are accessible from anywhere in the project, but you still have to either import the class or use fully qualified class path when you use it.
public methods are visible throughout the project
however if you want to dispense with the imports you can make the path explicit
my.package.UtilClass.methodIWannaCall(someArg);
No. Import is needed for any static method to be visible.(which is a good thing).
As others mentioned, Java IDEs do this job for us.

Java: refactoring static constants

We are in the process of refactoring some code. There is a feature that we have developed in one project that we would like to now use in other projects. We are extracting the foundation of this feature and making it a full-fledged project which can then be imported by its current project and others. This effort has been relatively straight-forward but we have one headache.
When the framework in question was originally developed, we chose to keep a variety of constant values defined as static fields in a single class. Over time this list of static members grew. The class is used in very many places in our code. In our current refactoring, we will be elevating some of the members of this class to our new framework, but leaving others in place. Our headache is in extracting the foundation members of this class to be used in our new project, and more specifically, how we should address those extracted members in our existing code.
We know that we can have our existing Constants class subclass this new project's Constants class and it would inherit all of the parent's static members. This would allow us to effect the change without touching the code that uses these members to change the class name on the static reference. However, the tight coupling inherent in this choice doesn't feel right.
before:
public class ConstantsA {
public static final String CONSTANT1 = "constant.1";
public static final String CONSTANT2 = "constant.2";
public static final String CONSTANT3 = "constant.3";
}
after:
public class ConstantsA extends ConstantsB {
public static final String CONSTANT1 = "constant.1";
}
public class ConstantsB {
public static final String CONSTANT2 = "constant.2";
public static final String CONSTANT3 = "constant.3";
}
In our existing code branch, all of the above would be accessible in this manner:
ConstantsA.CONSTANT2
I would like to solicit arguments about whether this is 'acceptable' and/or what the best practices are.
A class with only static fields is a code smell. It's not a class.
Some people use interfaces, so they can implement it to use the constants more easily. But an interface should be used only to model a behaviour of a class. (http://pmd.sourceforge.net/rules/design.html#AvoidConstantsInterface) Using static imports from Java 5 removes the need for simple constant usage at all.
Are your constants really Strings, or just used as Strings. If they are different options for some type (so called enumerations), you should used typesafe enumerations, using enum in Java 5 or the Enum provided by Commons Lang. Of course, converting your code to use enums might be a little work.
You should at least split the constants to groups of related constants in files with proper business name. Moving the final members is easy in IDE and will update all usages.
If you can afford it, convert them to enums then. (Think about using about a script to do that, often it's possible.) Class hierarchies are only usefull, if there is a relation between the constants/enums. You can keep the Strings if you have to but still think about them as entities, then extends might make sense for some (describing is-a relation). First enums can be simple classes made by yourself if serializing is not a problem. Enums are always favourable due to their type safe nature and the extra name showing intend or business/domain specific things.
If the constants are really String constants use a Properies or ResourceBundle, which can be configured by plain text files. Again you can script the refactoring using the constant names as resource bundle keys and generate both files automatically.
I don't like it, but it's probably the best you can do right now.
The right answer would be to break up the constants into coherent groups, fixing the code breaks as you go along. In C#, I'd use enums.
Peter Kofler has already discussed how you might wish to better organize constants. I'll share how to automate the transition:
The eclipse "Inline" refactoring can automatically replace constants by their defintion, saving you from having to hunt down and change each usage manually. So you'd simply change the code to:
public class ConstantsA {
public static final String CONSTANT1 = "constant.1";
public static final String CONSTANT2 = ConstantsB.CONSTANTFOO;
public static final String CONSTANT3 = ConstantsB.CONSTANTBAR;
}
public class ConstantsB {
public static final String CONSTANTFOO = "constant.2";
public static final String CONSTANTBAR = "constant.3";
}
... and then have eclipse inline COONSTANT2 and CONSTANT3 (while all affected projects are checked out, if you can't do that, look into refactoring scripts), and you're done.
I've seen this done by putting the static final String on an interface, so that you can 'implement' it and not have to worry about what to do when you need a different base class. It's just as accessible that way.
In general though, enums are pretty good at what you are trying to do, and may get rid of the "I'm not sure" feeling you are experiencing, as that's the intention of enums.
I think what you are doing is fine. Yes, the classes are tightly-coupled, but that is kind of the point -- you want to be able to reference only a single class to see all of your project-wide constants.
You do have to be diligent to ensure that ConstantsB contains only constants that are generalizable amongst all your projects, and ConstantsA contains only project-specific constants. If, later on, you realize that there is a constant in ConstantsB that you seem to be overriding in your subclasses a lot, then that's an indication it should've never been put in ConstantsB in the first place.
I think what you've got is a good first step. The next step is to gradually replace all references to ConstantsA.CONSTANT2 and ConstantsA.CONSTANT3 with ConstantsB.CONSTANT2 and ConstantsB.CONSTANT3 until you can remove the extends.
Most IDEs can be configured to show a warning if you refer to a superclass constant via a subclass, and I'd guess static analysis tools like FindBugs can do it, too.
One idea that might be slightly cleaner:
make all the constants classes interfaces
move all the constants out of ConstantsA and call it something like LegacyConstants
have LegacyConstants extend all the other, modular Constants interfaces
deprecate LegacyConstants
The goal would be not to have any inheritance between the Constants interfaces. LegacyConstants would be the only place there's any inheritance, it wouldn't declare any constants of its own, and when it's no longer used -- when every class that did use it instead refers to the proper Constants interface -- you've finished refactoring.
When you extract your constants, have the old class reference the constant defined in the new class. There's really no need to create an inheritance relationship here.
I could be wrong, but I don't think we need constants at all. It just means that you can't change the value of the constants and you probably should.

Anonymous class binary names

I have the following problem:
1) There is some abstract class A with several anonymous subclasses stored in the static fields of A. There is circular dependency between two of the anonymous subclasses. The code of that abstract class is similar to following:
class A implements Serializable
{
public static final A _1 = new A() {
public A foo()
{
return _2;
}
};
public static final A _2 = new A() {
public A foo()
{
return _1;
}
};
public static final A _3 = new A() {
public void bar()
{
// do something
}
};
}
2) Instances of class A is referenced by other objects which are used in serialization. There are some objects which are pre-serialized by developers and then included into release as binary data.
After some refactoring of A class binary names of anonymous subclasses was changed in the release builds. I think this may be due to difference of java compiler versions. From .class files made on my machine I can see that anonymous subclasses of A stored in _1, _2 and _3 fields have names A$1, A$2 and A$3, respectively, but from .class files taken from release build I can see that anonymous subclasses of A stored in _1, _2 and _3 fields have names A$2, A$3 and A$1, respectively. Due to this pre-serialized data became unusable and I need to fix this somehow.
Are there any specifications for java compilers or JVM which will say what binary names I should expect for my anonymous classes? The JLS says that name of anonymous class should be name of enclosing class, "$"-sign and non-empty sequence of digits without setting any constraints on these sequences.
I believe that I shouldn't rely on internal names of anonymous classes, I also know "proper" ways to fix that problem like generating pre-serialized data on the build server. Too bad we don't have much time for this now, so I want to know from where this naming difference comes, so I could fix this issue now.
May I dare to challenge some elements ? Hopefully it can be useful to you :
if you want your classes to have a well-known name ... well, anonymous is the contrary of a named class ! ;-)
preserializing and delivering objects as binary data is a dangerous choice, and you got bitten by it (during a refactoring, but I believe that could happen in many other conditions). Serialized data is usually considered as a short term solution in Java, good for a few seconds. Many other options are available for longer term storage.
Now, if asked to solve your short-term problem, the only approach I see is to restore your classes to a state compatible with the previous version. If the different ordering you mention is the only difference, I believe that defining the anonymous classes in the same order as before is worth trying ! Also take care that references should be backwards (to a class earlier in the file), not forward (to a class later in the file).
The only reason I can guess why it fails is that the new Java version reorders the class names because you reference _2 in _1. That said, I don't think you can rely on the names since Java makes no guarantees in which order it will process fields of a class (and therefore, the sequence in which it will create inner classes).
But I think your problem is somewhere else. What error do you get?
Did your compiler not give any warnings?
I believe you can read the data without relying on the anonymous class names in the current code by overriding ObjectInputStream.readClassDescriptor. Replace with a descriptor of a "compatible" class. No guarantees that will work, but may be worth a try if your data is important.

Categories

Resources