Enum backed by enum in Java [duplicate] - java

I'm developing a LALG compiler to my college course on Java 1.6. So I did a types class and grammar class.
EnumTypes
public enum EnumTypes {
A("OLA"),
B("MUNDO"),
C("HELLO"),
D("WORLD"),
/**
* The order below is reversed on purpose.
* Revert it and will you get a NULL list of types furder.
*/
I(EnumGrammar.THREE),
H(EnumGrammar.TWO),
F(EnumGrammar.ONE),
E(EnumGrammar.ZERO);
private String strValue;
private EnumGrammar enumGrammarValue;
private EnumTypes(String strValue) {
this.strValue = strValue;
}
private EnumTypes(EnumGrammar enumGrammarValue) {
this.enumGrammarValue = enumGrammarValue;
}
public String getStrValue() {
return strValue;
}
public EnumGrammar getEnumTiposValue() {
return enumGrammarValue;
}
}
EnumGrammar
public enum EnumGrammar {
ZERO(EnumTypes.A,EnumTypes.B,EnumTypes.F,EnumTypes.D),
ONE(EnumTypes.C),
TWO(EnumTypes.B,EnumTypes.H),
THREE(EnumTypes.D,EnumTypes.A,EnumTypes.C);
private EnumTypes[] values;
private EnumGrammar(EnumTypes ... values) {
this.values = values;
}
public EnumTypes[] getValues() {
return values;
}
}
When I call EnumTypes.E.getEnumTiposValue().getValues() where are supposed to be the EnumTypes.F value is NULL.
Main
public class Main {
public static void main(String[] args) {
//prints [A, B, null, D]
System.out.println(Arrays.toString(EnumTypes.E.getEnumTiposValue().getValues()));
}
}
There are a workaround or something like that?
Thanks!

Essentially, it is always a very risky thing to allow a reference to an object to get outside of the class before the class is fully constructed, that is before the constructor is finished. Enums are singletons. Here you have two classes whose constructors receive each other's instances in a circular dependency. Add to this that class loading is lazy, so the classes will be loaded and enum instances created as you go and it sounds quite reasonable that the ends result depends on the order in which the enums are initialized.
I can't quote the corresponding point from JLS right now (I'll look for it), but I believe that if you allow a reference to an object to "leave the class" from outside of the constructor (which happens here due to enums being singletons initialized by the JVM), the JVM is free to do something strange.
EDIT: these points from the JLS are of importance for the case:
17.5.2 - A read of a final field of an object within the thread that constructs that object is ordered with respect to the initialization of that field within the constructor by the usual happens-before rules. If the read occurs after the field is set in the constructor, it sees the value the final field is assigned, otherwise it sees the default value. Since enum values are internally treated like static final fields (see 16.5 below), if you reference one enum from inside the constructor of another enum whose constructor references the first one, at least one of these two objects will not yet have been fully initialized and so the reference may still be null at this point.
16.5 - The definite assignment/unassignment status of any construct within the class body of an enum constant is governed by the usual rules for classes
8.3.2 - rules for initialization of fields
12.4.1 - when initialization occurs

Here is what's happening, in order:
Your code calls EnumTypes.E.getEnumTiposValue(), triggering class loading of EnumTypes.
Static initialization of EnumTypes begins - its enum constants will be initialized in the order they're declared.
EnumTypes.A through EnumTypes.D are initialized.
EnumTypes.I begins initialization - its constructor call references EnumGrammar.THREE, triggering class loading of EnumGrammar.
Static initialization of EnumGrammar begins - its enum constants will be initialized in the order they're declared.
EnumGrammar.ZERO is initialized - its constructor call references EnumTypes.A, EnumTypes.B, EnumTypes.F, and EnumTypes.D. Out of those, EnumTypes.F has not yet been initialized. Therefore, the reference to it is null.
From there, static initialization of the two enum classes finishes, but it doesn't matter for EnumGrammar.ZERO - its values field has already been set.

