Proper way to use Final Field in RealmObject - java

I wanted to use final field in RealmObject like private final int fieldName. Because, I want to use constants and methods efficiently.
CleanTime.java
public class CleanTime extends RealmObject {
private final int NIGHT_TIME_LECTURE_MINUTE_LENGTH = 50;
private final int NIGHT_TIME_LECTURE_BREAK_TIME_MINUTE = 10;
// and other field
public CleanTime() {
// Constructor which use NIGHT_TIME_LECTURE_MINUTE_LENGTH
}
// and other methods
}
But the problem is my Logcat throws the error which said "this class contains illegal final field"
So, I had found some documents about realm and got the reason why it doesn't work.
In Realm official document..
Currently, Realm models have no support for final, transient and volatile fields. This is mainly to avoid discrepancies between how an object would behave as managed by Realm or unmanaged.
So, I have tried to solving this problem and below codes are completed which is using Instance Initializer
CleanTime.java
public class CleanTime extends RealmObject {
private int NIGHT_TIME_LECTURE_MINUTE_LENGTH;
private int NIGHT_TIME_LECTURE_BREAK_TIME_MINUTE;
// and other field
{ // Instance Initializer
NIGHT_TIME_LECTURE_MINUTE_LENGTH = 50;
NIGHT_TIME_LECTURE_BREAK_TIME_MINUTE = 10;
}
public CleanTime() {
// Constructor which use NIGHT_TIME_LECTURE_MINUTE_LENGTH
}
// and other methods
}
But I am curious whether this is proper, realm recommened way to use final field. Am I doing right? Is there any better idea?
Ah, above codes is same as NIGHT_TIME_LECTURE_MINUTE_LENGTH = 50 I want to fix NIGHT_TIME_LECTURE_MINUTE_LENGTH field and don't want it to be changed

Related

