Java classes and constructors - java

I hope this won't sound like a stupid question.
I have a class A and a class B. Now the only thing B has is a String ID.
Now I can have multiple objects A that each can have 0 or more objects of type B.
These are contained in a HashMap(ID,someData) each class A has.
What I want to do is each time I add a new ID in class A to check whether there already
is a on object of Type B with the same ID in any of the other class A objects I have, and if not, create a new B object.
Hope this makes sense. If what I ask is wrong is some way, please be kind enough to explain
how is this a bad practice or conceptualy wrong.
Thanks a lot.
EDIT:To be more clear,in my case, it is not desireable to share the HashMap(ID,someData) for all my objects as for example let's say A is a Course class,Or Catalogue, or Bank etc. Each A class may share some students/clients but each A class may contain different class B objects.

It's not bad practice, it seems like you're implementing the Instance Manager Pattern.
Ability to look up one or more instances (via a key) of the managed object(s). If only one managed object, then a key is not necessary.

The thing you need to do this is to have a collection of all A objects so you can check them all. As you get more A objects this will become more inefficient. A diiferent was to structure this might be to use the ID as you collection.
Map<ID,/* class with A and someData *> map = ...
This allows you to ensure uniqueness of ID across all A.

To achieve your purpose, you can make the HashMap a static variable, instead of an instance variable. Therefore, it will be shared among all instance of Class A.

If I were you I would have created a B_Factory class. This class would be responsible for creating the B objects. A class objects would call B_Factory methods to add or delete a B object. Inside B_Factory, you could use a Map to store the instances of B objects.
There should be only one instance of B_Factory class, which will be injected in all A instances.

You should loop through all your A instances and use Hashmaps containsKey method to check that the new B value is already stored or not. If you only need to store all the B values to every A class only once, you can add a static modifier for your HashMap field.

Related

Are instances of Class immutable?

I was wondering whether Class instances are immutable. The declared methods names do not suggest that the instance state is changed when they are invoked, but I found no explicit guarantee on the javadoc.
Scenario: I need to store unique class names in a Set. Ideally, I would like to populate the set with Class instances to avoid unnecessary calls to Class.forName() when I need to access the classe via reflection. However, it preferable to use immutable objects as keys of sets. Hence I was wondering if I could use Class instances right away.
First, The generics part Class<?> really doesn't matter here. Sure, no raw types, so Class<?> is better than Class, but for your question, the wildcard doesn't matter.
So in essence, you are asking whether Class objects are immutable. And for all practical purposes, they are.
Class objects come into existence when a class loader loads a class, and they stay put unless the whole class loader is unloaded, and everything it loaded with it.
Which can't happen when such class objects are still used in a map somewhere.
On the other hand: Class.forName() shouldn't be too expensive for classes already loaded. And when things such as serialization come into play, people suggest to go with String instead of Class objects for example (see here).
One has to distinguish between the immutable identity of a class object, and the actual "code" belonging to the class. That code can be changed at runtime (by instrumentation, think hot swap of code). But the class name, and its each code, and equals() equality should not be affected by that. Because the "identity" stays the same.
Final note: as the interesting comments below lay out, there are certain ways to alter Class objects to a certain degree. But all of these activities are definitely "out of the norm". Therefore: theoretically, you might prefer Strings over Class objects, but practically, in "normal" applications, using Class should work fine, too.
As I don’t really agree with other answer I decided to write this one,
Classes are not immutable, but they are unique - only one instance of Class object can exist for one class.
BUT class it not defined by its name, as classes might be from different class loaders, and different class loaders might have classes with same names - but that will be different classes, you would get ClassCastException if you would pass some object between code handled by 2 different class loaders if that object type would exist in both of them (as separate one, not inherited).
Class instances can be still safely used in Set, as they use default implementation of hashset/equals so only same instances of Class will be considered equals.
But to decide if you should use String or Class you need to know how exactly your app is supposed to work, as like I said, multiple classes with same name can exist between different class loaders.
And by just storing class name you can’t be sure that Class.forName will return same instance as expected it might even load some other class with same name from current class loader instead of using expected one.

Is it possible for two classes to be data members of each other mutually?

Is it possible for a class A to be a field of another class B and at the same time, for class B to be a field of Class A?
I have a scenario where I have two classes: Match and Venue. I'm not sure whether to have the Venue as a data member of Match or the other way around or have each of them as a data member of the other, if Java permits that.
Yes it is possible, but I doubt it can be achieved during object construction time, which causes cyclic dependency.
First create classA and classB objects and assign the mutual reference by using setter of each objects.
Yes, Java actually supports cyclic dependencies between classes. So what you are asking is achievable but as the other answer pointed out it would cause some problems at construction time. I mean one constructor calling another might cause an overflow error. So instead you can do something like.
Match match = new Match();
Venue venue = new Venue();
match.setVenue(venue);
venue.setMatch(match);
In view of Garbage collection, If Match and Venue were to be referenced to each other and not by any other objects then they would be in a state of isolation ie Island of Isolation. They won't be eligible for garbage collection. I hope this helps.

Class design, case for static methods

I had a discussion about usage of static method, briefly the argument is should a class definition have a method as static or instance method in the following scenario. There is a class that defines an entity i.e, what its properties are and what operations are allowed on it.
class dummy{
String name;
String content;
String someRandomOpeation(){
....
}
static String createKey( String inputName, String inputContent ){
return inputName+inputContent;
}
}
The class definition also has a static method that takes in some arguments (say content and date, which defines an instance logically) and use it to construct a key (a string) and return the same. Now if an instance of the message is created it would have the content and date as fields. Is the argument that I can get a key given a name and content and not have to create an instance valid to have the static method. Or does the fact that a pair of name and content logically define an instance say that an instance to be created and get a key from that?
Having a method as static just because you do not wish to instantiate is NOT a valid argument. According to design we use static methods in helper/util classes which may or may not have any properties of its own. These classes basically help in performing some common action which many different classes can use. Also the functions are so modular that they only use the arguments passed to the function to derive the output.
The class mentioned by you will not work because you cannot make a static reference to a non static field constant in JAVA.
Moreover, the disadvantage of using static methods strictly associated with its class fields is that you can not override them.
Is the argument that I can get a key given a name and content and not
have to create an instance valid to have the static method.
No. In this case you almost do not need a class at all. You can always pass data members to class methods, but that does not mean that we do not need classes.
There is an additional argument - encapsulation. It is much clearer and niced to have an instance method getKey() with no arguments and hide the implementation details.
Or does the fact that a pair of name and content logically define an
instance say that an instance to be created and get a key from that?
Also no. The fact itself does not mean that you should create an instance.
The first question here is wether we need a class or not. Do we really have some meaningfull objects, instances of something (dummy)? For example, if I have a library, it obviously make sense to have a class Book, as I have lots of books around. Do you have such a situation? Is this key logically associated with an instance of whatever (dummy here), in a way that Author and ISBN are logically associated with a Book? Does instances of this concept (dummy) has some relationships with some other concepts? Like a Book can be rented.
If most of these answers is yes - than this method should be instance method with no arguments.
Or...
Do you maybe only need kind of a "service" that calculates a key from 2 strings? It this all you need? Are there some other similar "services" that you need, independent on instances. If these answers are mostly "yes", that you do not even need a class. Or you can have a class "Services", with no attributes and with this static method and arguments (and maybe additional methods).
There is also a mixed situation. You still need instances for some other purpose, but you also need a createKey method that is totally independent on any instance, and only provide some global service that is somehow related with the class logic. Then a static method can make sense.
I think your way of thinking is kind of function-oriented instead of object oriented. I think you need a "click" in your mind, which would help you understand the right purpose and the meaning of objects and classes.

create constant object in Java

I wonder, In Java How can we create a constant object (but not-reference nor immutable since immutability is a feature to all objects of a class) ?
First:
final MyClass c = new MyClass();
creates a constant reference to non-constant object hence I can do:
c.setData(100);
Second:
String class is a class that all its instances should be constant (a.k.a immutable object). I need to have a kind that I can create from a constant objects and non-constanct objects.
In Other words, How to grant the constant-ness to some objects of a class and remove it from other objects. (without the need to wrap this object inside any wrapper).
I suppose that you want something along the lines of the const keyword in C++, which makes an instance of an otherwise mutable class immutable. However, no direct equivalent for this exists in Java.
If you control the class, you could define an interface that only exposes the getters and use that interface whenever you need a "const" reference - this would not require any wrapping, but it would be rather cumbersome if you need to do this for a lot of classes.
The closest you could do is to extend the base class and override its setter methods so they throw java.lang.UnsupportedOperationException , that way you can create object from the base class or the immutable subclass...
And what about an Enumeration containing only one element ? I think that comes pretty close to what he needs

Java: How to create a collection of a specific parent type and not its subtypes?

I am learning Java for a test (tomorrow) and am wondering about a question that will probably never come up but has got me curious.
Is it possible to create a new collection class such as a list or something that can hold only a specific type and not its sub-types? Would I use generics to achieve this goal?
Not really, or at least not practically.
Subtypes should operate like sets in mathematical set theory. If B is a subset of A, any item in B is also an item in A.
In the same way, if B is a subtype of A, any item in B is also an item of A. Thus, any collection of A must be able to maintain items of B.
That being said, there may be convulted ways that B can override certain operations to explicitly break the ability to use it in a collection or to instantiate it.
I don't think generics will solve that problem.
If you create a custom collection class, you can check the class of the object on insert using reflection, and reject it if it's not of a particular exact type. Alternatively, if you have control over the class definition for the class contained in the collection, making it final will prevent subclasses from being created. (obviously this is a problem if you need subclasses for some other use)
The question is: why would you want that. If you have a list containing animals, why would you want to fill that list only with the "base animal", but prevent dogs or cats being added to the list. One of the basic concepts of OO is that you use an instance of a subclass everywhere where you need in instance of the base class (Wikipedia: Liskov substitution principle). If that does not apply in your situation, something might be wrong with your class hierarchy.
You could use "final" in the class definition of the contained class to disallow subtyping it. I don't immediately see how you can test for this or restrict your generics to require final classes. You can use reflection to test whether the class has the final modifier set, for instance when constructing the collection, and throw if it doesn't.
If the class itself is not final, you can check every single object added to the collection to ensure that its runtime class is exactly the class the collection wants and not a subclass of it.
see http://java.sun.com/docs/books/tutorial/reflect/ for info on reflection on Java.

Categories

Resources