For the workaround, suppose that you have EnumA and EnumB, I will just put EnumB's name in EnumA's constructor.
When you have to retrieve EnumB from EnumA, you can simply use EnumB.valueOf(EnumA.this.enumB)
For example, Question is the EnumB
public enum Question {
RICH_ENOUGH(R.string.question_rich_enough, Arrays.asList(Answer.RICH_ENOUGH_YES, Answer.RICH_ENOUGH_NO)),
ARE_YOU_SURE(R.string.question_are_you_sure, Arrays.asList(Answer.ARE_YOU_SURE_YES, Answer.ARE_YOU_SURE_NO)),
FOUND_A_NEW_JOB(R.string.question_found_new_job, Arrays.asList(Answer.FOUND_A_NEW_JOB_YES, Answer.FOUND_A_NEW_JOB_NO)),
// ...
and Answer is the EnumA
public enum Answer {
RICH_ENOUGH_YES(R.string.answer_yes, "ARE_YOU_SURE"),
RICH_ENOUGH_NO(R.string.answer_no, "THAT_SOMEBODY"),
ARE_YOU_SURE_YES(R.string.answer_yes, null),
ARE_YOU_SURE_NO(R.string.answer_no, "FOUND_A_NEW_JOB"),
FOUND_A_NEW_JOB_YES(R.string.answer_yes, "GO_FOR_NEW_JOB"),
// ...
private final int answerStringRes;
// Circular reference makes nulls
private final String nextQuestionName;
Answer(#StringRes int answerStringRes, String nexQuestionName) {
this.answerStringRes = answerStringRes;
this.nextQuestionName = nexQuestionName;
}
Whenever I need to get the next Question from an Answer
public Question getNextQuestion() {
if (nextQuestionName == null) {
return null;
}
return Question.valueOf(nextQuestionName);
}
This should be simple enough to be a workaround.
Example source: an open source Android app for fun I just written last night - Should I Resign?

Related

How to make a specific parameter unique in Java

How can I make sure that each instance of a class will have a unique value for a specific parameter?
For example:
public Foo(int value);
value should be different for each instance of Foo. Otherwise, it can throw an exception.
Do you want to assign that value, or do you just want to make sure you have some kind of id?
A minimal solution for an id would be to use a static field as counter:
public class Foo {
private static int counter = 1;
private int id;
public Foo() {
id = counter++;
}
}
To check for assigned values you might want to use some kind of FooFactory:
public class FooFactory {
private static Set<int> ids = new Set<int>();
public static Foo createFoo(int value) {
if (ids.contains(value)) {
throw new FooAlreadyExistsException();
}
ids.add(value);
return new Foo(value);
}
}
Or, as other comments suggest, you could do this in the Foo constructor:
public class Foo {
private static Set<int> ids = new Set<int>();
public Foo(int value) {
if (ids.contains(value)) {
throw new FooAlreadyExistsException();
}
ids.add(value);
}
}
Create a factory:
public Foo createFoo( int value ) {....}
In the factory code, you can maintain a set of "allocated" values. This allows you to optimize the code; for example if the values are consecutive, a BitSet might be better than Set<Integer>. Note that you must "deallocate" your instances of Foo somehow if you want to be able to reuse values.
If you just GC instances of Foo, the value will still be "in use" unless you notify the factory somehow.
Assuming all instances of Foo would be in memory, you can maintain a static Set in the Foo class that would hold the values that were already used. You can check against this Set any time a new instance is created.
Another alternative, assuming there is no functional meaning to this value, is to have some sequence (backed by either a DB or a file) that would increment any time a new instance is created, and the value of each new instance would be the current value of that sequence.
I think your unique value should not be a parameter (which is under control of an arbitrary caller) but a responsibility of Foo.
A simple solution would be to use a static field which is incremented each time an instance is created:
private static int instanceCounter;
// instance initializer
{
instanceCounter++;
}
As others have mentioned this smells of a problem in your design or your understanding of the requirements.
Please share the requirements, your intended design and the code you have created so far.
EDIT: 'Aaron Digulla' has a better suggestion, to create a factory which manages this aspect of the object lifecycle.
I'd propose having a static ArrayList inside of a class, containing a list of your objects. But this is bad design IMHO.

Usage of final in java

I was wondering what the difference is between
public final type attribute_name;
and
private type attribute_name;
public type getA_name() {
return attribute_name;
}
Basically I want to make an attribute read-only, so it can't change after it has been initialized.
Do I make it public final, or do I make it private, and only make it accesible through a get method (without a set method)?
When it's not final but private, the class itself is able to change the value.
A final field MUST be set before the constructor exits. Once set, the reference cannot be modified (the value cannot be reassigned). Emphasis on the cannot be reassigned. This means that while the reference cannot change, the value itself can change.
This is legal:
final List<Integer> list = new List<Integer>();
list.add(5); // the value of list changes, but the reference doesn't
This is not:
final List<Integer> list = new List<Integer>();
list = new List<Integer>(); // may seem sort of redundant but the compiler won't allow it nonetheless
A private variable with a only getter can be reassigned internally by the class that holds it (but it's not visible externally so it cannot be reassigned outside the class holding it). Also, outside the class the reference is inaccessible so the variable cannot be modified except by the class holding it.
A final variable cannot be reassigned anywhere, but if it's public, another class can still access the reference and change the value of whatever object it points to.
If you don't want the variable to be reassigned after initialization as you described, use both final and private.
Use final for something like this:
public class User {
private final long registrationTimeMillis;
public User(/* various parameters probably would be here */) {
registrationTimeMillis = System.currentTimeMillis();
}
public long getRegistrationTimeMillis() {
return registrationTimeMillis;
}
}
We don't expect that a user's registration time will change, so it makes sense to not allow it to change after construction.
Use private with no setter for something like this:
public class VendingController() {
private int drinksStocked = 0;
private int drinksDispensed = 0;
public void dispenseDrink() {
drinksDispensed++;
}
public void stockDrinks(int numberOfDrinks) {
drinksStocked = getDrinksRemaining() + numberOfDrinks;
drinksDispensed = 0;
}
public int getDrinksRemaining() {
return drinksStocked - drinksDispensed;
}
}
We don't want the value of drinksDispensed to change except when dispenseDrink() or stockDrinks(int numberOfDrinks) is called. It still needs to be able to be reassigned by it's own class when the vending machine is refilled though, so we shouldn't make it final
With respect to using public final, generally in Java that's only done for constants and that static keyword is also included since constants shouldn't be dependent on an instance.
An example of when it makes sense to use public static final
public class UnitConversions {
public static final double CENTIMETERS_PER_INCH = 2.54;
}
It could then be used in a method as follows
public double convertFromCentimetersToInches(double centimeters) {
return centimeters / UnitConversions.CENTIMETERS_PER_INCH;
}
Best of luck OP and happy coding.
More reading on final fields
This depends on some factors.
If this is a real constant that is known before and will never change, then use final. In Java final fields can be initialized in the constructor as well, so if your value is known at construction time then you can use final too.
If this value gets set (once, multiple times) during runtime then use private + getter.
The final modifier allows a field to be assigned only once - it cannot be changed after that and it has to be set at during object construction (that is, before the constructor returns).
If you want to make the field read-only, use the principles of information hiding: make it private and provide a public getter that returns the field (or a copy of it for non-primitive types).
You should use public final only for true constants. Even if your field is immutable because of final it is often a good idea to still make it private.
The correct way is to think in the future. What would help you achieve your goals? Maybe later you would also like to give that variable a value. If I were you, I'd do this by creatin a get method and keeping the variable private.
Full documentation for final keyword : http://en.wikipedia.org/wiki/Final_(Java)
Depends on where you want to access it from. Public variables can be accessed from any class within the project and package where private can only be accessed from the class where the variable is.
The 'final' operator makes it permanent and read-only.
Let's assume that type is a reference to an object, not a primitive type.
public final type attribute_name means that attribute_name cannot be reassigned to refer to something else. But attribute_name can be used to call a method that changes its state.
In private type attribute_name, only methods within the class can call methods on attribute_name.
So if you want it to remain constant, use approach (2). Limit the public methods to ones that ultimately call methods on attribute_name that don't modify its state.

Is there a method in java that returns member variables of a class

I have a requirement to check if the member variables of a class are there in a list or not. For this, I need to get all the variables of a class dynamically (if possible as a list). Is there a method for that in java?
Thanks,
KD
This is the concept of Reflection. You should be able to do something like the following (untested) code snippet:
/**
* #return {#code true} if all of the values of the fields in {#code obj} are
* contained in the set of {#code values}; {#code false} otherwise.
*/
public boolean containsAllValues(HashSet<Object> values, MyClass obj) {
Field[] fields = MyClass.class.getFields();
for (Field field : fields) {
Object fieldValue = field.get(obj);
if (values.contains(fieldValue)) {
return false;
}
}
return true;
}
You may get all of the field names (and their values) by calling Class#getFields()
Example: Consider the class below
public class Test{
public int x, y, z;
}
Test.class.getFields() will return the fields x,y,z, in which you could get their name through Field#getName() and get their value by calling the appropriate get method. In the Test class above, you could do something like this:
Test instance = new Test();
instance.x = 50;
int xValue = Test.class.getField("x").getInt(instance);
The value of xValue would be 50.
For a better demonstration of how it works, please see this.
You're talking about reflection.
Have a look at Class.getFields():
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html
See also:
http://forgetfulprogrammer.wordpress.com/2011/06/13/java-reflection-class-getfields-and-class-getdeclaredfields/
There are quite a lot of fishhooks with reflection. Property-based access -- bean properties, of the form getX()/setX() or isX()/setX() -- may be a little better in helping you avoid unstable implementation internal of the class.
You can use the getFields() method, that will return a Field array: http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getFields()
And then the getName() method for each element in the Field[] to get the name: http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Field.html#getName().
Most answers recommend Class.getFields() but as the JavaDoc states, it will only return the public fields:
Returns an array containing Field objects reflecting all the
accessible public fields of the class or interface represented by this
Class object.
I rarely make my class fields public and rather make them private with getters and setters. To get the list of all fields (including private, protected and package private) you need to use Class.getDeclaredFields():
Returns an array of Field objects reflecting all the fields declared
by the class or interface represented by this Class object. This
includes public, protected, default (package) access, and private
fields, but excludes inherited fields.
Note that unlike Class.getFields(), Class.getDeclaredFields() will not returned the inherited fields. To get those you need to loop through the class hierarchy (loop over Class.getSuperclass() until you reach Object.class). Private fields names could be repeated in parent classes.

Initializing on declaration vs initializing in constructors [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Should I initialize variable within constructor or outside constructor
I was wondering, which is a better practice and why. Should I initialize class fields upon declaration, or should I do it in the constructor? Given that it's a simple one-line initialization.
class Dude
{
String name = "El duderino";
Dude() {
// irrelevant code
}
}
vs.
class Dude
{
String name;
Dude() {
name = "El duderino";
// irrelevant code
}
}
Edit: I am aware of the situations where one of the styles would be preferred over the other like in the case of executing initializer code that might throw an exception. What I'm talking about here are cases when both styles are absolutely equivalent. Both ways would accomplish the same task. Which should I use then?
If the member can only be set via an accessor (a "setter" method), I prefer the first style. It provides a hint that the initialized value is the default upon construction.
If the member can be specified during construction, I generally pass the default value to an appropriate constructor from constructor with fewer parameters. For example,
final class Dude {
private final String name;
Dude() {
this("El Duderino");
}
Dude(String name) {
this.name = name;
}
}
The first one is used usually to initialize static variable and should be used only for that purpose.
In this case, you should use the second method.
Please correct me if I am wrong.
It is best to declare variables inside the constructor for the sake of consistency. A variable may require something like a loop or an if-else statement to initialize it, which can not be done in the declaration without placing the operation inside of a method.
The exception to this rule is static variables, which should be declared outside of the constructor.
Single-line declarations cannot contain complex initialization logic.
If you initialize a variable as:
class AnotherClass
{
MyClass anObject = new MyClass(); //MyClass() throws a checked exception.
}
then you'll find that you cannot provide the initial value in the single line. You'll need to place such code in a block, that quite obviously goes inside a constructor (or in a non-static initialization block):
Using a constructor:
class AnotherClass
{
MyClass anObject;
AnotherClass()
{
try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
}
}
Using a initialization block:
class AnotherClass
{
MyClass anObject;
{
try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
}
}
I find that the latter makes for less understandable code, as the declaration and initialization are separated from each other, and the initialization does not occur in a constructor coded by the developer (although there is no difference at runtime).
The same goes for other complex routines involved in initialization of fields. For example, if you intend to initialize an Array or a Collection and set the contents of the array/collection to some default value, then you should do so inside a constructor:
class AnotherClass
{
Integer[] integers;
AnotherClass()
{
this.integers = new Integer[10];
for(Integer integer: integers)
{
integer = Integer.MIN_VALUE;
}
}
}

How does Object Oriented Programming work?

I am not sure about some things in OOP.
If I have Class1, which has some private field, for example private Field field1, and make
getField1 () {
return field1;
}
then I have some class with constructor
public Class2 (Field field) {
someMethod(field);
}
And then I call constructor of Class2 in Class3 like:
Class2 cl = new Class2(instanceOfClass1.getField1());
And now the question: Am I working with field1 of instanceOfClass1 in someMethod(field)?
This depends on whether field is a value or a reference.
Value types are copied when passed as parameters. Reference types are not; the function is simply handed a "reference" that points back to the original value, and any changes that it makes are reflected in the original value.
Whether a given type is value or reference depends on your particular programming language. Generally speaking, basic integer and boolean types are usually value types, and everything else is up in the air -- some languages make strings values, and others treat them as references, etc.
Edit: Since you mentioned you're using Java, here's a short program that demonstrates value and reference types:
class ClassOne {
public int myInt;
}
class ClassTwo {
public int myInt;
public ClassTwo(ClassOne c)
{
myInt = c.myInt;
c.myInt = 3;
}
}
public class main
{
public static void main(String[] args)
{
ClassOne c = new ClassOne();
c.myInt = 1;
System.out.println("C1: " + c.myInt);
ClassTwo c2 = new ClassTwo(c);
System.out.println("C2: " + c2.myInt);
System.out.println("C1: " + c.myInt);
}
}
Running this program will give the output:
C1: 1
C2: 1
C1: 3
In this program, both ClassOne and ClassTwo contain an integer field -- a value type. ClassTwo takes a ClassOne parameter -- a reference type -- in its constructor, and sets its own integer field based on the value of the ClassOne object it is given, and then changes the ClassOne object's value.
Because classes are reference types, changing the ClassOne object in the ClassTwo constructor causes the original object to be changed. (In the main function here, that's c.) But because integers are value types, even though c2 changes the value of c.myInt in its constructor, because it sets its own value beforehand, c2.myInt isn't affected: it retains the original number, because it was copied rather than referenced.
Hopefully this helps clear things up a bit.
You're working with the value contained in it. If it is a mutable object then yes, it is possible to change the state of the instance of Class1 from outside, which violates data protection principles. This is why you should copy mutable types before returning them.
I had to reread your question two or three times to make sure I understood what you're asking.
To recap:
There is Class1 which contains an field attribute (of type Field?) which is sent back by it's getField1() method.
There is then Class2 which is apparently has a constructor that accepts an object parameter of Field type and contains a method that uses an instance of Field to trigger a local method in this class.
You then use a third class to instantiate Class2 and initialize it using an instance of Field using the getField1() method from an instance of Class1.
In the case of Java, providing you've done the necessary instantiation this would mean that the Field instance in Class1 is being used throughout the process. You can verify this using a System.out.println() (this will give you an # symbol with a series of weird numbers) or using the a.equals(b) method common to all objects.
Here is an interesting link about passing objects by value:
http://www.javaranch.com/campfire/StoryPassBy.jsp

Categories