Take these two Java classes:
class User {
final Inventory inventory;
User (Inventory inv) {
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
Is there any way without using reflection* to pull this off? I don't actually expect it is, but it can't hurt to ask.
Update: Since in bytecode construction has two steps (1. allocate object, 2. call constructor**) could this be (ab)used to do this, with handwritten bytecode or a custom compiler? I'm talking about performing step 1 for both objects first, then step 2 for both, using references from step 1. Of course something like that would be rather cumbersome, and this part of the question is academic.
(* Because reflection may give trouble with a security manager)
(** Says my limited knowledge)
This can only work cleanly if one of the objects is created by the other. For example you can change your User class to something like this (while keeping the Inventory class unchanged):
class User {
private final Inventory inventory;
User () {
inventory = new Inventory(this);
}
}
You need to be careful about accessing the User object in the Inventory constructor, however: it's not fully initialized yet. For example, its inventory field will still be null!
Ad Update: I've now verified that the bytecode-manipulation approach does not work. I've tried it using Jasmin and it always failed to load with a VerifyError.
Delving deeper into the issue, I foundĀ§ 4.10.2.4 Instance Initialization Methods and Newly Created Objects. This section explains how the JVM ensures that only initialized object instances get passed around.
You can do it if you don't need to inject one of the objects.
class User {
private final Inventory inventory;
User () {
inventory = new Inventory(this);
}
}
class User {
private final Inventory inventory;
User (/*whatever additional args are needed to construct the inventory*/) {
//populate user fields
inventory = new Inventory(this);
}
}
class Inventory {
private final User owner;
Inventory (User own) {
owner = own;
}
}
That's the best I can think of. Maybe there's a better pattern.
Slightly pedantic, but it's not strictly speaking necessary to create one inside the other, if you don't mind a little indirection. They could both be inner classes.
public class BadlyNamedClass {
private final User owner;
private final Inventory inventory;
public BadlyNamedClass() {
this.owner = new User() {
... has access to BadlyNamedClass.this.inventory;
};
this.inventory = new Inventory() {
... has access to BadlyNamedClass.this.owner;
};
}
...
}
Or even:
public class BadlyNamedClass {
private final User owner;
private final Inventory inventory;
public BadlyNamedClass() {
this.owner = new User(this);
this.inventory = new Inventory(this);
}
public User getOwner() { return owner; }
public Inventory getInventory() { return inventory; }
...
}
This is one "solution", though the loss of one final is inconvenient.
class User {
Inventory inventory;
User () { }
// make sure this setter is only callable from where it should be,
// and is called only once at construction time
setInventory(inv) {
if (inventory != null) throw new IllegalStateException();
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
If you are only interested in JVM bytecode and don't care about coding in Java specifically, perhaps using Scala or Clojure could help. You'll need some kind of letrec machinery.
B: "Inventory created by the User is our last hope".
Y: "No, there is another."
If you abstract the references to a third party, you can control the relationship therein.
For example.
public class User
{
private final String identifier; // uniquely identifies this User instance.
public User(final String myIdentifier)
{
identifier = myIdentifier;
InventoryReferencer.registerBlammoUser(identifier); // Register the user with the Inventory referencer.
}
public Inventory getInventory()
{
return InventoryReferencer.getInventoryForUser(identifier);
}
}
public interface Inventory // Bam!
{
... nothing special.
}
// Assuming that the Inventory only makes sence in the context of a User (i.e. User must own Inventory).
public class InventoryReferencer
{
private static final Map<String, Inventory> referenceMap = new HashMap<String, Inventory>();
private InventoryReferencer()
{
throw ... some exception - helps limit instantiation.
}
public static void registerBlammoUser(final String identifier)
{
InventoryBlammo blammo = new InventoryBlammo();
referenceMap.add(indentifier, blammo);
}
public static void registerKapowUser(final String identifier)
{
InventoryBlammo kapow = new InventoryKapow();
referenceMap.add(indentifier, kapow);
}
public static Inentory getInfentoryForUser(final String identifier)
{
return referenceMap.get(identifier);
}
}
// Maybe package access constructors.
public class InventoryBlammo implements Inventory
{
// a Blammo style inventory.
}
public class InventoryKapow implements Inventory
{
// a Kapow style inventory.
}
Related
I am working on a project where I am trying to represent a Stock Portfolio. There is a class called Position. Also, there is another class called Portfolio and it's basically represents a set of positions along with additional instance variables/methods.
A single Position is stored in a plain .txt file. In order to read that file, I've created another class: ReaderService. In this class, necessary I/O operations are being performed and in the end, a List<Position> is being returned by the method called readPositions().
Portfolio class depends on ReaderService in order to set its positions field, and I am injecting that dependency via constructor, that is constructor injection.
What I can't be sure about is that it seems like a bad practice to initialize a instance variable of Portfolio class in a setter method by using ReaderService dependency. Does this approach leads to any problems like tight coupling or smt else?
Here is the quick summary
ReaderService:
public class ReaderService {
// necessary fields..
// a method to extract all positions from the each line of .txt file.
public ArrayList<Position> readPositions(){
ArrayList<Position> positions = new ArrayList<>();
...
/* for each line in the file, a new `Position` is being created
and being added to `positions` after necessary file operations performed. */
...
// Initializing a new position and adding it to the list
Position position = new Position(...);
positions.add(position);
return positions;
}
}
Position class:
public class Position {
private String stockCode;
private double balance;
...
// There are more than two fields. Truncated it for the sake of the question.
public Position(String stockCode, double balance, ...) {
this.stockCode = stockCode;
this.balance = balance;
...
}
}
And the class in question; Portfolio class:
public class Portfolio {
private ArrayList<Position> positions;
...
private final DataService dataService;
private final ReaderService readerService;
public Portfolio(DataService dataService, ReaderService readerService){
this.dataService = dataService;
this.readerService = readerService;
}
public ArrayList<Position> getPositions() {
return positions;
}
// Check out this method. Is it a poor design?
public void setPositions() {
try {
this.positions = readerService.readPositions();
}
catch (IOException ex){
ex.printStackTrace();
}
}
}
Is it correct thing to question the following:
"A ReaderService is responsible to read the positions, but you are giving it the responsibility of creating list of positions for Portfolio class as well.'
I mean do I break the Single Responsibility principle here?
I am also considering to make these service classes static.
For the sake of readability, I answer here.
Rather than setPositions(), I would like to create with constructor. And create another class (or you can put it in main class as you said, but you may don't like it) as below.
public class PortfolioService {
private final DataService dataService;
private final ReaderService readerService;
public PortfolioService(DataService dataService, ReaderService readerService) {
this.dataService = dataService;
this.readerService = readerService;
}
public PortfolioService createPortfolio() {
return new Portfolio(readerService.readPositions());
}
}
then, Portfolio class will look like this.
public class Portfolio {
private final List<Position> positions;
public Portfolio(List<Position> positions) {
this.positions = positions;
}
// and do something else with positions
}
so I am trying to make a Minecraft plugin that listens to the configuration file for input of which mobs to not target players. Here is what I have so far
public class ZombieListener implements Listener {
private final List<String> entities;
public ZombieListener(List<String> entities){
this.entities = entities;
}
#EventHandler
public void onEntityTargetEvent(EntityTargetLivingEntityEvent event) {
if (event.getTarget() event.getTarget() instanceof Player ) {
final Player targeted = (Player) event.getTarget();
if (targeted.hasPermission("dont.target.me") && entities.contains(targeted)){
event.setCancelled(true);
}
}
}
}
I realise that I can't check for an entity from an object and therefore I need to make targeted a List. How should I do this?
The other answer is way more complex than it needs to be. Try to do this instead:
public class ZombieListener implements Listener {
private final List<String> entities;
public ZombieListener(List<String> entities){
this.entities = entities;
}
#EventHandler
public void onEntityTargetEvent(EntityTargetLivingEntityEvent event) {
if (event.getTarget() instanceof Player && entities.contains(event.getEntityType().getName())) {
final Player targeted = (Player) event.getTarget();
if (targeted.hasPermission("dont.target.me") && entities.contains(targeted)) {
event.setCancelled(true);
}
}
}
}
All I did was add a small bit of code in the first if-statement:
entities.contains(event.getEntityType().getName())
This makes it so the application checks if the entity is one of the affected types, and carries on with the listener accordingly.
Hope this helps!
Use the entity class instead.
For example I created a mod that caused animals to age over time, making them die (they also would breed on their own). In order to allow the config to determine how quickly animals aged, I used the animal class:
private Class species;
private Entity entity;
public EntityAIAging(Random random, EntityAnimal ent, Class spec, EntityAgeTracker ageTracker) {
species = spec;
entity = ent;
//...
}
public void updateTask() {
// Both of these function the same:
// Unaging animals do not age, do not die, and do not procreate
if(HardLibAPI.animalManager.isUnaging(species)) {
return;
}
if(HardLibAPI.animalManager.isUnaging(entity.getClass())) {
return;
}
//...
}
So what you'd want to do is call entity.getClass() and check if it exists within a List<Class> entities. If you want to see how I parsed a config file to locate classes, you can see that code here. Its complicated and has some additional logic to handle minor misspellings.
I don't want to do the deep copy way.
Say, I have a field of some mutable type, a x,y,z Coordinate for example. Occasionally, I need to expose this field to some viewers. And I want it be read-only. I remember reading something like a wrapper to do these kind of stuff, but I don't remember the details.
The x,y,z Coordinate example may be too simple because x,y,z are primitive type. So getX() always return a copy.
I want a general solution even if the x,y,z fields are of yet another mutable type.
Can anybody help?
EDIT:
public class Client
{
public static final Holder holder = new Holder();
public static void main(String[] args)
{
UserWrapper user = holder.getUser();
System.out.println(user); //UserWrapper{user=User{address=Address{street='street 101'}}}
user.getAddress().setStreet("mars"); //UserWrapper{user=User{address=Address{street='mars'}}}
System.out.println(user);
}
}
public class Holder
{
private User user;
public Holder()
{
user = new User();
Address address = new Address();
address.setStreet("street 101");
user.setAddress(address);
}
public UserWrapper getUser()
{
return new UserWrapper(user);
}
}
public class User
{
private Address address;
public Address getAddress()
{
return address;
}
public void setAddress(Address address)
{
this.address = address;
}
}
public class UserWrapper
{
private User user;
public UserWrapper(User user)
{
this.user = user;
}
public Address getAddress()
{
return user.getAddress();
}
}
EDIT:
credit to I don't know who(he deletes the answer), I find this link he mentioned in his original post very helpful.
The traditional ways:
deep copy - prevents mutations from impacting the client who is reading
immutable objects - instead of copying for the client, you copy to update and the client gets an old pointer reference.
customer iterator - you provide your own iterator / navigation interface, which is sensitive to a "version" field embedded with the data structure. Before visiting each element, it checks that the version has not been changed since the iterator was created (java collections does this).
strong synchronization - while a reader is reading, the reader holds a lock on the data structure preventing update. Generally a bad solution, but occasionally useful (included for completeness).
lazy copy - you construct an object that mostly references the original, but is triggered (as a listener) to the original, such that when a mutation is done on the original, you copy the pre-mutated value locally.
This is like a lazy deep copy strategy.
There's others, but this should get you started.
There is no built-in mechanism in Java that will enable you to do that. Usually, if you move instances around, you'd either:
Use immutable objects
Pass on copies of the objects
Since you don't want/can't choose either of these ways, you'll need to use an alternative. There are a lot of different ways to implement this depending on your requirements and how complex is your class structure, but the general approach would be to publish an immutable wrapper instead of the original.
Here are some examples:
public class XYZ {
public int x, y, z;
}
public class XYZWrapper {
private XYZ xyz;
public XYZWrapper(XYZ xyz) {
this.xyz = xyz;
}
public int getX() { return x; }
public int getY() { return y; }
public int getZ() { return z; }
}
public class Address {
public String name;
public XYZ xyz;
}
public class AddressWrapper {
private String name; // Note that this could be public since any String is immutable
private XYZWrapper xyzWrapper;
public AddressWrapper(String name, XYZ xyz) {
this.name = name;
this.xyzWrapper = new XYZWrapper(xyz);
}
public String getName() {
return name;
}
public XYZWrapper getXYZWrapper() {
return xyzWrapper;
}
}
Now, if instead of XYZ and Address classes, you work with interfaces, you can have 2 implementations (e.g. XYZMutable & XYZImmutable) which will allow you to abstract which type of class you're returning, and also will enable you to create an instance of XYZImmutable from an instance of XYZMutable (assuming that the interface defines only & all getter methods).
One more note about this approach (especially if you do it the preferred way by using interfaces): Even if you have a complex class hierarchy, you can do this relatively effortlessly by creating a generator class that receives an interface instance, a mutable implementation instance and returns an immutable implementation instance as the return value.
Perhaps you're thinking of the "copy on write" idiom. This allows you to avoid copying unless you have to. It's use is generally not recommended because it is not thread-safe unless you use synchronization which will unnecessarily slow down single-threaded applications.
It works by keeping a reference count of its internal data; something like this untested bit of code:
public class User
{
private int addressReferenceCount;
private Address address;
public User(Address address) {
addressReferenceCount = 0;
this.address = address;
}
public Address getAddress() {
addressReferenceCount++;
return address;
}
public void setAddress(Address address)
{
if (addressReferenceCount == 0) {
this.address = address;
}
else {
this.address = new Address(address);
addressReferenceCount = 0;
}
}
}
This ensures that user code like this will get different addresses when necessary:
User u = new User(new Address("1 Acacia Avenue"));
Address oldAddress = u.getAddress();
Address stillOldAddress = u.getAddress();
u.setAddress(new Address("2 Acacia Avenue"));
Address newAddress = u.getAddress();
assert (oldAddress == stillOldAddress); // both refer to same object
assert (oldAddress != newAddress);
I am creating a dump Java app for student information system for learning and implementing OOPS Concepts like inheritance, abstraction, polymorphism and encapsulation.
What I am doing is, I have created Faculty Class, Student Class and a College Class. Now i want to add new faculty in College. So my approach is to create a method in College class i.e. addFaculty(Faculty f) and fireFaculty(Faculty f), now i want to add Faculties in College class.
Whats the best way to do it? How do i store list of Faculty Object in College Object. Because i can add more than one faculty and more than one student in college.
Whats the best approach to solve this problem in OOPS?
Here is College.java code which i have implemented, it works fine but is this the best way i can solve it?
public class College
{
String name;
String location;
String courses[];
HashMap<String,Faculty> faculties;
int noOfFaculties = 0;
int noOfStudents = 0;
public College(String name,String location,String courses[])
{
this.name = name;
this.location = location;
this.courses = courses;
faculties = new HashMap<>();
}
public void addFaculty(Faculty faculty)
{
faculties.put(faculty.getName(),faculty);
}
public void printFaculties()
{
Set<String> set = faculties.keySet();
if(set.size()>0)
{
for(String s:set)
{
System.out.println(faculties.get(s).getName());
}
}
else
{
System.out.println("No Faculties Currently Working");
}
}
public void fireFaculty(Faculty faculty)
{
faculties.remove(faculty.getName());
}
public String getName()
{
return name;
}
public String getLocation()
{
return location;
}
public String[] getCourses()
{
return courses;
}
}
If you cannot have duplicates use HashSet<Faculty> if you dont mind use a List<Faculty>.
Example:
class College {
private List<Faculty> listFactories = new ArrayList<>(); // dupes allowed
private Set<Faculty> setFactories = new HashSet<>(); // no dupes allowed
}
Check collections API.
There's a ton of ways you can do it. Probably the easiest way to handle storing a collection of objects is by using one of the Collections provided by Java. For beginners, probably the easiest one to understand is an ArrayList, which is basically an array that grows in size dynamically depending on the amount of objects in the collection.
So, as an axample, your code might be something like this:
public class College
{
private ArrayList<Faculty> faculty;
public College()
{
faculty = new ArrayList<Faculty>();
}
public void addFaculty(Faculty f)
{
faculty.add(f);
}
public void fireFaculty(Faculty f)
{
faculty.remove(f);
}
}
imho It depends what kind of services College college offers. If I were coding, I would start with:-
List<Faculy> faculties = new ArrayList<>();
....
public void addFaculty(Faculty f) {
faculties.add(f);
}
//... etc
And change to an altearnative later if needed.
For now, I have a class with fields.
#Entity
public class Fuel {
#Id #GeneratedValue
private Long id;
private boolean diesel;
private boolean gasoline;
private boolean etanhol;
private boolean cng;
private boolean electric;
public Fuel() {
// this form used by Hibernate
}
public List<String> getDeclaredFields() {
List<String> fieldList = new ArrayList<String>();
for(Field field : Fuel.class.getDeclaredFields()){
if(!field.getName().contains("_") && !field.getName().equals("id") && !field.getName().equals("serialVersionUID") ) {
fieldList.add(field.getName());
}
Collections.sort(fieldList);
}
return fieldList;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isDiesel() {
return diesel;
}
public void setDiesel(boolean diesel) {
this.diesel = diesel;
}
public boolean isGasoline() {
return gasoline;
}
public void setGasoline(boolean gasoline) {
this.gasoline = gasoline;
}
public boolean isEtanhol() {
return etanhol;
}
public void setEtanhol(boolean etanhol) {
this.etanhol = etanhol;
}
public boolean isCng() {
return cng;
}
public void setCng(boolean cng) {
this.cng = cng;
}
public boolean isElectric() {
return electric;
}
public void setElectric(boolean electric) {
this.electric = electric;
}
}
I think it makes sense, but when I asked another question (maybe a stupid example since there can only be either automatic or manual gearbox) https://stackoverflow.com/questions/11747644/selectonemenu-from-declared-fields-list-in-pojo , a user recommend me to use enums instead. Like this way:
public enum Fuel {
DIESEL("diesel"),
GASOLINE("gasoline"),
ETANHOL("etanhol"),
CNG("cng"),
ELECTRIC("electric");
private String label;
private Fuel(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
}
However, since there exists hybrids on the market (like Toyota Prius) the parent class would implement the boolean class at this way:
private Fuel fuel = new Fuel();
and if using enumerated list at this way:
private List<Fuel> fuelList = new ArrayList<Fuel>();
What is the best practice? Keep in mind that I might have 100 different fuels (just for example =). Do not forget that it is an entity and hence persisted in a database.
Thanks in advance =)
It sounds to me like you want an EnumSet, yes, definitely over a bunch of bool's.
This reminds me a lot of the design patterns for flags and I recently posted an SO question on exactly that: Proper design pattern for passing flags to an object
This supports having 100 different fuel types easily. However it doesn't support a car using 100 different fuel types simultaneously easily. But that to me sounds perfectly fine - it would be very hard to build such a car and this is perfectly reflected in the programmatic complexity of coding this :) (Unless of course it really was just supporting all corn-based fuels - in which you might prefer a polymorphic pattern.)
You should definetly use enums.
Image you want to get the fuel-type of an object.
If you would use bools you would end up with something like this:
if (myClass.IsGasoline())
else if (myClass.IsOtherFuel())
else if
...
If you use enums you can simply do something like:
Fuel fuel = myClass.GetFuelType()
(This is just pseudo-code ;))
If the number of hybrids is low, and I guess it will be better to use Enums, and include hybrids as a different case.
Otherwise you will have to manage the logic in a way that can be cumbersome, as when you set a certain Fuel to true you, most likely, will have also to set to false the current one set to true. I am saying this as you have setters for your fuel categories and you don't only define at construction.
EDIT: the way on how to ask for the type of fuel you are using would also be an argument in favor of enums.