What is the recommended pattern for two classes with identical behaviours but different class constants? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I have two classes which have identical behaviour, except class SnakeCaseyMapper uses snake_case constant fields and class CamelCaseyMapper uses camelCase constant fields.
Before requiring two of these classes, my logic looked roughly like:
public class Mapper {
public static final String FIELD = "snake_casey_field";
// Lots of other constant fields ...
public Foo map(Bar bar) {
// Some logic that makes use of the constant FIELDs
}
}
public class ClassThatsDoingLogic {
var mapper = new Mapper();
var result = mapper.map(bar);
}
Now I require this same method, map(Bar bar) but with camelCase constants, as well as the original implementation with snake_case.
My idea was to make use of abstract classes:
public abstract class Mapper {
public String field; // Not instantiated here
// Lots of other member variable fields ...
public Foo map(Bar bar) {
// Some logic that makes use of the constant FIELDs
}
}
public class SnakeCaseyMapper extends Mapper {
public SnakeCaseyMapper() {
field = "snake_casey_field";
// Lots of other fields instantiated
}
}
public class CamelCaseyMapper extends Mapper {
public CamelCaseyMapper() {
field = "camelCaseyField";
// Lots of other fields instantiated
}
}
public class ClassThatsDoingLogic {
var snakeCaseyMapper = new SnakeCaseyMapper();
var result = snakeCaseyMapper.map(snakeCaseyBar);
var camelCaseyMapper = new CamelCaseyMapper();
var result = camelCaseyMapper.map(camelCaseyBar);
}
This way both classes use the same method logic in map() without duplicating the code. However, I think I lose the finality of the constant fields I had originally. Is there a way around this? Is there a way of handling this problem I'm missing?
As #Kayaman suggested, inheritance should be avoided, and in your case, it is all about parameterisation. If you can do it via configuration loading it would be great.
A solution in the middle, could be possibly to instantiate a private constructor with all the arguments needed, and then provide one public constructor that would call the private one, setting the arguments needed under condition. (Note: untested code in examples below)
public class Mapper {
enum MapperType {
CamelCase,
SnakeCase
}
// Never define a public property. Use setters
// and getters to modify them outside the class,
// preserving the encapsulation principle.
private MapperType mType;
private int mProperty1;
public Mapper(MapperType type) {
this(type, type == MapperType.CamelCase ? 100 : 200);
}
private Mapper(MapperType type, int mProperty1) {
this.mType = type;
this.mProperty1 = property1;
// More properties here
}
}
A deviation to this, would also be to use Factory-ish pattern (Note: take the definition with a grain of salt, as normally, a factory can be used in order to generate instances of different derived classes sharing the same base class).
public class Mapper {
enum MapperType {
CamelCase,
SnakeCase
}
private MapperType mType;
private int mProperty1;
public Mapper(MapperType type, int mProperty1) {
this.mType = type;
this.mProperty1 = property1;
// More properties here
}
}
Then, you can create a Factory "Wrapper" class for the initialization:
public static class MapperFactory {
public static Mapper instantiate(Mapper.MapperType type) {
// Dummy example. Notice that we change all parameters.
// a dispatch table can also be considered to avoid switching.
switch(type) {
case Mapper.MapperType.CamelCase:
return new Mapper(Mapper.MapperType.CamelCase, 100);
case Mapper.MapperType.SnakeCase:
return new Mapper(Mapper.MapperType.SnakeCase, 200);
}
}
}
and then, you can do:
Mapper m = MapperFactory.instantiate(Mapper.MapperType.CamelCase);
Consider though that, if you are just adding such a few parameters, such implementation is overengineering, just to show you an example. Use it only if you have LOTS of parameters for your objects and you want ti. In simple scenarios, just call the Mapper class with the appropriate parameters, or make a simple conditional check upon initialization.
Also, regarding the difference between snake_case and camelCase fields, you can use regex in order to distinguish and properly initialize upon condition, but my sense is that you are asking mainly for the proper code segmentation, rather than fields distinction based on the style they are written.
To add to my comments. Since inheritance can be used when there's different behaviour, this is definitely not the right place for it.
Below are 3 examples with "least effort", although they still require at least the amount of lines that you have fields in the mapper.
public class Mapper {
private final String FIELD;
private String FIELD2 = "defaultCamelCase";
private final String FIELD3;
public Mapper(boolean snakeCase) {
// This would work for final instance fields
FIELD = snakeCase ? "snakey_case_field" : "camelCaseField";
// or fields having default values
if(snakeCase) {
FIELD2 = toSnakeCase(FIELD2);
// or some kind of similar mechanism
}
// or final instance fields with a private constructor helper
// that returns either the parameter as-is, or converts it
FIELD3 = initField("fieldName", snakeCase);
}
private String initField(String field, boolean snakeCase) {
if(!snakeCase)
return field;
return Arrays.stream(field.split("(?=[A-Z])")).map(String::toLowerCase).collect(Collectors.joining("_"));
}
}

What is the correct way to initialize fields of Action classes in Struts 2?

