Initializing private variables inside a constructor - java

I have been looking at this code for a comparator. My question is there a specific benefit of initializing the two private variables inside the constructor(Done here in the default constructor). I know the second constructor can be used to create an instance with supplied values. What difference would it make if I do
private String sortBy = COLUMN_LAST_NAME;
private boolean ascending = true;
I apologize if its a real simple and generic question.
public class CustomComparator implements Comparator<StudentList>
{ private String sortBy;
private boolean ascending;
public CustomComparator()
{
sortBy = COLUMN_LAST_NAME;
ascending = true;
}
public CustomComparator(String sortBy, boolean ascending)
{
this.sortBy = sortBy;
this.ascending = ascending;
}

The best practice i've seen preached everywhere is have one constructor that takes all parameters, even if it means it has to be private, and then just call it from other constructors using this(..,..,...) while supplying appropriate values.
This will make you reuse as much code as possible and future fixes go to one place and one place only - no need to make double maintenance of code.
Your example would look like this:
public class CustomComparator implements Comparator<StudentList> {
private String sortBy;
private boolean ascending;
public CustomComparator()
{
this(COLUMN_LAST_NAME, true);
}
public CustomComparator(String sortBy, boolean ascending)
{
this.sortBy = sortBy;
this.ascending = ascending;
}
}
Initialization is generally accepted to be in the constructor as to distinguish easier between static initialization of static members and per-instance init of instance variables. There is no performance difference.

Actually it matters if you care about object immutability (and you should :-)). If both of your fields are final, you must initialize them like this:
public class CustomComparator implements Comparator<StudentList> {
private final String sortBy;
private final boolean ascending;
public CustomComparator() {
sortBy = COLUMN_LAST_NAME;
ascending = true;
}
public CustomComparator(String sortBy, boolean ascending) {
this.sortBy = sortBy;
this.ascending = ascending;
}
}
Or even better:
public class CustomComparator implements Comparator<StudentList> {
private final String sortBy;
private final boolean ascending;
public CustomComparator() {
this(COLUMN_LAST_NAME, true);
}
public CustomComparator(String sortBy, boolean ascending) {
this.sortBy = sortBy;
this.ascending = ascending;
}
}

it's all about what you need, both constructor are good choices, obviuosly if you want to initialize the fields is the best choice but think if you use this class like an Entity on Hibernate or like a bean on Spring framework, if you dont write the empty constructor nothing will run fine...
if you think in DTO patterns, declaring inmutable fields like #Tomasz Nurkiewicz says then the parametrized constructor is the only choice....
but like i say before, it depends on requeriments...

I can't think of any difference and I prefer initializing in the variable declaration.

Related

How does a static method use a comparator?

I have a static method which needs to invoke the SportsMenComparator. But this, as we all know is not allowed. How does a static function use a comparator subclass ? Although I have workarounds, I am looking for best practices for this particular problem.
final class SportsMan {
private final String name;
private final int rank;
private final String sport;
public SportsMan (String name, int rank, String sport) {
this.name = name;
this.rank = rank;
this.sport = sport;
}
public String getName() {
return name;
}
public int getRank() {
return rank;
}
public String getSport() {
return sport;
}
}
final class Sport {
private final String sport;
private final int numberOfPlayers;
public Sport(String sport, int numberOfPlayers) {
this.sport = sport;
this.numberOfPlayers = numberOfPlayers;
}
public String getSport() {
return sport;
}
public int getNumberOfPlayers() {
return numberOfPlayers;
}
}
public final class Joins {
private Joins () {}
public class SportsMenComparator implements Comparator<SportsMan> {
#Override
public int compare(SportsMan s1, SportsMan s2) {
return s1.getSport().compareTo(s2.getSport());
}
}
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList) {
Collections.sort(sportsMans, new SportsMenComparator());
}
}
Eclipse results in the following message: No enclosing instance of type Joins is accessible where Joins is name of the enclosing class.
But this, as we all know is not allowed. How does a static function use a comparator subclass ?
You cannot use a non static reference,still you are allowed to create a new object and use it. So since you are creating a new SportsMenComparator object and passing, no issues.
For example:
public static void main(String[] args) {
List<String> s =new ArrayList<String>();
s.add(""); // allowed
}
But
List<String> s =new ArrayList<String>();
public static void main(String[] args) {
System.out.println();
s.add(""); // Error: Cannot make a static reference to the non-static field s
}
Edit:
Since you defined the comparator class inside the Joins , you need the Joins object to access the comparation inside it
Collections.sort(sportsMans, new Joins().new SportsMenComparator());
For using a Comparator, there is no difference between using it from a static- or non-static method. In either case an instance of the Comparator has to be used.
The Garbage Collector of modern JVMs is very efficient at handling short-lived objects. Therefore the penalty to be paid for using a fresh instance (via new) every time is usually no issue. However, if you don't want to use a fresh instance every time, I think the best option would be to add a static field to your SportsMenComparator, containing a singleton instance of the comparator:
public class SportsMenComparator implements Comparator<SportsMan> {
public static final SportsMenComparator instance=new SportsMenComparator();
#Override
public int compare(SportsMan s1, SportsMan s2) {
return s1.getSport().compareTo(s2.getSport());
}
}
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList) {
Collections.sort(sportsMans, SportsMenComparator.instance);
}
The problem is that you try to access an instance element (in this case it is a class, indeed the same as with a filed or method) within a static method, which is not associated with an instance. SURESH ATTA's answer is right, but you can also make your SportsMenComparator class static and it will work. I do not sse any reason to associate your comparator with an instance of the Joins class.
One can use something like this---
public static boolean someMethod(MyObject obj1, MyObject obj2){
return obj1.compare(obj2);
}
Why you cant include parameter to the function.
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList, Comparator comparator) {
Collections.sort(sportsMans, comparator);
}

