I am working on Java for some time. I saw there are too many talks about decoupling the objects. I see they say "new" keyword is considered as symbol of high coupling. I did not get any answer till now why it is. can anyone explain me?
Well new creates an instance of a specific class. So whenever you use new you are creating coupling between the class being created and the code that creates it. Example:
List<String> strings = new ArrayList<>();
creates an instance of ArrayList, which is a problem if you don't need to hard-wire the code to use that specific implementation of the List API.
Note that Java new doesn't allow you to make the class name a parameter. Not even with generic type parameters.
The alternative is to use a factory function or object, or use dependency injection to decouple the code that needs the instance of a class from the procedure that creates it. (Or pass around Class objects as parameters and use reflection to create instances.)
Related
Recently, when I was reading the book named "Design Pattern-Elements of Reusable Object-Oriented Software", there was such a paragraph in the book:
Using templates to avoid subclassing. As we've mentioned, another potential
problem with factory methods is that they might force you to subclass just
to create the appropriate Product objects. Another way to get around this in
C++ is to provide a template subclass of Creator that's parameterized by the
Product class.
what I want to know is: In Java, How to implement the functions similar to using the template parameter to avoid creating Creator subclasses in C++?
I have tried to use generics, but I don't know how to use it.
public class ConcreteCreator<T extends Product> extends Creator{
#Override
public Product createProduct() {
// ... how can I return new T();
}
}
// ... how can I return new T();
Simple answer: you can't that easily in Java.
Java isn't C++, and generics are in many ways less powerful than C++ templates.
The point is: there is no way to "generically" create new objects of some unknown arbitrary class. You might be able to work around that by using reflection, and Class.forName() and newInstance(), but that comes at the usual cost of reflection: it is clumsy and errorprone.
Sure, you can return a specific subclass type (and instance there), but then you have to write a specific method for each such type.
In java, there is already a generic type for factory methods. It's Supplier<T>.
You should probably use Supplier<Product> instead of your Creator.
Then, you typically use a lambda function or method reference to supply an instance.
If you want to call setCreator(Supplier<Product>), for example, and you want it to create your MyProduct subclass, then you just call setCreator(MyProduct::new).
Lambdas allow you to do more complex constructions without subclassing, even when an appropriate constructor doesn't exist, like setCreator(() -> new MyProduct(CONST_VAL_1, UtilityClass.getCurrentValue2());
You can not instantiate T. It is a placeholder which will be erased on run time. Instead of returning the Product you want to return the concrete type of Product.
Whenever we call a constructor in Java, it creates a new object and returns its reference in the end (of newly created object).
Is there any possibility that a Java constructor does not create a new object but return the reference to an already created object?
// Is it possible that myObject is not a new object, its already existing object
MyClass myObject = new MyClass();
I have a list of objects of some class, and based on few parameters in constructor sometimes it more efficient that I don't create a new object, instead I pick up an already existing object. Is there is any other way?
No. Constructors by definition run when a new object is created to initialize it. If the constructor is run, a new object has already come into existence, and there's nothing you can do about it.
What you could do is make a static method which either creates a new object, or returns an existing one. This is the standard approach in such cases.
Say, Boolean.valueOf(boolean value) in the standard library exists for the purpose of avoiding creation of extra objects. You can create them using new Boolean(value), but it is much better to call this method because it will return the same object for the same values.
you cannot do this using constructors but you could use one of the patterns mentioned below.
If you only ever need 1 object then use the Singleton pattern.
If your might have a few variations then use Flyweight pattern as duffymo mentioned.
As duffymo mentions in his comment below - if you using any of these patterns then its important from a concurrency perspective to understand that these objects will be global state - you should therefore ensure they are immutable, and if you cannot make them immutable then you may want to rethink your approach.
No, this is not possible.
JLS section 15.9:
Unqualified class instance creation expressions begin with the keyword new.
An unqualified class instance creation expression may be used to create an instance of a class, regardless of whether the class is a top level (§7.6), member (§8.5, §9.5), local (§14.3), or anonymous class (§15.9.5).
and JLS section 12.5:
A new class instance is explicitly created when evaluation of a class instance creation expression (§15.9) causes a class to be instantiated.
...
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure: [...]
Notice that this clearly mentions creation of objects and not a possibe re-utilization.
On the other hand, you could create a static factory for your object that uses a pool. You could take a look at the implementation of Integer.valueOf(i) for example. Refer to this answer for example.
You cannot achieve this with just a constructor in Java.
If required, such a behaviour is achieved by using either static method inside the class (like Integer.valueOf(0)) or the whole dedicated object of the different class (like DocumentBuilderFactory) to return the instances. This provides enough control to substitute the existing object instead of always creating a new one.
As a rule, such objects should be immutable and thread safe to be easily shareable. Also, instance reuse and sometimes caching is implemented along these lines.
No. Class provides the blueprint for objects, when using the new operator it is followed by a call to a constructor, which initializes new object.
Source.
If you wish to reuse objects for any reasons you may want considering implement the Flyweight pattern as well as the Factory pattern into your project for best result.
No it's not possible. Create a static method to create objects based on required logic and don't forget to make constructor private.
If both classes are at same level (Both are child class), how to use instance of one class into another one.What is best way to use instance of one class into another class without passing into constructor? so manually require to pass null. How to make independent code?
Class PreviewPanel{
private PreviewPanel(Builder builder) {
this.previewMode=builder.previewMode;
formsPreview=new NTFormsPreview(previewMode);
formsPreview.setCanAddComment(builder.canAddComment);
ntPreviewTreePanel=new NTPreviewTreePanel(builder,formsPreview);
//This class have some event bus implemented.Sometime There, formsPreview instance is require.
}
public static class Builder {
private PreviewMode previewMode;
private Document document;
public Builder(PreviewMode previewMode,Document document) {
this.previewMode = previewMode;
this.document=document;
}
public PreviewPanel build() {
return new PreviewPanel(this);
}
}
}
If I pass that instance into constructor,I have to follow chain of inner class and pass same instance to reach specific class. I want to avoid it. This is big product. it is not easy to show how many classes inside it to reach actual handler implementation.
Code Structure:
private PreviewPanel(Builder builder)
->formsPreview=new NTFormsPreview(previewMode);
->NTPreviewTreePanel(builder,formsPreview);
->NTPreviewTree(document, bidDocuments, previewMode, canAddComment,canViewComment, previewFormTxnEncryptionDetails,formsPreview);
->NTTreeNode(formsPreview)
private void fireReportItemClicked(Document document,esenderCSReport){
eventBus.fireEventFromSource(formPreviewEvent, formsPreview);
}
is there any way to use instance of one class into another class without passing instance into constructor?
There are other ways.
Pass the instance of the second class to the first class using a setter method.
Pass the instance of the second class to the first class by assigning to a instance variable in the first class.
Create the instance of the second class in the first class.
If you an answer that is more relevant to your example, you will need to explain more clearly what you are trying to do here, and why you think that your current solution is unsatisfactory.
Re this attempted explanation:
I have to follow chain of inner class and pass same instance to reach specific class. I want to avoid it.
I have no idea what you are trying to say. I suspect that other readers has the same problem.
I suspect that the real problem here is with the design of your existing code. It looks like you / someone has gone a bit crazy with nesting classes, and that you are suffering the consequences. It could be that the only way to simplify things is to unpick the nesting or rethink the constructors. (Why does a private constructor require a "builder" argument?)
It is a fairly common phenomenon for complicated OO software to have inherently complicated initialization patterns. There tends to be no neat way to deal with this programatically, but you can often avoid this by using some kind of "Dependency Injection" (DI) mechanism. Another name for this is "Inversion of Control" (IoC).
For example, Spring DI works by adding annotations to your class, and getting Spring to create and assemble the instances in the required form. Or you can specify how the instances (beans) are assembled in XML.
This could be a solution for you ...
Your problem is unclear to me but I think you could do the following :
Create a new Class that will "Own both of your child class - composition"
Make it work a Mediator Pattern so that one can use and call stuff on the other one following the rule/logic you want.
No need to pass one of the child to the other one in any way.
Freely, redesign the interaction logic if it gets to change
No need to "change"" the structure you already have
FYI The builder, seems to be related to the Builder Pattern, you might wanna read on it and see if you can understand something out of your project.
This may sound like a silly question, however i am trying to test my game under different circumstances using reflection. I was wondering if their was anyway to dynamically create an object to contain certain methods, i know i can use proxies, but then i am limited to the methods declared in the interfaces i choose to use in the proxy so i have to create a new interface for each thing i want to add to my object that i am creating. I am hoping to access each method using reflection. I know there are libraries that do this so i am sure that this is possible and i am hoping to not have to install libraries, as i will have to deal with a new api.
In languages like C, you can pass function references as parameters to another function or procedure. Is this what you are referring to? You want to pass a reference to a function to a method about which the method may not have advance knowledge?
You can't pass function references as a parameter in Java. It isn't allowed. But the workaround for this is exemplified by the abstract factory pattern. This pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.
Every other class in Java inherits from the Object class.
Is it possible to add a second, completely separate, class hierarchy in Java based around my own FastObject class?
My original goal in doing so was to create smaller, faster objects with less functionality specifically designed for certain algorithms. But let me be clear, I am not interested in whether or not this is a "good idea". I just want to know if it is possible; I have not been able to find a way to do so. Would it require a change to the JVM? New boot classpath functionality? Is the real solution to ignore Object and look at replacing java.lang.Class? Would using a direct Java compiler instead of a VM make my job any easier?
To be clear, I don't just want to edit the root Object class. That would require potentially re-writing the entire Java library. I don't want to replace the current hierarchy, I just want to create a separate one I can use in the same code.
No, this is not possible.
All created classes extend another class, either explicitly or implicitly. If you create a class and explicitly define which class it extends, then it extends that class. If not, then it implicitly extends Object. There is no way around this, just as there is no way to overload operators or anything of that sort. It is a fundamental design decision of the Java programming language.
All classes extend Object. The only things that don't are primitive types. The exception to this is Object itself, of course, which does not extend itself.
It may be possible for you to inject your own Object implementation by mucking with the boot classpath. However, I don't think there is any way to use a base object other than Object. You could try some byte code manipulation, but it is entirely possible that your modified class will be rejected by the class loader.