I have a class which I am using to store data that I retrieve from a database which has objects as fields.
I want to initialize the objects when the class is instantiated to avoid null pointer problems.
I thought I read somewhere that it should not initialize the fields in the field declaration because it may cause problems for Struts (but I can't find the statement now), so I am initializing the fields in the constructor.
My question is:
Does it matter which way you do it? Or should you not do it at all and only put in the new objects after you instantiate the class? In other words should I define my class like this:
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo;
private PartyInfo partyInfo;
private RequestTableInfo requestTableInfo;
private PartyRequestInfo partyRequestInfo;
public MenuView(){
projectInfo = new ProjectInfo();
partyInfo = new PartyInfo();
requestTableInfo = new RequestTableInfo();
partyRequestInfo = new PartyRequestInfo();
}
followed by getters and setters or like this.
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo = new ProjectInfo();
private PartyInfo partyInfo = new PartyInfo();
private RequestTableInfo requestTableInfo = new RequestTableInfo();
private PartyRequestInfo partyRequestInfo = new PartyRequestInfo();
public MenuView(){ }
followed by getters and setters or like this:
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo;
private PartyInfo partyInfo;
private RequestTableInfo requestTableInfo;
private PartyRequestInfo partyRequestInfo;
public MenuView(){}
followed by getters and setters and then instantiate it like this:
MenuView menu = new MenuView();
menu.setProjectInfo(new ProjectInfo);
Any of the methods above would work but this would be best. The whole point of initializing a class is to avoid null referenced of course and initialize them with preferred values as shown below.
Adding getters and setters would work just fine from there
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo;
private PartyInfo partyInfo;
private RequestTableInfo requestTableInfo;
private PartyRequestInfo partyRequestInfo;
public MenuView(int a, int b, int c, int d){
projectInfo = new ProjectInfo(a);
partyInfo = new PartyInfo(b);
requestTableInfo = new RequestTableInfo(c);
partyRequestInfo = new PartyRequestInfo(d);
}
I read somewhere that you should not initialize the fields in the field declaration because that may cause problems for Struts (but I can't find the statement now)
No, not that I know
so I am initializing the fields in the constructor.
You can, but you're not forced to. I never use constructors on actions (I almost never use constructors at all, since I'm using Java EE 6+ and CDI, and in constructors the #Injected objects have not been injected yet - I use a #PostConstruct method instead, when necessary), but that's up to you, it's not a rule.
My question is does it matter which way you do it?
No
Or should you not do it at all and only put in the new objects after you instantiate the class?
Struts2 will handle the nulls for you in the JSP. The only NullPointerExceptions you must handle are on the Java side, so just check for null, or instantiate the objects in the declaration, and don't worry about it anymore.
Just remember that Struts2 will need a no-arg constructor to instantiate beans with JSP values.
It doesn't matter for Struts2, only sufficient that a ModelDriven object you should create yourself (if you are using ModelDriven interface).
The framework will create the objects if they are null when the form is submitted. This option is enabled by default. The magic is performed by the params interceptor which is using OGNL under hoods to populate the model from parameters passed to the action.
While this interceptor is being invoked, a flag
(ReflectionContextState#CREATE_NULL_OBJECTS) is turned on to ensure
that any null reference is automatically created - if possible. See
the type conversion documentation and the InstantiatingNullHandler
javadocs for more information.
More or less this feature is documented under com.opensymphony.xwork2.conversion.NullHandler.
The beans should comply a JavaBeans spec., so they could be instantiated by the Struts2 framework (if you want to learn more about JavaBeans, see this post What is a JavaBean exactly).

Convert outdated stored class to updated class

I am facing a problem with the classes. I store data in Serializable classes as a Java Object, not as a series of variables at some places. However, when I make changes to the class in question, Java would immediately throw an Error.
For example this is an old class:
class Demo implements Serializable{
private int a; private int b; int c;
public void doSomething(){}
public void doSomethingElse(){}
}
Which gets updated to:
class Demo implements Serializable{
private int a; private private int b; private int c; private String x; private String y; private String z;
public void doSomething(){}
public void doSomethingElse(){}
public void doAnotherThing(){}
public void doYetAnotherThing(){}
}
Is there a way to convert the old Object to the new one seamlessly without having to name the new class as DemoNew or something and then transferring the values one by one?
Regards.
That's what the serialVersionUID is for. If you declare it in your new class, and it has the same value as it had when the object was serialized, then Java will know that the new class is still compatible with the old class, and will initialize a, b, and c (and will leave the other fields to their default value).
So, get the old serialVersionUID from the error being thrown, and add this field to the class:
private static final long serialVersionUID = ...;
Of course, that only works if the new class is effectively still compatible with the old one. If you renamed or removed fields, then you'll have to make it compatible by explicitely reading the object as it was at the time of serialization.
If I were you, I would stop using serialization as a long-term persistence mechanism. Choose an easily migratable format instead: a database, JSON, or XML for example.

Getting a Field from an instance?

Is there any way to get a Field reference from an instance (not from a class) ?
This is an example :
public class Element {
#MyAnnotation("hello")
public String label1;
#MyAnnotation("world")
public String label2;
}
public class App {
private Element elem = new Element();
public void printAnnotations() {
String elemLabel1 = elem1.label;
String elemLabel2 = elem2.label;
// cannot do elemLabel.getField().getDeclaredAnnotations();
String elemLabel1AnnotationValue = // how ?
String elemLabel2AnnotationValue = // how ?
}
}
Sorry for not being too clear, but i already know how to fetch Fields from a class (Class --> Field --> DeclaredAnnotations)
What i am wondering is how to get the Field for a particular instance.
In this example, from elemLabel1 string instance, i wish to be able to get the Field of Element.label1.
What exactly do you mean? A Field on defined on the Class. You can get the value for a specific instance:-
private static class Test {
private int test = 10;
}
public static void main(String[] args) throws Exception {
final Test test = new Test();
final Field field = Test.class.getDeclaredField("test");
field.setAccessible(true);
final int value = field.getInt(test);
System.out.println(value);
}
The the class Test has a Field called test. This is true of any Test - it is defined in the Class. The instance of the class is has a specific value for that Field, in this case 10. This can retrieved for a specific instance using the getXXX or get method.
EDIT
From the code in your question it looks like you want the value of an Annotation field not the value of a class field.
In Java, values in annotations are compile time constants and therefore are also defined at the class rather than instance level.
public class Element {
#MyAnnotation("l")
public String label;
}
In your example, the MyAnnotation value field must be equal to 1 for every instance of Element.
Field belongs to class. Therefore you actually want to do the following:
elemLabel.getClass().getField("theFieldName").getDeclaredAnnotations();
However although your field is public typically all fields should be private. In this case use getDeclaredField() instead of getField().
EDIT
you have to call field.setAccessible(true) before using the field.

Should a java class' final fields always be static?

I could not find any references online about this. But just wanted to know if final fields in a class should always be static or is it just a convention. Based on my understanding of their uses, I feel that it is more of a logical thing to do than something that is imposed by the language.
Of course not. They must be static if they belong to the class, and not be static if they belong to the instance of the class:
public class ImmutablePerson {
private static final int MAX_LAST_NAME_LENGTH = 255; // belongs to the type
private final String firstName; // belongs to the instance
private final String lastName; // belongs to the instance
public ImmutablePerson(String firstName, String lastName) {
if (lastName.length() > MAX_LAST_NAME_LENGTH) {
throw new IllegalArgumentException("last name too large");
}
this.firstName = firstName;
this.lastName = lastName;
}
// getters omitted for brevity
}
No, absolutely not - and it's not a convention.
static and final are entirely different things. static means that the field relates to the type rather than any particular instance of the type. final means that the field can't change value after initial assignment (which must occur during type/instance initialization).
static final fields are usually for constants - whereas instance fields which are final are usually used when creating immutable types.
They don't always come together and it's not a convention. final fields are often used to create immutable types:
class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
On the other hand static but not final fields are not that common and are quite tricky. static final is seen often because it means application1-wide constant.
1 - well, class loader-wide, to be precise
Final fields do not need to be static, and sometimes it can be useful to have a non-static final instance variable. Fields that are marked both static and final are usually used for constants, like this:
public static final int BORDER_WIDTH = 5;
However, sometimes you'll see a non-static final field when an object has a immutable property. Usually, non-static final fields are still marked private for the usual reasons, though, so it's more of an extra check so the compiler can make sure you're never setting the property again.
If you want to access them like ClassName.FIELD, then yes, you have to do that. If you don't make it static, you have to do something like new ClassName().FIELD, which is unnecessary and a pointless creation of an object.
However, if you are only using it in the class or making it private, then don't make it static. If you are within the actual class, you can just do FIELD.
To fully grasp this concept, you have to know what static means. Static means that it belongs to the actual class, not an instance of it.
Absolutely not. Consider:
class Point {
public final int x;
public final int y;
public Point(int _x, int _y) {
x = _x;
y = _y;
}
}
Drop the final, and the class becomes mutable. Add a static, and all your points are the same, and there is no legal way to write the constructor.
Absolutely not. Immutable objects, for example, have final properties, that can be set only once, by the constructor.
For more information, please see: http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
Immutable objects are not the only case in which final properties are used, but they provide a evident example of their usefulness.
The answer is no.
static
"Indicates that only one such data field is available for all
instances of this class. Without this modifier, each instance has its
own copy of a data field"
...meaning there can only be one of this
final
"The value provided for the data field cannot be modified"
...meaning that this is a constant

Categories