public static final field in an abstract class or interface

I have a lot of subclasses of an abstract class and each of them declare a public static final field with the same name. I was thinking of having this field in the abstract superclass without initializing it and hoping that each subclass would be forced to initialize it.
I was thinking of this because all of my subclasses of the abstract class declare a public static final String field called UNIQUE_ID, and it is necessary for every subclass to declare such a field with exactly that name.
I hope my question is clear enough, if not please tell me so.
Can something more or less equivalent to this be done?
EDIT: Code added:
My abstract class looks like:
public abstract class ExperimentPanelModel extends Panelizable {
protected String nextButtonText;
protected String backButtonText;
protected String skipButtonText;
protected Properties currentFile;
protected List<Properties> pastFiles = new ArrayList<Properties>();
public ExperimentPanelModel(Properties argcurrentfile, List<Properties> argpastfiles) {
currentFile = argcurrentfile;
pastFiles = argpastfiles;
nextButtonText = "Next";
backButtonText = "Back";
skipButtonText = "Skip";
}
...
}
Some of the non-abstract subclasses of that abstract class look like (note that all of them declare public static final String UNIQUE_ID) :
public class ConfigurationGUI extends ExperimentPanelModel {
public static final String UNIQUE_ID = "ConfigurationGUI";
public static final String DATA_MODIFIED = "DataModified";
Date dateOfLastSession;
int ExperimentalSession;
int ExperimentOrder;
boolean nextButtonEnabled = false;
public ConfigurationGUI(Properties argcurrentfile, List<Properties> argpastfiles) {
super(argcurrentfile, argpastfiles);
nextButtonText = "Confirm";
backButtonText = "Abort";
}
...
}
One example more:
public class Introduction extends ExperimentPanelModel {
public static final String UNIQUE_ID = "Introduction";
public static final String INSTRUCTIONS_XML_FILE = "instructions.xml";
public static final String THIS_INSTRUCTION_PROPERTY = UNIQUE_ID;
private String thisInstructionText = UNIQUE_ID;
Properties readInstructionsProperties = new Properties();
public Introduction(Properties argcurrentfile, List<Properties> argpastfiles) {
...
And the last one:
public class Instruction1 extends ExperimentPanelModel {
public static final String UNIQUE_ID = "Instruction1";
public static final String INSTRUCTIONS_XML_FILE = "instructions.xml";
public static final String THIS_INSTRUCTION_PROPERTY = UNIQUE_ID;
...
}
The field idea won't work, because static fields can't be overridden in subclasses. What you can do is you can declare an abstract method on the abstract class so that your subclasses must implement it.
Also note you can't make it a static method because those don't get overridden either.
In your case I would define the variable in the ancestor. No point in having a variable in each of the extending classes, unless you have a particularly good reason, which you don't sound like having.
+1 for Nathan's reply though. In quite a few cases, that's a better thing to do.
Put the public final field UNIQUE-ID in the abstract class and declare a protected constructor which takes the value for UNIQUE-ID. You'll not be able to make it static though as the values are required to be different for different instances.

Determine which subclass to choose by accessing static variables from the Class object

I am trying to implement an interface in Java to use different types of databases for one application.
My though was to create an abstract class with the common interface and two static variables which are then overwritten by the subclasses. I then wanted to add a Class[] List with the classes of all available subclasses to the abstract class as well as a couple of functions that allow the determination of the correct class to be used.
The goal is to first get a list of all available database types and let the user choose one. Afterwards another function should translate the name (which could be localized) to the IDENTIFIER which is specified in the subclass. Finally a third function allows the instantiation of an object by giving such an IDENTIFIER.
My abstract class would look something like this:
public abstract class DataBase {
public static final IDENTIFIER = "";
public static final NAME = "";
private static final Class[] dbTypes = new Class[]{PostgreSQL.class, MySQL.class};
public static String[] getNameList() {
String[] names = new String[dbTypes.length];
for(int i = 0; i < dbTypes.length; i++){
names[i] = dbTypes[i].NAME; //Cannot access the static variable this way.
}
return names;
}
public static String getIdentifierForName(String name) {
for(int i = 0; i < dbTypes.length; i++){
if(name.equals(dbTypes[i].NAME){
return dbTypes[i].IDENTIFIER;
}
}
return "";
}
public static DataBase getInstanceOf(String identifier) {
for(int i = 0; i < dbTypes.length; i++){
if(identifier.equals(dbTypes[i].IDENTIFIER) {
return dbTypes[i].newInstance();
}
}
return null;
}
}
The Child classes would look something like this:
public class MySQL extends DataBase {
public static final IDENTIFIER = "ab.cde.MySQL";
public static final NAME = "MySQL";
...
}
public class PostgreSQL extends DataBase{
public static final IDENTIFIER = "ab.cde.PostgreSQL";
public static final NAME = "PostgreSQL";
...
}
My problem now is, that I cannot access the static variables from the Class object. Obviously the dbTypes list does not contain any typed classes. I tried changing the type of the Array to Class<? extends DataBase>, but I get an error Cannot create a generic array of Class<? extends DataBase> I also tried checking the classes with isAssignableFrom() and then casting the class, but I was still not able to access the static variables.
For now I have two solutions which are working:
Hardcode all existing subclasses into each function if(PostgreSQL.NAME.equals(name)){...}etc.
However, if I add new subclasses, I only want to have to add them at one point in my implementation.
Instead of using a Class[] array, I can use an array of DataBase[] with instances of each class. However, I would think this is bad practice to instantiate each available DataBase subclass, even though I only need one in the end.
Since I have never done such a thing before I might also be approaching the problem completely wrong. Maybe I am missing the correct way in which something like this is usually done?
Thank you for your help.
There are no "abstract properties" in Java. You have to create two astract methods in the DataBase class, like this:
public abstract class DataBase {
// No "abstract propeties"
public abstract String getDBName();
public abstract String getDBIdentifier();
// etc etc...
}
and then, in each subclass:
public class MySQL extends DataBase {
public static final IDENTIFIER = "ab.cde.MySQL";
public static final NAME = "MySQL";
#Override
public String getDBName() {
return NAME;
}
#Override
public String getDBIdentifier() {
return IDENTIFIER;
}
// etc etc...
}
When using the classes, you can just cast to DataBase (not MySQL or PostgreSQL) and call the two abstract methods.
Therefore, in order to solve your "pick a database class" problem, I would create a configuration file that contains the names of the databases and the corresponding class, and instantiate it with reflection (newInstance()) as needed.
As an alternative, you can use reflection to access the static variables like Nikita's answers suggested, or you can just use the name of the class as the identifier of the database it supports, like this (not tested):
public abstract class DataBase {
private static final Class[] dbTypes = new Class[]{PostgreSQL.class, MySQL.class};
public static Class getDBClass(String type) {
for (Class c : dbTypes) {
if (c.getSimpleName().toLowerCase().equals(type.toLowerCase())) {
return c;
}
}
return null;
}
public static Set<String> getSupportedDB() { // <-- you populate a dropdown menu with this
Set<String> supported = new HashSet<String>();
for (Class c : dbTypes) {
supported.add(c.getSimpleName());
}
return supported;
}
// etc etc...
}
However, I don't like this solution and I would not use it.
You can use reflection to get values for each class:
public static String[] getNameList(){
String[] names = new String[dbTypes.length];
for(int i=0; i<dbTypes.length; i++){
Field f = dbTypes[i].getField("NAME");
names[i] = f.get(null);
}
return names;
}
But it might be slow.
Also I'd suggest to create separate enum DBRegistry that will contain names, identifiers and classes:
public enum DBRegistry {
MYSQL("ab.cde.MySQL", "MySQL", MySQL.class),
POSTGRESQL("ab.cde.PostgreSQL", "PostgreSQL", PostgreSQL.class);
private String name;
private String identifier;
private Class<?> dbClass;
private DBRegistry(String identifier, String name, Class<?> dbClass) {
this.identifier = identifier;
this.name = name;
this.dbClass = dbClass;
}
// Getters...
}
You can iterate on all items in registry using DBRegistry.values
Not tested, but I would suggest something like this. You could register databases by calling DataBase.registerDataBase(new DataBase(...))); which may be invoked from the main file.
public class DataBase {
private final static List<DataBase> INSTANCES = new ArrayList<DataBase>();
private final String identifier;
private final String name;
private final Class<?> dbType;
public DataBase(String identifier, String name, Class<?> dbType) {
this.identifier=identifier.toString();
this.name=name.toString();
this.dbType=dbType;
}
String getIdentifier() {return identifier;}
String getName() {return identifier;}
Class<?> getDbType() {return dbtype;}
public synchronized static void registerDatabase(DataBase database) {
database.getClass();
INSTANCES.add(database);
//may check if already registered and either fail or replace it
}
public synchronized static List<DataBase> getNameList() {
return new ArrayList<DataBase>(INSTANCES);
}
public synchronized static List<String> getNameList() {
List<String> names = new ArrayList<String>(INSTANCES.size());
for (Database db:INSTANCES) names.add(db.getName());
return names;
}
public synchronized static String getIdentifierForName(String name) {
for(DataBase db:INSTANCES){
if(name.equals(db.getName())) return db;
}
return null;
}
public synchronized static DataBase getInstanceOf(String identifier) {
for(DataBase db:INSTANCES){
if(identifier.equals(db.getIdentifier())) return db;
}
return null;
}
}
}
I would advise to keep it simple, never more than necessary to utilize in the actual application. It is easier to extend things than to re-factor code to accomodate for additional complexity. Most of the stuff you mention are merely artefacts of your problem solving, not the actual requirements of your application per se. And it so happens, that a modern object-oriented language has everything you need, and you can implement a good design without reflection and without resorting to static properties and string identifiers.
Remember to rely on the compiler rather than runtime for whatever you know in advance - anything that is known not to change from one application run to another, does not need reflection, because it does not involve runtime variables! I would go for interfaces, classes implementing them, and more importantly the Factory pattern to abstract using these classes:
interface Database
{
void query(String sqlString);
}
class MySQLDatabase implements Database
{
public void query(String sqlString)
{
}
}
class PostgreSQLDatabase implements Database
{
public void query(String sqlString)
{
}
}
class DatabaseFactory
{
Database connectDatabase()
{
/// F.e. return new MySQLDatabase();
}
}
The whole "database abstraction layer" has been done to death already anyway, giving birth to DBA, ODBC and other software stacks that solve your problem. You should let yourself be inspired by these, unless you are sure your particular way of solving this yields advantages that can be proven. If you want to go about this in a professional way, of course. If you want to educate yourself, by all means, use reflection, strings in place of more specific objects, and tight-coupling instead of aggressive modularity.

Java Enum with multiple datatype fields?

I have following fields
a(String)
b(String)
c(String)
d(boolean)
e(boolean)
Is it possible to have them all in an Enum like following?
public enum Fields {
a("A")
b("B")
c("C")
d(true)
e(false)
}
You can have them but you should define constructors which takes String or boolean as parameters.
public enum Constants {
CONSTANT_STRING1("CONSTANT_VALUE1"),
CONSTANT_STRING2("CONSTANT_VALUE2"),
CONSTANT_STRING3("CONSTANT_VALUE3");
CONSTANT_FLAG1(false);
CONSTANT_FLAG2(true);
private String constants;
private boolean flag;
private Constants(String cons) {
this.constants = cons;
}
private Constants(boolean lFlag) {
this.flag= lFlag;
}
}
It sounds like you are using an enum to store constants, which is bad practice.
It is possible, but I would advice against it. In most cases, what you really want is a common interface, which is implemented by two (or more) different classes.
Please also note that is fully legitimate for an enum to implement an interface, but it is seldom you see two enums implement the same interface like in the example below:
public interface Fields {
}
public enum StringFields implements Fields {
A("A"),
B("B"),
C("C")
private StringFields(String str) {
this.str = str;
}
private final String str;
}
public enum BooleanFields implements Fields {
D(true),
E(false);
private BooleanFields(boolean val) {
this.val = val;
}
private final boolean val;
}
You can have two different constructors in the enum, but that means you need to have two fields (with one of them not being set). I do not think this would make much sense.
public enum Fields {
a("A"), b("B"), c("C"), d(true), e(false);
Fields(String str) {
strval = str;
value = false;
}
Fields(boolean val) {
strval = null;
value = val;
}
private final String strval;
private final boolean value;
}
EDITED*** Compiles now. You have to initialize both at the same time.

How to create an immutable class in Java without using final keyword [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Implement a final class without the “final” keyword
I want to create an immutable class in Java without using the final keyword.
I think smt like should work fine
class Immutable {
private int i;
public static Immutable create(int i){
return new Immutable(i);
}
private Immutable(int i){this.i = i;}
public int getI(){return i;}
}
But final is preferable.
The final keyword won't make your class inmutable. It will avoid your class to be extended from another class.
public final class Foo {
//....
}
public class Bar extends Foo {
//COMPILATION ERROR!
}
An adecuated class design is what will make you class inmutable, as you can see at duffymo answer.
Note that you can declare as final the fields that you will initialize at the constructor:
class Foo {
private final int state
public Foo(int v) {
this.state=v;
}
//....
}
The difference is that, while at duffymo example, the value ccould be changed from inner routines (i.e, a method adds one to the value, kind of a counter), at my example you wouldn't be able to do so.
Let's try to avoid absolutely the use of the final keyword:
public class Foo {
private int state;
private Foo(int v) {
this.state=v;
}
public static Foo getInstance(int value) {
return new Foo(value);
}
}
You only can get an instance of Foo accesing the Foo.getInstance method.
But anyway, you can extend the Foo class and make it mutable
I was wrong here. I won't compile, as you can acceess the Foo constructor.
public class Bar extends Foo {
private int ohNopes;
//COMPILATION ERROR!
public Bar(int v) {
this.ohNopes=v;
}
}
So, it seems it can be done, after all.
The problem with an immutable class not being final is that, subclasses may not be immutable.
Here is an example from the Java API, java.lang.String is immutable and final, if a string is passed to one of your methods you can be sure that it will remain in a consistent state.
the following will not compile because String is final:
public class MyString extends java.Lang.String {
public MyString(String original) {
Super(original);
}
#Override
public String toString() {
return String.valueOf(System.currentTimeMillis());
}
On the other hand, java.ma.BigDecimal itself is immutable, but it is not final and allowed to be subclassed. This opens up a range of issues. If a BigDecimal is passes to one of your methods you can't rely on the fact that no one has overridden BigDecimal like you can with String. subclasses of BigDecimal could potentially replace its methods with others which give unpredictable results.
The following will compile because BigDecimal is not immutable:
public class MyBigDecimal extends java.math.BigDecimal {
public MyBigDecimal(double val) {
super(val);
}
private int count = 0;
// override intValue which changes the state of this instance
#Override
public int intValue() {
return count++;
}
// rinse and repeat for the rest of the BigDecimal methods...
}
You cannot rely on he state of BigDecimal instances passed into your code, you should make Defensive copies of non final classes if you need to rely on their immutability.
I can't imagine why you object to using final, but here's a class that will get the job done. I know there are subtleties regarding serialization and reflection, but this can't be changed without special shenanigans:
public class Immutable
{
private int value;
public Immutable(int v)
{
this.value = v;
}
public int getValue() { return this.value; }
}
The class should set all its values in the constructor, and provide no setters (methods that modify class members).
You can create a class then create a .jar and use the jar as resource.

Categories