Do java's Inner classes pose a security risk? - java

Recently the security team on my project released a secure code guidelines document, designed to be used as part of our code reviews. The first thing that struck me was an item that said "Do not use Inner classes". I thought this seemed like a very heavy handed and sweeping statement. Inner classes are good if used correctly right?, but i did a bit of googling and found this, quoted here for convenience.
Rule 5: Don't Use Inner Classes
Some Java language books say that
inner classes can only be accessed by
the outer classes that enclose them.
This is not true. Java byte code has
no concept of inner classes, so inner
classes are translated by the compiler
into ordinary classes that happen to
be accessible to any code in the same
package. And Rule 4 says not to depend
on package scope for protection.
But wait, it gets worse. An inner
class gets access to the fields of the
enclosing outer class, even if these
fields are declared private. And the
inner class is translated into a
separate class. In order to allow this
separate class access to the fields of
the outer class, the compiler silently
changes these fields from private to
package scope! It's bad enough that
the inner class is exposed, but it's
even worse that the compiler is
silently overruling your decision to
make some fields private. Don't use
inner classes if you can help it.
(Ironically, the new Java 2
doPrivileged() API usage guidelines
suggest that you use an inner class to
write privileged code. That's one
reason we don't like the
doPrivileged() API.)
My questions are
Does this behaviour still exist in java 5 / 6?
Is this actually a security risk, given that any class, other than the outer and inner classes, that tried to access the outer class' private members would not compile?
Does it pose enough of a security risk to warant the 'guideline' 'Do not use inner classes'?

This information is a around a decade out of date. The widespread use of anonymous inner classes with AccessController.doPrivileged should be a clue. (If you don't like the API, consider the proportion of try-finally blocks that are incorrectly missing in the JDK.)
The policy is that no two class can share the same package if they are loaded by different class loaders or have different certificates. For more protection, mark packages as sealed in the manifest of your jars. So, from a security standpoint, "Rule 4" is bogus and hence also this rule.
In any case, working out security policies you should understand what you are protecting against. These sorts of policies are for handling mobile code (code that moves) that may have different levels of trust. Unless you are handling mobile code, or your code is going into a library that may be required to, there is very little point in these sorts of precautions. However, it is almost always a good idea to use a robust programming style, for instance copying and validating arguments and return values.

Does this behaviour still exist in java 5 / 6?
Not exactly as described; I've never seen a compiler where this was true:
In order to allow this separate class access to the fields of the outer class, the compiler silently changes these fields from private to package scope!
Instead IIRC Sun Java 3/4 created an accessor rather than modifying the field.
Sun Java 6 (javac 1.6.0_16 ) creates a static accessor:
public class InnerExample {
private int field = 42;
private class InnerClass {
public int getField () { return field; };
}
private InnerClass getInner () {
return new InnerClass();
}
public static void main (String...args) {
System.out.println(new InnerExample().getInner().getField());
}
}
$ javap -classpath bin -private InnerExample
Compiled from "InnerExample.java"
public class InnerExample extends java.lang.Object{
private int field;
public InnerExample();
private InnerExample$InnerClass getInner();
public static void main(java.lang.String[]);
static int access$000(InnerExample);
}
$ javap -classpath bin -c -private InnerExample
static int access$000(InnerExample);
Code:
0: aload_0
1: getfield #1; //Field field:I
4: ireturn
Is this actually a security risk, given that any class, other than the outer and inner classes, that tried to access the outer class' private members would not com[p]ile?
I'm speculating a bit here, but if you compile against the class it doesn't, but if you add the access$000 then you can compile code which uses the accessor.
import java.lang.reflect.*;
public class InnerThief {
public static void main (String...args) throws Exception {
for (Method me : InnerExample.class.getDeclaredMethods()){
System.out.println(me);
System.out.printf("%08x\n",me.getModifiers());
}
System.out.println(InnerExample.access$000(new InnerExample()));
}
}
The interesting thing is that the synthesised accessor has modifier flags 00001008 where if you add a package level static method it has flags 00000008. There's nothing in the second edition of the JVM spec for that flag value, but it seems to prevent the method being seen by javac.
So it appears that there's some security feature there, but I can't find any documentation on it.
(hence this post in CW, in case someone does know what 0x1000 means in a class file)

Yes, this behavior still exists.
It is a security risk because the rogue class could be crafted with something else than the standard javac.
It depends of how much paranoid you are :) If you don't allow alien classes to run in your JVM, I don't see the problem though. And if you do, you have bigger problems (sandboxes and all)
I know you only had 3 questions, but like other people here, I think this is a stupid restriction.

