I have an object that I instantiate - it's quite nifty as it also extends a superclass and does some stuff in the constructor - in fact all the vital parameters and method calls are handled in the constructor.
After this I never call the object again to do something - I don't pass it to any other objects either - after it's instantiated it does it stuff and all is good. Is this the wrong way to do it?
Yes, doing significant work in the constructor is usually a bad idea.
Could you do this through a static method instead? The static method could create an instance of the superclass and then do whatever it needs to. The only problem with this approach would be if the superclass called virtual methods during its constructor, but that's a code smell in itself...
It may be a smell from the superclass, not the subclass.
Why do you need to do that? Is there functionality in the superclass that is publicly accessible only through the constructor? If so then you probably do need to create an instance to access that functionality. But it may be better to hide that behaviour behind a normal method rather than a subclass constructor.
But that's still not as good as fixing the superclass.
There should a purpose for the object to exist. Constructor is only a tool for preparing the object so it can work as needed after creation. If you don't use the object, you don't need to create it either.
Creation of unnecessary objects consumes memory and also makes garbage collector do more work, so you should consider rewriting code (possibly with a static method as it has already been suggested).
Related
I have an abstract class called Policy, and two subclasses DepreciablePolicy and ExpirablePolicy
I have an array of Policy, policies[]
I want to check what subclass my object is in (if it's a Policy, DepreciablePolicy or ExpirablePolicy)
I did this by using this if statement.
if (this.policies[polNum] instanceof DepreciablePolicy){
For each type of subclass, there is a different method I have to run.
Only problem is that I'm only able to use the Policy methods, but not the subclass methods or constructors.
Is there a way I can do this?
This is inheritance done the wrong way. The whole point of polymorphism is that your code doesn't care which subclass an object is. Anything you need to do should be expressed through the Policy, which should really be an interface. Your code should interact with a Policy based on that interface, and the subclasses choose how to react.
That being said, you're probably looking for simple down-casting:
DepreciablePolicy d = (DepreciablePolicy) policy;
This is nothing better than a poor bandage on a bad design, though.
For each type of subclass, there is a different method I have to run.
Then you've misdesigned it. Define an abstract method in Policy, have all the derived classes implement it according to their own requirements. Then just call the method.
I am running findbugs on some code and it says the readObject(...) method must be private to be invoked for serialization/unserialization? Why? What is the problem if it is made public?
About readObject()/writeObject() being private, here's the deal: if your class Bar extends some class Foo; Foo also implements readObject()/writeObject() and Bar also implements readObject()/writeObject().
Now, when a Bar object is serialized or deserialized, JVM needs to call readObject()/writeObject() for both Foo and Bar automatically (i.e. without you needing to call these super class methods explicitly). However, if these methods are anything but private, it becomes method overriding, and JVM can no longer call the super class methods on the sub class object.
Hence they must be private!
In the modern Java implementations (at least JDK 6 through 10), the ObjectInputStream and ObjectOutputStream classes will only recognize readObject, readObjectNoData and writeObject methods if they are declared as private and NOT static.
(I couldn't find this stated explicitly in any of the documentation, but the restriction is clearly implemented in the code.)
So, irrespective of whether it is a good idea or not, FindBugs is correct in pointing out that a non-private readObject method is a bug. It won't be used.
The only reason I want to make this method public is to make it final so that inheriting objects cannot fiddle with it.
I don't think you should try to do that. Put a note in the class-level javadoc to say what you think that subclasses should and should not do. If someone chooses to implement a class ignoring that advice, it is their problem to deal with the consequences.
The problem with trying to force other people to implement subclasses in a particular way is that they may have a use-case that requires them to do things differently ... for reasons that you are not in a position to understand. It is a better idea to leave future developers with the freedom to do what they want, and let them take responsibility for the consequences.
I'm not sure why findbugs thinks it's a bug, but I can guess at two possible reasons. Making readObject public breaks encapsulation because the calling code has visibility into the internal structure of your class. Also, by making it public you force all derived classes to declare readObject as public. So unless the class is final, you're changing the contract for serialization.
I thought findbugs could provide rationale for most of its messages. Does it have anything to say about this?
There's no reason for you to call serialization methods such as readObject yourself, much less from another class. You should minimize the visibility of everything you can.
Edit: If you want subclasses to be able to change the behavior, make the method protected... that's acceptable.
In order for your method to be called by objectInputStream.readObject(), you must declare it private:
private void readObject(ObjectInputStream objectInputStream)
If you do not, your method will not be called (put a break point in there to prove this). Your code may appear to work but that is because the default serialization is being used.
You might be wanting to make this protected to allow for subclassing but this is not needed. The serialization process automatically calls the readObject of the base class prior to calling the readObject of the concrete class. This happens even if the concrete class does not make a call to:
objectInputStream.defaultReadObject();
...contrary to other posts I have read on the web. The same applies to the writeObject methods as well.
What is the advantage of having constructor simillar to the one mentioned below:-
class A{
public A(A a){}
public A(){}
}
If you mean the one with the parameter, there's no reason for having that at all, given that it completely ignores the parameter, and there's already another constructor with the same effect.
If you can give a more realistic example, we may be able to give more useful information...
A(A a){/*do something*/} Can be helpful as copy constructor.
As others have said, you have a copy constructor. There are a number of reasons why you may want a copy constructor. Some of those are:
You can provide an alternative to the clone method. (Which is implemented via the Clonable interface.)
Copy constructors are easily implemented.
You can use another constructor to build the copy (by extracting data from the original object and forwarding to a regular constructor).
Check out the link I added to this post for more information about copy constructors and why you would want to use them (if you need them).
There is no advantage unless you need to have a copy constructor. I would suggest using the clone() method if this object should be clonable rather than using a copy constructor semantic.
You're question is very unclear, but basically if you hava a class, that has a constructor, that takes an instance of the same class, then you have a copy constructor. i.e. a constructor that creates a new instance with the same internal values as the original.
Edit -- assuming of course that your constructor does something other than just create a new instance.
It could also be useful in a number of delegation-based design patterns such as decorator or proxy etc.
Providing a default constructor might still be considered good practice, especially in scenarios where dependency injection or serialization are considered.
I have few questions regarding Java constructors
Can a constructor be private? If yes then in which condition?
Is a constructor a method or not?
If a constructor does not return anything then why we are getting a new Object every time we call it?
What's the default access modifier of a constructor if we do not specify.
Edit
The answers for 1 & 3 are very clear. I'm still not sure about 2 & 4 since I'm getting different answers for them.
Can a constructor be private? If yes then in which condition?
Yes. There are no conditions. Of course, no one except the class itself can call it then.
This is actually a frequent pattern: Have a static getInstance() and keep the constructor private.
There can also be private constructors that the public constructors internally call.
Constructor is a method or not?
Hmm. I say "no". At the very least, it is a "very special kind of" method. In what context exactly? The terminology is less important than what you are trying to do.
If constructor does not return anything then why we are getting a new Object every time we call it.
The new operator returns something (the new instance).
Whats the default access modifier of a constructor.
Same as for methods. Package-private.
If you do not specify any constructor, the class gets a default constructor, which takes no arguments, does nothing except calling the parent constructor and is public.
Yes, in any case. However, if all constructors for a class are private, that means that the class cannot be directly instantiated. You will need to use something like the Factory Pattern to create instances of the object.
Yes, the constructor is a method.
A better way to think about it is that the new operator returns the object and in the process of creating the object, calls the constructor. Another way to think about it (although this is only a way to think about it, it isn't technically correct) is simply that the return type is implied by convention. A good place to read more about this is to read about new in the context of C++. The constructor's role is not to create the object but rather to initialize the memory contained within the object.
Default access for a constructor in Java is package private just like any other method. (One such source: http://www.javabeginner.com/learn-java/introduction-to-java-access-modifiers and from the horse's mouth: http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
Yes, constructors can be private. This is done when you want tighter or alternate control over instance creation such as with factory methods or with a pattern such as a Singleton.
It is a method but it is not called directly. It is a special type of method invoked on your behalf when you create a new object.
Constructors don't return anything, they create new objects.
The default is package private. So public to any class within the package but not visible to code outside of the package.
Thoughts on Tomcat performance and scalability: This is a highly variable situation based on your server hardware and types of requests and of course the quality, efficiency and memory footprint of the code serving each request.
Your lower bound on concurrent requests was 500. Consider that you probably want to create a thread for each request and given a 1MB stack per thread you're looking .5 GB just for thread stack space. And this is before heap memory and the performance overhead of allocating that many threads. I think that if need to handle that many requests at a time you might want to consider a more heavy duty server like JBoss.
A constructor can be declared private for any class.
A constructor is a special method that returns an instance of the class it belongs to, therefore you do not need to specify a constructors return type.
Package private is the right answer as pointed out below.
Yes -- factory instance singletons often use this pattern, to force users to init their class via static factory method.
Yes, it's a method
Because that is what a constructor does - it constructs. (it's assumed the result of construction will be returned)
same as methods
With regards to your Tomcat question, it depends on which version of Tomcat, which IO model it's using (e.g., NIO versus historical network IO modules), and your configuration. Single Tomcat's can process hundreds of requests at a time, although the concurrency is tune-able (each request will be handled by a distinct thread or thread from a pool).
The default access modifier of a constructor is CLASS ACCESS MODIFIER,
If a class is public , then access modifier of a constructor is public. If the class is default , then constructor is also default.
Constructor can be created as a private in any case.
Constructor is a special type of method which can be automatically called when we
are creating object for the corresponding class.
Constructor does not contain any return values. It just create new objects. Should not provide any return type for constructor.
The default access specifier of the constructor is public
Yes.
Yes.
because a constructor is called by new. What returns the object is the new, the constructor simply sets up the internal state.
Public.
I'm learning Java (and OOP) and although it might irrelevant for where I'm at right now, I was wondering if SO could share some common pitfalls or good design practices.
One important thing to remember is that static methods cannot be overridden by a subclass. References to a static method in your code essentially tie it to that implementation. When using instance methods, behavior can be varied based on the type of the instance. You can take advantage of polymorphism. Static methods are more suited to utilitarian types of operations where the behavior is set in stone. Things like base 64 encoding or calculating a checksum for instance.
I don't think any of the answers get to the heart of the OO reason of when to choose one or the other. Sure, use an instance method when you need to deal with instance members, but you could make all of your members public and then code a static method that takes in an instance of the class as an argument. Hello C.
You need to think about the messages the object you are designing responds to. Those will always be your instance methods. If you think about your objects this way, you'll almost never have static methods. Static members are ok in certain circumstances.
Notable exceptions that come to mind are the Factory Method and Singleton (use sparingly) patterns. Exercise caution when you are tempted to write a "helper" class, for from there, it is a slippery slope into procedural programming.
If the implementation of a method can be expressed completely in terms of the public interface (without downcasting) of your class, then it may be a good candidate for a static "utility" method. This allows you to maintain a minimal interface while still providing the convenience methods that clients of the code may use a lot. As Scott Meyers explains, this approach encourages encapsulation by minimizing the amount of code impacted by a change to the internal implementation of a class. Here's another interesting article by Herb Sutter picking apart std::basic_string deciding what methods should be members and what shouldn't.
In a language like Java or C++, I'll admit that the static methods make the code less elegant so there's still a tradeoff. In C#, extension methods can give you the best of both worlds.
If the operation will need to be overridden by a sub-class for some reason, then of course it must be an instance method in which case you'll need to think about all the factors that go into designing a class for inheritance.
My rule of thumb is: if the method performs anything related to a specific instance of a class, regardless of whether it needs to use class instance variables. If you can consider a situation where you might need to use a certain method without necessarily referring to an instance of the class, then the method should definitely be static (class). If this method also happens to need to make use of instance variables in certain cases, then it is probably best to create a separate instance method that calls the static method and passes the instance variables. Performance-wise I believe there is negligible difference (at least in .NET, though I would imagine it would be very similar for Java).
If you keep state ( a value ) of an object and the method is used to access, or modify the state then you should use an instance method.
Even if the method does not alter the state ( an utility function ) I would recommend you to use an instance method. Mostly because this way you can have a subclass that perform a different action.
For the rest you could use an static method.
:)
This thread looks relevant: Method can be made static, but should it? The difference's between C# and Java won't impact its relevance (I think).
Your default choice should be an instance method.
If it uses an instance variable it must be an instance method.
If not, it's up to you, but if you find yourself with a lot of static methods and/or static non-final variables, you probably want to extract all the static stuff into a new class instance. (A bunch of static methods and members is a singleton, but a really annoying one, having a real singleton object would be better--a regular object that there happens to be one of, the best!).
Basically, the rule of thumb is if it uses any data specific to the object, instance. So Math.max is static but BigInteger.bitCount() is instance. It obviously gets more complicated as your domain model does, and there are border-line cases, but the general idea is simple.
I would use an instance method by default. The advantage is that behavior can be overridden in a subclass or if you are coding against interfaces, an alternative implementation of the collaborator can be used. This is really useful for flexibility in testing code.
Static references are baked into your implementation and can't change. I find static useful for short utility methods. If the contents of your static method are very large, you may want to think about breaking responsibility into one or more separate objects and letting those collaborate with the client code as object instances.
IMHO, if you can make it a static method (without having to change it structure) then make it a static method. It is faster, and simpler.
If you know you will want to override the method, I suggest you write a unit test where you actually do this and so it is no longer appropriate to make it static. If that sounds like too much hard work, then don't make it an instance method.
Generally, You shouldn't add functionality as soon as you imagine a use one day (that way madness lies), you should only add functionality you know you actually need.
For a longer explanation...
http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It
http://c2.com/xp/YouArentGonnaNeedIt.html
the issue with static methods is that you are breaking one of the core Object Oriented principles as you are coupled to an implementation. You want to support the open close principle and have your class implement an interface that describes the dependency (in a behavioral abstract sense) and then have your classes depend on that innterface. Much easier to extend after that point going forward . ..
My static methods are always one of the following:
Private "helper" methods that evaluate a formula useful only to that class.
Factory methods (Foo.getInstance() etc.)
In a "utility" class that is final, has a private constructor and contains nothing other than public static methods (e.g. com.google.common.collect.Maps)
I will not make a method static just because it does not refer to any instance variables.