Enum variable is found to be null when not set that way - java

Whenever I try to get a field from an enum, it always returns null.
I've set the value of it according to the enum constructor. It still comes out null.
public enum TeamType {
RED("Red",ChatColor.RED,DyeColor.RED,Point.RED),
BLUE("Blue",ChatColor.BLUE,DyeColor.BLUE,Point.BLUE); //<----Set as Point.RED/BLUE
private String name;
private int crystalHealth = 50;
private Point point;
private int teamPoints;
private ChatColor chatColor;
private DyeColor dye;
private HashSet<ArenaPlayer> playerList = new HashSet<>();
private List<ArenaPlayer> queue = new ArrayList<ArenaPlayer>();
private Location spawn;
public Point getPoint()
{
if(point == null)
System.out.println("WHY? for: " + this.toString()); //<---This always runs
return point;
}
private TeamType(String name,ChatColor color,DyeColor dye,Point point1) {
this.name = name;
this.point = point1; // <--- My assignment
this.dye = dye;
this.chatColor = color;
}
The Point enum class
public enum Point{
RED(ChatColor.RED + "Red",TeamType.RED),
BLUE(ChatColor.BLUE + "Blue",TeamType.BLUE),
NEUTRAL(ChatColor.WHITE +"None",null);
private String name;
private TeamType teamOwned;
private Point(String name,TeamType team) {
this.name = name;
teamOwned = team;
}
public TeamType getTeamOwned() {
return teamOwned;
}
public String getName() {
return name;
}
#Override
public String toString() {
return name;
}
There's obviously something that's happening outside of my knowledge of Java.
Could it possibly be that the Point Enum is not initialized yet when TeamType enum is. This could explain why it's null.
I need some help.

Well, I think the source of the problem is that you have a circular reference. TeamType has a Point reference and vice versa.
Suppose the TeamType enum class is initialized, then the enum constants are initialized as well. These refer to Point, which is in turn initialized. The classloader loads the Point class, but will not initialize TeamType again. At this point, properties you expect to be non-null are still null.
The JLS § 12.4 defines this process.

Suppose we have a class called A which has class B’s Object. (in UML terms A HAS B). at the same time we class B is also composed of Object of class A (in UML terms B HAS A). obviously this represents circular dependency because while creating the object of A, the compiler must know the size of B... on the other hand while creating object of B, the compiler must know the size of A. this is something like egg vs. chicken problem...
to avoid such type of circular dependency you can use any proxy interface .
https://dzone.com/articles/tackling-circular-dependency

Related

Final attribute vs. a Private attribute with no Setter method in Java

In Java, I feel that using Private when declaring an attribute and not declaring a Setter method for it gives the same outcome as using Final when declaring the attribute, both allow the variable to stay constant.
If that is the case, what is the benefit of using Final in this scenario?
Even without a setter other methods in the class can change the attribute so it's a completely different concept.
Many would argue it's not a good thing to do (it adds "side effects" to your program) but it's still possible.
Assumed you are talking about variables, the keywords final and private define different characteristics.
The keyword final denies any changes to the variable and throws compilation errors when modified or changed. However, without specifying public or private, with the default package-private access modifier, it could be accessed by other classes in the same package once initialized (text with bold fonts are corrected by #charsofire and #MC Emperor).
On the other hand, the keyword private rejects the idea of being called by other classes, even in the same package. But it could be changed and modified by methods in the same class, even without setter or getter methods.
For example in the same class of the same package:
public class Student {
private int score;
final int id;
public Student(int id, int score) {
this.id = id;
this.score = score;
}
public void modifyGrade(int newScore) {
// Accepted
this.score += newScore;
}
public void modifyID(int id) {
// Rejected
this.id = id;
}
}
And in different class of the same package:
public class School {
public static void main(String[] args) {
Student student = new Student(0, 35);
// Accepted
System.out.println(student.id);
// Rejected
System.out.println(student.score);
// Accepted
student.modifyGrade(29);
// throws exception
student.id = 5;
// Not visible
student.score = 29;
}
}
Hope this answer helps you well,
and many thanks again to both #charsofire and #MC Emperor, who helped to clarify significantly in this answer.
The answer is Encapsulation
Consider this.
public class Point
{
int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
//no getters or setters needed, I can just modify or read x and y directly.
}
public class FinalPoint
{
public final Point point;
public FinalPoint(int x, int y)
{
this.point = new Point(x, y);
}
//no getters needed, I'll just read point since it is public
}
Right now, this FinalPoint has a final Point as an instance field. On the one hand, it means that that instance field cannot be reassigned. However, the fields of that instance field can definitely be reassigned.
For example.
FinalPoint p = new FinalPoint(1, 2);
p.point.x = 4; //I have now modified state! final did not protect us here
The final keyword is powerful, but it does not mean that your data is unchangeable. It only means that that surface level reference is unchangeable - it will force a reference to always point to the same object. That does not stop the object its pointing to from changing it's internal state as much as it wants. The only guarantee final makes is that you always be pointing at the same object.
Which brings us to encapsulation. Encapsulation was created to solve this exact problem and more.
Consider this.
public class EncapsulatedPoint
{
private Point point;
public EncapsulatedPoint(int x, int y)
{
this.point = new Point(x, y);
}
public int getX() { return this.point.x; }
public int getY() { return this.point.y; }
}
Now, because I have encapsulated Point and exposed only the data I can safely expose, I have protected myself from modification. It is impossible to change this object (without using reflection or other hacks the designers are actively removing). It truly is Immutable.
Of course, Encapsulation is not superior to using final. There is a time and a place for both. Knowing when and where allows you to make your software secure.
Private variables will never access from the outside of the class and Final will never change by taking input from the user.

Cannot cast to... android

I created some classes with inheritance concept, I have the main class for my application, that is called modulo, which corresponds to an module, and also some other classes called moduloLedRGB, ModuloSwitch, and ModuloDimmer, these 3 classes all extends the class modulo which has just the common arguments for modules like, id, name, Module type, and ipAdress. But, when I try to cast a module to one of those 3 childs classes I get an exception that says I cannot cast Modulo to ModuloSitch or ModuloLedRGB...
This is where I get the error:
switch (modulo.getModulo()){
case "RGB":
ModuloLedRGB rgb = (ModuloLedRGB) modulo;
rgb.setProgress(c.getDouble(c.getColumnIndex("progress")));
rgb.setProgressRed(c.getDouble(c.getColumnIndex("progressRed")));
rgb.setProgressGreen(c.getDouble(c.getColumnIndex("progressGreen")));
rgb.setProgressBlue(c.getDouble(c.getColumnIndex("progressBlue")));
break;
case "Dimmer":
ModuloDimmer dimmer = (ModuloDimmer) modulo;
dimmer.setProgress(c.getDouble(c.getColumnIndex("progress")));
break;
case"Switch":
ModuloSwitch sw = (ModuloSwitch) modulo;
break;
It says I cannot cast modulo that is an object corresponds to the class Modulo, to ModuloRGB.
getModulo returns a string that says me which kind of Module this is.
package br.com.andrey.projetointegradoapp;
/**
* Created by andrey on 04/08/2016.
*/
public class Modulo {
private long id;
private String nome;
private String ModuleIpAdress;
private String modulo;
public String getModulo() {
return modulo;
}
public void setModulo(String modulo) {
this.modulo = modulo;
}
public String getModuleIpAdress() {
return ModuleIpAdress;
}
public void setModuleIpAdress(String moduleIpAdress) {
ModuleIpAdress = moduleIpAdress;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
This is the Modulo Class.
and this is ModuloLedRGB class:
package br.com.andrey.projetointegradoapp;
/**
* Created by andrey on 16/12/2016.
*/
public class ModuloLedRGB extends Modulo {
private double progress;
private double progressRed;
private double progressGreen;
private double progressBlue;
public double getProgressRed() {
return progressRed;
}
public void setProgressRed(double progressRed) {
this.progressRed = progressRed;
}
public double getProgress() {
return progress;
}
public void setProgress(double progress) {
this.progress = progress;
}
public double getProgressGreen() {
return progressGreen;
}
public void setProgressGreen(double progressGreen) {
this.progressGreen = progressGreen;
}
public double getProgressBlue() {
return progressBlue;
}
public void setProgressBlue(double progressBlue) {
this.progressBlue = progressBlue;
}
}
Any ideas for why am I getting this exception? since the child extends the main class I think I should be able to cast it down, not?
Based on the comments, it appears that you misunderstand the nature of casting.
When you say
class Modulo { ... }
class ModuloLedRGB extends Modulo { ... }
Subclassing defines an is-a relationship; every ModuloLedRGB is also a Modulo. But that doesn't work both ways.
If you create an object with
new Modulo()
then it is a Modulo, but not a ModuloLedRGB. If you create it with
new ModuloLedRGB()
it is both a ModuloLedRGB and a Modulo. Saying it's a Modulo means that you can assign a variable of type Modulo to it, or use it as a Modulo parameter:
ModuloLedRGB x = new ModuloLedRGB();
Modulo y = x; // this is legal, but the object's class doesn't change
y is a reference to the ModuloLedRGB object. But note that although y is declared as Modulo, it still refers to the same object, whose class is ModuloLedRGB, because that's the way the object is created.
That's why you can use downcasting. Say you later use the expression
(ModuloLedRGB)y
At this point, the compiler knows only that y (if not null) is a Modulo; it could be an object of class Modulo, ModuloLedRGB, ModuloSwitch, or anything else. So at run time, the code checks to see what kind of object it's actually referring to. Since the example above set y to an object created as a ModuloLedRGB, the cast is successful. But if y were set to some other object that wasn't a ModuloLedRGB, the cast throws an exception.
This cast doesn't change an object, and it doesn't create a new object. It just says "Make sure the object is of class ModuloLedRGB, and then treat it as a ModuloLedRGB so that we can access methods and instance variables that are particular to a ModuloLedRGB".
It looks, however, that you're trying to convert the object by changing its class. You've created an object whose class is Modulo, and you're trying to come up with some new object whose class is ModuloLedRGB. You can't do that with a cast. If you have a Modulo and you want to create a ModuloLedRGB, you will have to create a new object with new ModuloLedRGB(), somewhere. One common way to do this is to write a constructor:
class ModuloLedRGB extends Modulo {
public ModuloLedRGB(Modulo m, maybe other parameters) {
// copy the instance variables from "m"
this.field = m.field;
this.anotherField = m.anotherField;
// set the new instance variables
this.newField = maybe a parameter or some other computation;
...
}
or write a static factory method to create a new ModuloLedRGB from a Modulo. But you'll have to create it, and you'll have to write the code to create it. You can't "convert" it from a Modulo. There's no such thing in Java.

Assign each enum instance a growing ID

I'm just starting my first steps with Java, learned all the basics but then found a problem with an enum I need, so forgive me, if the solution to my problem is something very obvious:
So I've got this enum and want to add a unique id to each instance counting from 0 upwards, but without having to add another parameter to each constructor calling (because this can later on lead to errors ofc).
public enum TerrainTile{
WATER(1), GRASSLAND(1), HILL(2), FORREST(2), BLANK(99);
private final int id;
private final int moveCost;
private boolean hidden = true;
private TerrainTile(int moveCost) {
this.moveCost = moveCost;
}
And I thought to just add a
static int nextID = 0;
and edit the constructor to
private TerrainTile(int moveCost) {
this.id = nextID++;
this.moveCost = moveCost;
}
But I get an error message that it can not refer to a static field inside the initializer.
Is there any workaround?
You can use the ordinal() method for it. It is based on the order in which the members are declared in the source-code and counted from zero. So I guess, exactly what you need.
Just a note:
You can get your original enum member from ordinal number by calling .values()[index]
example:
int hillOrdinal = TerrainTile.HILL.ordinal(); // 2
TerrainTile hill = TerrainTile.values()[hillOrdinal];
It sounds like you are trying to combine class features into an enum. I'd be particularly wary of non-final, non-static member fields in an enum declaration. The behaviour you want seems to be best served by using a TerrainTile class (possibly a flyweight if you truly want the single-instance-per-type behaviour) and a TerrainTileType (or TerrainTile.Type) enum. Something like this:
public class TerrainTile {
public enum Type {
WATER(1), GRASSLAND(1), HILL(2), FORREST(2), BLANK(-1);
public final int MOVE_COST;
private TerrainTile(int moveCost) {
this.MOVE_COST = moveCost;
}
public boolean isTraversable() {
return (MOVE_COST > 0);
}
}
private final Type type;
private final Image texture;
...
private TerrainTile(Type type) {
this.type = type;
}
private static final Map<Type, TerrainTile> tiles = new EnumMap<>();
static {
// instantiate one TerrainTile for each type and store into the tiles Map
for (Type type: Type.values()) {
// Eventually, also load tile textures or set Color in this step
tiles.put(type, new TerrainTile(type));
}
}
public static TerrainTile getTile(Type type) {
// return the reference to the TerrainTile of this type
return tiles.get(type);
}
...
}

Is there any way to access this.toString()'s value when calling another constructor?

For everyone who is talking about the fact that the object is in an "unitialized state", please refer to the answer to this question which shows that an object reference can be passed around, dereferenced, have methods invoked from it, and have fields accessed before a constructor terminates and all fields have been assigned (including final fields).
So here's the use case:
public class Entity {
private final String name;
public Entity() {
this(toString()); //Nope, Chuck Testa
}
public Entity(String name) {
this.name = name;
}
}
The compiler error is:
Cannot refer to an instance method while explicitly invoking a constructor.
Note that toString() has not been overriden and is the default call from Object.
I'm certainly interested in the philosophical/technical reasons behind this, so if anyone can explain that, that would be an awesome bonus. But I'm looking for a way to call toString() from that default constructor as it refers down to the more specific one with more arguments. The actual use case is a bit more complicated and ends up referring all the way down to a constructor with four arguments, but that shouldn't really matter.
I know I could do something like this...
private static final String TO_STRING_CONSTRUCTOR_ARGUMENT = "aflhsdlkfjlkswf";
public Entity() {
this(TO_STRING_CONSTRUCTOR_ARGUMENT);
}
public Entity(String name) {
this.name = name == TO_STRING_CONSTRUCTOR_ARGUMENT ? toString() : name;
}
... but it seems like a pretty inelegant solution.
So, any way to pull it off? Or any recommended best practices to deal with this situation?
I would prefer not to pass this around until the object is created. Instead I would do this:
public class Entity {
private final String name;
public Entity() {
this(null); // or whatever
}
public Entity(String name) {
this.name = name;
}
public String getName() {
return name != null ? name : Objects.hashCode(this);
}
}
If you can live without the final name, you can use an initializer block:
public class Entity {
private String name;
{name = this.toString();}
public Entity() {
}
public Entity(String name) {
this.name = name;
}
}
this is only available after all calls to this() or super() are done. The initializer runs first after the constructors call to super() and is allowed to access this.
As for the reasons why that is a compiler error, please see section 8.8.7 of the JLS. The reasons why this was made a compiler error are not clear, but consider that the constructor chain has to be the first thing executed when new'ing an Object and look at the order of evaluation here:
public Entity() {
this(toString());
}
toString() is evaluated first before the even the super constructor is invoked. In general this leaves open all kinds of possibilities for uninitialized state.
As a personal preference, I would suggest that everything an object needs to have in order to create valid state should be available within its constructor. If you have no way of providing valid state in a default constructor without invoking other methods defined in the object hierarchy, then get rid of the default constructor and put the onus on the users of your class to supply a valid String to your other constructor.
If you are ultimately just trying invoke the other constructor with the value of toString(), then I would suggest the following instead:
public Entity() {
name = toString();
}
which accomplishes the same goal you set out to achieve and properly initializes name.
As explained in the JLS this is not allowed before the instance is initialized.
However, there are ways to handle your scenario in a consistent manner.
As I see your case, you want to signify either a generated value (toString()) or a user provided value, which can be null.
Given this constraints, using TO_STRING_CONSTRUCTOR_ARGUMENT is failing for at least one specific use case, however obscure it may be.
Essentially you will need to replace the String with an Optional similar to what exists in Google Guava and will be included in Java 8, and seen in many other languages.
Having a StringOptional/StringHolder or whatever you choose, similar to this:
public class StringOptional {
private String value;
private boolean set = false;
public StringOptional() {}
public StringOptional(String value) {
this.value = value;
this.set = true;
}
public boolean isSet() { return set; }
public String getValue() { return value; }
}
Then you can call constructors with the knowledge of the inferred path.
public class Entity {
public Entity() {
this(New StringOptional());
}
public Entity(String s) {
this(new StringOptional(s));
}
private Entity(StringOptional optional) {
super(optional);
}
}
And store this for subsquent need:
if (optional.isSet() ? optional.getValue() : toString();
This is how I usually would handle a maybe-null scenario, hope it augments as an answer.
You cannot 'use' an instance that has not been created yet. By calling a second constructor you are postponing the creation, you cannot use it before the call or in the action of calling.
You can use a static method factory in your class Entity, and put the constructor private:
public class Entity {
private String name;
private Entity() {
}
public Entity(String name) {
this.name = name;
}
public static Entity createEntity() {
Entity result = new Entity();
result.name = result.toString();
return result;
}
}

Building a copy constructor in Java

How do I build a copy constructor that receive another point (x,y) and copy its values ?
I decide a signature: public Point1 (Point1 other) , but I don't know what to write in it...
The Point class looks like:
public class Point1
{
private int _x , _y;
public Point1 (Point1 other)
{
...
...
}
//other more constructors here...
}
I tried:
public Point1 (Point1 other)
{
_x = other._x ;
_y = other._y;
}
But I almost sure I can do it better..
thnx
Nope, your attempt of
public Point1(Point1 other)
{
_x = other._x ;
_y = other._y;
}
is absolutely fine... (I've corrected the parameter type.)
I'd be tempted to make _x and _y final, and make the class final, but that's because I like immutable types. Others definitely have different opinions :)
Cloning on an inheritance hierarchy is slightly trickier - each class in the hierarchy has to have a relevant constructor, pass whatever argument it's given to the superclass constructor, and then copy just its own fields. For example:
public class Point2 extends Point1
{
private int _z;
public Point2(Point2 other)
{
super(other);
this._z = other._z;
}
}
That's not too bad on the implementation side, but if you want to faithfully clone a Point2 you need to know it's a Point2 in order to call the right constructor.
Implementing Cloneable allows this to be done a bit more simply, but there are other things to consider around that... basically cloning objects isn't as simple as it might appear :) (I'm sure there's an entry in Effective Java for it. If you don't have a copy, buy one now.)
Although the question is quite old but here is an example of copy constructor
public class CopyConstructor {
private int id;
private String name;
public CopyConstructor(int id, String name) {
super();
this.id = id;
this.name = name;
}
public CopyConstructor(CopyConstructor copy) {
id = copy.id;
name = copy.name;
}
}
Copy constructor is much easier to implement and we don't need to
implement Clonable interface.
The clone method returns object which needs to cast , we don't need to cast copy
constructor.

Categories

Resources