Does this behaviour still exist in java 5 / 6?
You can use the javap tool to determine what your binaries are exposing and how.
package demo;
public class SyntheticAccessors {
private boolean encapsulatedThing;
class Inner {
void doSomething() {
encapsulatedThing = true;
}
}
}
The above code (compiled with Sun Java 6 javac) creates these methods in SyntheticAccessors.class:
Compiled from "SyntheticAccessors.java"
public class demo.SyntheticAccessors extends java.lang.Object{
public demo.SyntheticAccessors();
static void access$0(demo.SyntheticAccessors, boolean);
}
Note the new access$0 method.

You should consider what kind of security your application has to provide. An application with a secure architecture won't run into these named issues.
If there is something an user is not allowed to do with your code, you have to seperate this functionality and run it on a server (where the user has no access to the class files).
Remember that you can always decompile java class files. And don't rely on "security by obscurity". Even obfuscated code can be analyzed, understood and modified.

Malicious code can use java reflection to get to any piece of information in the JVM unless a security manager is in place which prohibits this, this includes changing private fields to public and much more.
My personal opinion is that the reasons not to, are overwhelmed by the other possibilities, so if you need it, it makes sense, and it is readable, use inner classes.

The idea of this kind of security in code is kind of silly. If you want code level security, use an obfuscation tool. Like #skaffman said in the comments above, "Code visibility has never been a security feature. Even private members can be accessed using reflection.".
If you are distributing your compiled code and not obfuscating it, then using an inner class is your last worry if you are worried about people tinkering with your privates.
If you are hosting your code, then why are you worried about someone poking around your inner classes?
If you going to linking some 3rd party code you don't trust and can't check at run time, then sandbox it.
Like I said above, if this is really a policy at your company, please promptly report your company to thedailywtf.com

"Is this actually a security risk, given that any class, other than the outer and inner classes, that tried to access the outer class' private members would not compile?"
Even if it won't compile under normal circumstances, you can still generate your own bytecode. But that's no reason to avoid inner classes. All you would have to do is assume all your inner classes are public.
If you really want to be able to run untrusted code, learn how setup your own sandboxes and security levels using The Java Security Architecture, it's not that hard. But mostly, you should avoid running random code in a secure environment.

nonsense! follow the same logic, do not write public methods either, because they have access to private fields, gush!

Note that the drawbacks listed do not hold for static inner classes as they do not have implicit access to their enclosing class (or object really.)
So if this rule is going to help up in your company, it might be an idea to get static inner classes excempted as they offer a way for encapsulation which is useful in many cases.
#Tom, quoting the Java language specification, "Member classes may be static, in which case they have no access to the instance variables of the surrounding class"

Related

How to test default access level class in Java without making everything public?

In Swift, to test a default access level class, one can put #testable in the test class header, making the internal access level class accessible and testable from the test package, without everything in the class public. I was wondering if Java has a way to access the same purpose?
How can I test a default access level class in Java from the test package without making everything in the class public?
There are #VisibleForTesting annotations in some java libs, but generally it does not prevent illegal access. Even making package protected does not solve all the issues as still some other classes can use testing code, which can lead to some unexpected behaviour. I recently stumbled upon nice construct that allows you to show the intentions about exposing some methods for tests
public class A{
private int someMethodYouWantToTest(){}
private Testability testability = new Testability();
class Testability{
int exposedMethodForTest(){
someMethodYouWantToTest()
}
}
}
And then in your test class
public class Test{
private A underTest = new A()
public void testHiddenMethod(){
a.testability.exposedMethodForTest()
}
}
This way you private method is private, and only access if by dedicated testability inner class that clearly states its purpose, so no one by accident calls your method outside of tests. This solves issues with package protected businness methods that may be called from other places but were really meant to be private.
In Java, the only thing you can do is make things package protected if you want them to be used from your test code (that is: if you don't want them to be public).
Example: my classes very often look like
class Whatever
public Whatever() { this(new A(), new B()); };
Whatever(A a, B b) { ...
allowing me to use the second constructor for unit tests that require dependency injection; and at the same time relying on the "convention" that production code should prefer to always use the public constructor.
So even when I have classes that I don't want to be used outside of my package ... i make the constructor public to indicate: use this one please.
The idea is basically that your production code and test code resides in identically-named packages.
In other words: Java doesn't have this nice feature of giving access only to test code.
Quoting an answer to a similar question
"
You generally don't unit test private methods directly. Since they are
private, consider them an implementation detail. Nobody is ever going
to call one of them and expect it to work a particular way.
You should instead test your public interface. If the methods that
call your private methods are working as you expect, you then assume
by extension that your private methods are working correctly."
This is equivalent to option 1 in this link
If 1 does not fit your goals, you can try Approach 2,3 and 4 mentioned in the link
Sure it is not perfect that one has to make methods visible for testing that would otherwise be private, even if it is only in the classes own package.
On the other side, it is anyway recommended (and has many great benefits) not to depend on impelementations but on Interfaces.
That means: Give the client an Interface that declares only the methods you want to expose and make the methods you have to test in your implementation protected and do not include them in the interface.

Check if object is instanceof a protected class

Say I am using a Java library that has the following method
public static SomeInterface foo();
The interface SomeInterface has multiple implementations, some of which are protected within the library's package. One of these implementation is TheProtectedClass
What would be the best way to check if the object returned by foo() is an instance of TheProtectedClass?
My current plan is to create an Utils class that lives within my project but in the same package as the protected class. This Utils can refer to TheProtectedClass since it is in the same package and thus it can check if an object is instanceof TheProtectedClass.
Any other ideas?
EDIT: Some people are asking "why" so here is more context.
I am using jOOQ and in some part of my code, I want to know if the Field instance that I have is an instance of Lower.
Currently, I use field.getName().equals("lower") but this isn't as robust as I'd like it to be.
I realize that since Lower is a protected class, it isn't part of the API and that it can change but I am ok with that.
Class.forName("TheProtectedClass").isAssignableFrom(foo())
although it is a bad idea for many reasons. You're breaking the encapsulation and the abstraction here. If it's package-private, you shouldn't have to concern with it outside. If it's protected, you should explicitly inherit from it and use the API provided by class for this case.
The less obvious but more correct solution is to get an instance of TheProtectedClass, and compare it by
guaranteedTPCInstance.getClass().isAssignableFrom(foo())
, while still being kind of hacky, at least is more portable and OOPy IMO.
As to your idea of creating a class in the same package as TheProtectedClass to avoid being package-private - it's a viable solution, but a) it breaks the basic principle of encapsulation and the programming contract of the TPC class; packaging is done by library/class authors for a reason - to prevent irresponsible data access and using private API or undocumented proprietary methods, b) it's not always possible (and shouldn't be possible in case of properly designed library classes), since those classes can be not only package-private, but final or effectively final (anonymous inner classes etc) - for the reasons described by Bloch in EJ 2nd, "favor composition over inheritance" item, see also Good reasons to prohibit inheritance in Java? Use of final class in Java etc c) you can't do it with some Java library classes, as you can't define your class to be and use e.g. java.lang package. As such, the only "portable" solution is through reflection and through what I described.
tl;dr The fact you can piggyback another package by mimicking its package definition is an obvious C-style deficiency of Java's syntax (allowing programmer to do what he shouldn't be able to normally do; same goes with some specific reflection methods); hacks made this way are neither maintainable nor safe.
NOTE: If you you expect to do something in a internal implementation-dependent and, at the same time, portable and maintainable (e.g. impervious to implementation changes/class name changes etc) way, you're obviously expecting the impossible.
It appears that the best solution is to create a package in your project that has the same package as the package-private class and either expose TheProtectedClass.class as a Class<?> or simply add a simple method that checks if your Object is instanceof TheProtectedClass.
This does not require reflection, it is fast and relatively safe (compilation will break if the package-private class changes name).

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!

Should Java methods be static by default?

Say you're writing method foo() in class A. foo doesn't ever access any of A's state. You know nothing else about what foo does, or how it behaves. It could do anything.
Should foo always be static, regardless of any other considerations? Why not?
It seems my classes are always accumulating many private helper methods, as I break tasks down and apply the only-write-it-once principle. Most of these don't rely on the object's state, but would never be useful outside of the class's own methods. Should they be static by default? Is it wrong to end up with a large number of internal static methods?
To answer the question on the title, in general, Java methods should not be static by default. Java is an object-oriented language.
However, what you talk about is a bit different. You talk specifically of helper methods.
In the case of helper methods that just take values as parameters and return a value, without accessing state, they should be static. Private and static. Let me emphasize it:
Helper methods that do not access state should be static.
1. Major advantage: the code is more expressive.
Making those methods static has at least a major advantage: you make it totally explicit in the code that the method does not need to know any instance state.
The code speaks for itself. Things become more obvious for other people that will read your code, and even for you in some point in the future.
2. Another advantage: the code can be simpler to reason about.
If you make sure the method does not depend on external or global state, then it is a pure function, ie, a function in the mathematical sense: for the same input, you can be certain to obtain always the same output.
3. Optimization advantages
If the method is static and is a pure function, then in some cases it could be memoized to obtain some performance gains (in change of using more memory).
4. Bytecode-level differences
At the bytecode level, if you declare the helper method as an instance method or as a static method, you obtain two completely different things.
To help make this section easier to understand, let's use an example:
public class App {
public static void main(String[] args) {
WithoutStaticMethods without = new WithoutStaticMethods();
without.setValue(1);
without.calculate();
WithStaticMethods with = new WithStaticMethods();
with.setValue(1);
with.calculate();
}
}
class WithoutStaticMethods {
private int value;
private int helper(int a, int b) {
return a * b + 1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int calculate() {
return helper(value, 2 * value);
}
}
class WithStaticMethods {
private int value;
private static int helper(int a, int b) {
return a * b + 1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int calculate() {
return helper(value, 2 * value);
}
}
The lines we are interested in are the calls to helper(...) on the classes WithoutStaticMethods and WithStaticMethods.
Without static methods
In the first case, without static methods, when you call the helper method the JVM needs to push the reference to the instance to pass it to invokespecial. Take a look at the code of the calculate() method:
0 aload_0
1 aload_0
2 getfield #2 <app/WithoutStaticMethods.value>
5 iconst_2
6 aload_0
7 getfield #2 <app/WithoutStaticMethods.value>
10 imul
11 invokespecial #3 <app/WithoutStaticMethods.helper>
14 ireturn
The instruction at 0 (or 1), aload_0, will load the reference to the instance on the stack, and it will be consumed later by invokespecial. This instruction will put that value as the first parameter of the helper(...) function, and it is never used, as we can see here:
0 iload_1
1 iload_2
2 imul
3 iconst_1
4 iadd
5 ireturn
See there's no iload_0? It has been loaded unnecessarily.
With static methods
Now, if you declare the helper method, static, then the calculate() method will look like:
0 aload_0
1 getfield #2 <app/WithStaticMethods.value>
4 iconst_2
5 aload_0
6 getfield #2 <app/WithStaticMethods.value>
9 imul
10 invokestatic #3 <app/WithStaticMethods.helper>
13 ireturn
The differences are:
there's one less aload_0 instruction
the helper method is now called with invokestatic
Well, the code of the helper function is also a little bit different: there's no this as the first parameter, so the parameters are actually at positions 0 and 1, as we can see here:
0 iload_0
1 iload_1
2 imul
3 iconst_1
4 iadd
5 ireturn
Conclusion
From the code design angle, it makes much more sense to declare the helper method static: the code speaks for itself, it contains more useful information. It states that it does not need instance state to work.
At the bytecode level, it is much more clear what is happening, and there's no useless code (that, although I believe the JIT has no way to optimize it, would not incur a significant performance cost).
If a method does not use instance data, then it should be static. If the function is public, this will give the important efficiency boost that you don't need to create a superfluous instance of the object just to call the function. Probably more important is the self-documentation advantage: by declaring the function static, you telegraph to the reader that this function does not use instance data.
I don't understand the sentiment of many posters here that's there's something wrong with having static functions in a Java program. If a function is logically static, make it static. The Java library has many static functions. The Math class is pretty much filled with static functions.
If I need, say, a function to calculate a square root, the rational way to do it would be:
public class MathUtils
{
public static float squareRoot(float x)
{
... calculate square root of parameter x ...
return root;
}
}
Sure, you could make a "more OOPy" version that looked like this:
public class MathUtils
{
private float x;
public MathUtils(float x)
{
this.x=x;
}
public float squareRoot()
{
... calculate square root of this.x ...
return root;
}
}
But aside from meeting some abstract goal of using OOP whenever possible, how would this be any better? It takes more lines of code and it's less flexible.
(And yes, I now there's a square root function in the standard Math class. I was just using this as a convenient example.)
If the only place a static function is used and is every likely to be used is from within a certain class, then yes, make it a member of that class. If it makes no sense to call it from outside the class, make it private.
If a static function is logically associated with a class, but might reasonably be called from outside, then make it a public static. Like, Java's parseInt function is in the Integer class because it has to do with integers, so that was a rational place to put it.
On the other hand, it often happens that you're writing a class and you realize that you need some static function, but the function is not really tied to this class. This is just the first time you happened to realize you need it, but it might quite rationally be used by other classes that have nothing to do with what you're doing now. Like, to go back to the square root example, if you had a "Place" class that included latitude and longitude, and you wanted a function to calculate the distance between two places and you needed a square root as part of the calculation, (and pretending there was no square root function available in the standard library), it would make a lot of sense to create a separate square root function rather than embedding this in your larger logic. But it wouldn't really belong in your Place class. This would be a time to create a separate class for "math utilities" or some such.
You ask, "Should foo always be static, regardless of any other considerations?" I'd say "Almost, but not quite."
The only reason I can think of to make it not static would be if a subclass wants to override it.
I can't think of any other reasons, but I wouldn't rule out the possibility. I'm reluctant to say "never ever under any circumstances" because someone can usually come up with some special case.
Interesting question. In practical terms, I don't see the point in making class A's private helper methods static (unless they're related to a publicly-accessible static method in A, of course). You're not gaining anything -- by definition, any method that might need them already has an instance of A at its disposal. And since they're behind-the-scenes helper methods, there's nothing to say you (or another co-worker) won't eventually decide one of those stateless helpers might actually benefit from knowing the state, which could lead to a bit of a refactoring nuisance.
I don't think it's wrong to to end up with a large number of internal static methods, but I don't see what benefit you derive from them, either. I say default to non-static unless you have a good reason not to.
No. Never. Static methods should be an exception. OO is all about having Objects with behaviour which revolves around the object's state. Imho, ideally, there shouldn't be any (or very few) static methods, because everything unrelated to the object's state could (and to avoid leading the concept of an object ad absurdum, should) be placed in a plain old function at module level. Possible exception for factories because Complex.fromCartesian (to take a wikipedia example) reads so well.
Of course this (edit: Module-level functions) isn't possible in a single-paradigm OO language (edit: like Java) - that's why I'm such a devoted advocate of multi-paradigm language design, by the way. But even in a language exclusively OO, most methods will revolve around the object's state and therefore be nonstatic. That is, unless your design has nothing to do with OO - but in this case, you're using the wrong language.
I usually
Perform these steps in order, as needed:
a) I write some code in a member method, figure out that I can probably re-use some of this code and
Extract to non-static method
b) Now I'll see if this method needs access to state or if I can fit its needs into one or two parameters and a return statement. If the latter is the case:
Make method (private) static
c) If I then find that I can use this code in other classes of the same package I'll
Make method public and move Method to a package helper class with default visibility
E.g. In package com.mycompany.foo.bar.phleeem I would create be a class PhleeemHelper or PhleeemUtils with default visibility.
d) If I then realize that I need this functionality all over my application, I
Move the helper class to a dedicated utility package
e.g. com.mycompany.foo.utils.PhleeemUtils
Generally I like the concept of least possible visibility. Those who don't need my method shouldn't see it. That's why I start with private access, move to package access and only make things public when they are in a dedicated package.
Unless you pass in an object reference, a static method on an class enforces that the method itself cannot mutate the object because it lacks access to this. In that regard, the static modifier provides information to the programmer about the intention of the method, that of being side-effect free.
The anti-static purists may wish to remove those into a utility class which the anti-utility purists surely object to. But in reality, what does artificially moving those methods away from their only call site achieve, other than tight coupling to the new utility class.
A problem with blindly extracting common utility methods into their own classes is those utilities should really be treated as a new public API, even if it's only consumed by the original code. Few developers, when performing the refactoring, fail to consider this. Fast-forward to other devs using the crappy utility class. Later on somebody makes changes to the extension to suit themselves. If you're lucky a test or two breaks, but probably not.
I generally don't make them static but probably should. It's valuable as a hint to tell the next coder that this method CANT modify the state of your object, and it's valuable to give you a warning when you modify the method to access a member that you are changing the nature of the method.
Coding is all about communicating with the next coder--don't worry about making the code run, that's trivial. So to maximize communication I'd say that if you really need such a helper, making it static is a great idea. Making it private is critical too unless you are making a Math. like class.
Java conflates the concepts of module, namespace, adt, and class, as such to claim that some class-oriented OO-purity should prevent you from using a java class as a module, namespace, or adt is ridiculous.
Yes the methods should be static. Purely internal support methods should be private; helper methods protected; and utility functions should be public. Also, there is a world of difference between a static field, a static constant, and a public static method. The first is just another word for 'global variable'; and is almost always to be avoided, even mediation by accessor methods barely limits the damage. The second is treating the java class as a namespace for a symbolic constant, perfectly acceptable. The third is treating the java class as a module for a function, as a general rule side-effects should be avoided, or if necessary, limited to any parameters passed to the function. The use of static will help ensure that you don't inadvertently break this by accessing the object's members.
The other situation you will find static methods invaluable is when you are writing functional code in java. At this point most of the rules-of-thumb developed by OO-proponents go out the window. You will find yourself with classes full of static methods, and public static function constants bound to anonymous inner functors.
Ultimately java has very weak scoping constructs, conflating numerous concepts under the same 'class' and 'interface' syntax. You shouldn't so much 'default' to static, as feel free to use the facilities java offers to provide namespaces, ADT's, modules, etc as and when you feel the need for them.
I find it difficult to subscribe to those avoid-static-methods theories. They are there to promote a completely sanitary object-oriented model anti-septically cleansed of any deviation from object relationships. I don't see any way essential to be anti-septically pure in the practice object-orientedness.
Anyway, all of java.util.Arrays class are static. Numeric classes Integer, Boolean, String have static methods. Lots of static methods. All the static methods in those classes either convert to or from their respective class instances.
Since good old Gosling, et al, proved to be such useful role models of having static methods - there is no point avoiding them. I realise there are people who are perplexed enough to vote down my response. There are reasons and habits why many programmers love to convert as much of their members to static.
I once worked in an establishment where the project leader wanted us to make methods static as much as possible and finalize them. On the other hand, I am not that extreme. Like relational database schema design, it all depends on your data modelling strategy.
There should be a consistent reason why methods are made static. It does not hurt to follow the standard Java library pattern of when methods are made static.
The utmost importance is programming productivity and quality. In an adaptive and agile development environment, it is not only adapting the granularity of the project to respond effectively to requirements variation, but also adapting programming atmosphere like providing a conformable coding model to make best use of the programming skill set you have. At the end of the day (a project almost never ends), you want team members to be efficient and effective, not whether they avoided static methods or not.
Therefore, devise a programming model, whether you want MVP, injection, aspect-driven, level of static-avoidance/affinity, etc and know why you want them - not because some theoretical nut told you that your programming practice would violate oo principles. Remember, if you work in an industry it's always quality and profitability not theoretical purity.
Finally what is object-oriented? Object-orientation and data normalization are strategies to create an orthogonal information perspective. For example, in earlier days, IBM manuals were written to be very orthogonal. That is, if a piece of info is written somewhere in a page within those thousands of manuals, they avoid repeating that info. That is bad because you would be reading learning how to perform a certain task and frequently encounter concepts mentioned in other manuals and you would have to be familiar with the "data model" of the manuals to hunt those connecting pieces of info thro the thousands of manuals.
For the same reason, OS/2 failed to compete with Microsoft because IBM's concept of orthogonality was purely machine and data based and IBM was so proudly declaring their true object-orientedness vs Microsoft's false object-orientedness pandering to human perspective. They had forgotten we humans have our own respective varying orthogonal perspectives of information that do not conform to data and machine based orthogonality or even to each other.
If you are familiar with the topology of trees, you would realise that you could pick any leaf node and make it the root. Or even any node, if you don't mind having a multi-trunk tree. Everyone thinks his/her node is the root when in fact any could be the root. If you think your perspective of object-orientation is the canon, think again. More important is to minimise the number of nodes that are accepted as candidate roots.
There needs to be a compromise between effectiveness and efficiency. There is no point in having an efficient data or object model that can be hardly effectively used by fellow programmers.
If it does nothing with objects of this class, but actually belong to this class (I would consider moving it elsewhere), yes it should be static.
Don't use static if you can avoid it. It clashes with inheritance ( overriding ).
Also, not asked but slightly related, don't make utility methods public.
As for the rest, I agree with Matt b. If you have a load of potentially static methods, which don't use state, just put them in a private class, or possibly protected or package protected class.
It depends i.g. java.lang.Math has no method which isn't static.
(You could do a static import to write cos() instead of Math.cos())
This shouldn't be overused but as some code that is intented to be called as a utility it would be acceptable. I.g Thread.currentThread()
A static method is used to identify a method (or variable for that matter) that does not have to do with the objects created from that class but the class itself. For instance, you need a variable to count the number of objects created. You would put something like: 'private static int instances = 0;' and then put something in the constructor for that class that increments 'instances' so you may keep count of it.
Do think hard before creating a static method, but there are times when they are a good solution.
Joshua Bloch in "Item 1: Consider Static Factory Methods Instead of Constructors" in Effective Java makes a very persuasive case that static methods can be very beneficial. He gives the java.util.Collections class's 32 static factory methods as an example.
In one case, I have a hierarchy of POJO classes whose instances can be automatically serialized into XML and JSON, then deserialized back into objects. I have static methods that use Java generics to do deserialization: fromXML(String xml) and fromJSON(String json). The type of POJO they return isn't known a priori, but is determined by the XML or JSON text. (I originally packaged these methods into a helper class, but it was semantically cleaner to move these static methods into the root POJO class.)
A couple of other examples:
Using a class as a namespace to group related methods (eg, java.lang.Math).
The method truly is a private class-specific helper method with no need to access instance variables (the case cited here). Just don't sneak a this-equivalent into its argument list!
But don't use statics unthinkingly or you run the danger of falling into a more disorganized and more procedural style of programming.
No, the use of statics should be quite niche.
In this case the OP is likely 'hiding' state in the parameters passed into the static method. The way the question is posed makes this non-obvious (foo() has no inputs or outputs), but I think in real world examples the things that should actually be part of the object's state would fall out quite quickly.
At the end of the day every call to obj.method(param) resolves to method(obj, param), but this goes on at a way lower level than we should be designing at.
If it's only ever used by methods in A and wouldn't have any use outside it, then it should be static (and, probably, be placed in a Helper Class. It doesn't have any use outside A now, but there's no guarantee it will never have. Otherwise, it shouldn't.
If it doesn't have anything to do with the state of A, it could be useful at other places...
Anyway, that doesn't make a good reason for Java methods to be static by default.
Talking about this last issue, they shouldn't be static by default, because having to write 'static' make people think before writing static methods. That's a good practice when you have heterogeneous teams (the ones where Java is most useful).
When you write a static method you should keep in mind that you'r gonna use it at use-site with static-import (make it look class free) and thus it should behave just like a function which doesn't something and may or may not return something and is isolated with the state of class it belongs to. So static methods should be a rare situation.
If you seem to be making a lot of helper methods, then consider using package-private instance methods instead of private ones. Less typing, less boilerplate since you can re-use them as a helper to other classes in the same package.
I think "private static" (edit: for methods) is kind of an oxymoron in Java. The main point of static methods in my mind is to provide access to functions outside of the context of object instances. In other words, they're practically only ever useful if they're public. If you're only calling a method from within the context of a single object instance, and that method is private, it makes no sense to make it static. (edit: but, it makes no practical difference).
In this sort of case, I usually try to make the methods abstract enough that they're useful in other contexts, and I make them public in a utility class. Look at it as writing supporting library code, and think hard about your api.
Most static methods are written because
You break down a complex method into submethods, or
You wish String (or Date, or...) had some functionality that it doesn't have
The first is not bad per se, but it's often a sign that you're missing objects. Instead of working with default types such as String or List, try inventing your own classes and move the static methods to those classes.
The second reason produces the always-popular StringUtil, DateUtil, FooUtil classes. These are problematic because you have no way to discover that they exist, so programmers often write duplicates of these utility methods. The solution, again, is to avoid using String and Date all the time. Start creating your own objects, perhaps by wrapping the original object. The static methods become non-static methods of the new object.
If foo() doesn't have anything to do with Object A then why is the method in there?
Static methods should still be relevant. If there isn't anything going on then why have you written a method that has no association with it?
If foo is private, it may be anything, static or not. But, most of the time it will be not static as these is one less word to type. Then, if you need to use the state because you've changed your code, you can do it right away.
When it is protected or public, it depends on what it does. A rule of thumb is to make it not static when it isn't a part of the instance's behaviour, and make it static when it makes sense to call it without any object.
If you are unsure, ask yourself if it makes sense to override the method in a subclass.
I think letting the methods in Java to be static will result in a rather chaotic implementation by beginner who haven't understand OO correctly. We've been there and think about it. If the methods were static as default how hard it is for us to understand the OO principle?
So yes, once you mastered the concept, it is a bit itchy to have static all over the methods (as result of refactoring). Nothing we ca do about that I think.
NB: Let me guess, are you by any chance have read Clean Code?
Plenty of interesting answers.
If you desperately seek a rule, then use this:
If the code is only ever used by instance methods of a single class, then make it an instance method - it is simply an extraction of code out of an instance context - which could be refactored back into (or out of) methods that access instance state.
If the code is used by MORE THAN ONE class, and contains no access to instance variables in the class in which the method resides, then make it static.
End of story.

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