How to find a static String in a Interface - java

I have the folowing interface;
public static interface Attributes
{
public final static String InterestDeterminationDate = "InterestDeterminationDate";
public final static String CreditType = "CreditType";
public final static String NumberInternal = "NumberInternal";
public final static String InterestRate = "InterestRate";
public final static String RemainingDebtAmount = "RemainingDebtAmount";
public final static String ConsumerPart = "ConsumerPart";
public final static String TechnicalProductName = "TechnicalProductName";
public final static String TermOfDuration = "TermOfDuration";
public final static String PeriodInterestTaxReduction = "PeriodInterestTaxReduction";
public final static String OriginMark = "OriginMark";
public final static String Currency = "Currency";
public final static String PenaltyRuleId = "PenaltyRuleId";
public final static String InstallmentCalculationMethod = "InstallmentCalculationMethod";
public final static String InterestRenewalDate = "InterestRenewalDate";
public final static String TechnicalProductDescription = "TechnicalProductDescription";
public final static String TechnicalProductDate = "TechnicalProductDate";
public final static String CollectionIntervalPeriod = "CollectionIntervalPeriod";
public final static String Enddate = "Enddate";
}
I need to check is a given string is a part of this Attributes Interface.
How can i check this?
Regards,
bas Hendriks

If you really want todo this, then you should use reflection and go through all the values in Attributes.
A better way to do this would be the use of enums :
public enum Attributes{
InterestDeterminationDate,
CreditType,
NumberInternal,
InterestRate,
RemainingDebtAmount,
ConsumerPart,
TechnicalProductName,
TermOfDuration,
PeriodInterestTaxReduction,
OriginMark,
Currency,
PenaltyRuleId,
InstallmentCalculationMethod,
InterestRenewalDate,
TechnicalProductDescription,
TechnicalProductDate,
CollectionIntervalPeriod,
Enddate;
}
and the Attributes.valueOf(yourVariable); would check this for you.
Beware with enum, the valueOf() method will throw a IllegalArgumentException if yourVariable isn't in Attributes. Plus you yourVariable isn't null or you will have to handle a NullPointerException

Your question doesn't make it clear whether you're trying to find out if the query string is the property name or value. If you're trying to find out if it's a value, the following will work:
public static boolean hasValue(String value) throws IllegalAccessException {
for(Field field : Attributes.class.getDeclaredFields()) {
if(((String)field.get(Attributes.class)).equals(value)) {
return true;
}
}
return false;
}
However, I would advise following Colin's suggestion of using an Enum, it will be easier for you to work with in the future.

You can build a set using reflection and test against that set:
Class<Attributes> attr = Attributes.class;
Field[] fields = attr.getDeclaredFields();
final Set<String> fieldsInAttributes = new HashSet<String>();
for (Field field : fields) {
fieldsInAttributes.add(field.getName());
}
System.out.println(fieldsInAttributes.contains("PenaltyRuleId"));

You can use the reflection API, and the "getFields()" method of the Class class.
Then you check the field name with the "getName()" method of the Field class.
Here is the Oracle official tutorial.

public static String getFieldName(String fieldValue) throws Exception {
for (Field field : Attributes.class.getFields())
if (fieldValue.equals(field.get(null)))
return field.getName();
return null;
}

Related

Java constant names conventions for date formats

Constant names should be match with this regular expression '^[A-Z][A-Z0-9](_[A-Z0-9]+)$' But I have DateConstant and I think date formats of constants more understandable and readable, if use write them like this:
public static final String DATE_FORMAT_yyyyMMdd = "yyyyMMdd";
public static final String DATE_FORMAT_yyyy_MM_dd = "yyyy-MM-dd";
public static final String DATE_FORMAT_yyyy_MM_dd_Combined = "yyyyMMddHHmm";
public static final String DATE_FORMAT_yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm";
public static final String DATE_FORMAT_dd_MM_yyyy = "dd-MM-yyyy";
public static final String DATE_FORMAT_dd_MM_yyyy_WITH_DOT = "dd.MM.yyyy";
public static final String DATE_FORMAT_mm_dd_yyyy_WITH_SLASH = "MM/dd/yyyy";
public static final String DATE_FORMAT_m_d_yyyy_WITH_SLASH = "M/d/yyyy";
public static final String DATE_FORMAT_dd_mm_yyyy_WITH_SLASH = "dd/MM/yyyy";
public static final String DATE_FORMAT_dd_MMM = "ddMMM";
public static final String DATE_FORMAT_dd_MM_yy = "ddMMyy";
public static final String DATE_FORMAT_dd_MMM_yyyy = "ddMMMyyyy";
public static final String DATE_FORMAT_dd_MM_yyyy_COMBINED = "ddMMyyyy";
public static final String DATE_FORMAT_dd_MM_yyyy_HH_mm_ss = "yyyy-MM-dd'T'HH:mm:ss";
public static final String DATE_FORMAT_dd_MM_yyyy_HH_mm_ss_sz = "yyyy-MM-dd'T'HH:mm:ss.SSS";
public static final String DATE_FORMAT_dd_MM_yyyy_HH_mm_ss_sz_XXX = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; // with mobile client
public static final String DATE_FORMAT_dd_MM_yyyy_HH_mm = "dd-MM-yyyy HH:mm";
public static final String DATE_FORMAT_HH_mm = "HH:mm";
public static final String DATE_FORMAT_YYYY_MM_DDTHH_mm_ssZ = "YYYY-MM-DD'T'HH:mm:ssZ"; // Google Calendar Format
I need some advice and find alternative way to rename these constant names.
I completely agree with #luk2302, including the value of a constant in its name is a bad idea.
However, given your current situation why not just define Map that is static and final. It is almost equivalent to all your constants defined and you wouldn't get any warnings from your IDE or tools like sonar.
In this solution we create 2 maps. The first map contains all the constant values but is defined as private. If this is declared public then its values can be altered and defeats the purpose of a constant. To overcome this issue we define an unmodifiable map which is declared in the last line of the static block. Now by exposing only this map no mutation on it is possible.
Try :
public class Constant {
private Constant() { } // Can't create obj of this class
// map that contains the constans but not exposed
private static final Map<String, String> mapOfConstants = new HashMap<String, String>();
// unmodifiable map that is exposed
public static Map<String, String> unmodifiableMap;
static {
mapOfConstants.put("yyyyMMdd", "yyyyMMdd");
mapOfConstants.put("yyyy_MM_dd", "yyyy-MM-dd");
mapOfConstants.put("yyyy_MM_dd_Combined", "yyyyMMddHHmm");
mapOfConstants.put("yyyy_MM_dd_HH_mm", "yyyy-MM-dd HH:mm");
mapOfConstants.put("dd_MM_yyyy", "dd-MM-yyyy");
mapOfConstants.put("dd_MM_yyyy_WITH_DOT", "dd.MM.yyyy");
mapOfConstants.put("mm_dd_yyyy_WITH_SLASH", "MM/dd/yyyy");
mapOfConstants.put("m_d_yyyy_WITH_SLASH", "M/d/yyyy");
mapOfConstants.put("dd_mm_yyyy_WITH_SLASH", "dd/MM/yyyy");
mapOfConstants.put("dd_MMM", "ddMMM");
mapOfConstants.put("dd_MM_yy", "ddMMyy");
mapOfConstants.put("dd_MMM_yyyy", "ddMMMyyyy");
mapOfConstants.put("dd_MM_yyyy_COMBINED", "ddMMyyyy");
mapOfConstants.put("dd_MM_yyyy_HH_mm_ss", "yyyy-MM-dd'T'HH:mm:ss");
mapOfConstants.put("dd_MM_yyyy_HH_mm_ss_sz", "yyyy-MM-dd'T'HH:mm:ss.SSS");
mapOfConstants.put("dd_MM_yyyy_HH_mm_ss_sz_XXX", "yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
mapOfConstants.put("dd_MM_yyyy_HH_mm", "dd-MM-yyyy HH:mm");
mapOfConstants.put("HH_mm", "HH:mm");
mapOfConstants.put("YYYY_MM_DDTHH_mm_ssZ", "YYYY-MM-DD'T'HH:mm:ssZ");
// observe this line
unmodifiableMap = Collections.unmodifiableMap(mapOfConstants);
}
}
Now you can use it in another class like :
public class Test {
public static void main(String[] args) {
Constant.unmodifiableMap.get("dd_MM_yyyy_COMBINED");
// this wouldn't execute
Constant.unmodifiableMap.put("asd", "asdad");
}
}
You won't be able to use an enum either as it would ask you to define the constants as per your question.

How to code a checkStyle method in Java?

Our teacher asked us to make a method which takes a Class as a parameter then checks the fields and methods if they follow the rules of Checkstyle (Upper case, lower case, final attribute, etc.)
He gave us a piece of code to start with but I don't know what to do next.
public class CheckStyle {
static String valider(Class c){
Field[] tattribut = c.getDeclaredFields();
String name = c.getName();
Method[] tmethod=c.getDeclaredMethods();
}
public static void main(String[] args) {
String error = CheckStyle.valider(a.class);
System.out.println(error);
}
}
Try to use some of this code:
public class SomeClass {
private String aaa;
private String bbb;
private double ccc;
}
public static void main(String[] args){
List<Field> privateFields = new ArrayList<>();
Field[] allFields = SomeClass.class.getDeclaredFields();
for (Field field : allFields) {
if (Modifier.isPrivate(field.getModifiers())) {
privateFields.add(field);
}
}
}
Then go over your fields to see if they are in the correct format you need and ect.

The difference between this and the class name

I've asked this question Adding objects to an array. And now it has brought up another question.
Is there a difference between this:
For class Patient:
public Patient(String ptNo, String ptName, int procType) throws IOException
{
Patient.patientNo = ptNo;
Patient.patientName = ptName;
Patient.procedureType = procType;
}
and this:
public Patient(String ptNo, String ptName, int procType) throws IOException
{
this.patientNo = ptNo;
this.patientName = ptName;
this.procedureType = procType;
}
I thought they were the same thing?
edit
I have created these in the Patient class.
private static String patientNo;
private static String procedureDate;
private static String patientName;
this is used to the access the properties that belong to an object whereas Classname is used to access the properties that belong to a class. Properties belonging to a class/static attributes means that those will be shared by all the objects.
Suggested reading: Understanding Instance and Class Members
public Patient(String ptNo, String ptName, int procType) throws IOException
{
Patient.patientNo = ptNo;
Patient.patientName = ptName;
Patient.procedureType = procType;
}
This code will only work if all three variables are static like this
public class Patient
{
static String patientNo;
static int procedureType;
static String patientName;
public Patient(String ptNo, String ptName, int procType) throws IOException
{
Patient.patientNo = ptNo;
Patient.patientName = ptName;
Patient.procedureType = procType;
}
}
Whereas something like this
public Patient(String ptNo, String ptName, int procType) throws IOException
{
this.patientNo = ptNo;
this.patientName = ptName;
this.procedureType = procType;
}
will work for non static variables, "this" simply is used to avoid confusion denote the object whose constructor is being called. Example
Patient p = new Patient("A","B",1);
would be same as saying
p.patientNo = ptNo;
p.patientName = ptName;
p.procedureType = procType;
EDIT
"this" comes to rescue in a situation like this
public class Patient
{
String patientNo;
int procedureType;
String patientName;
public Patient(String patientNo, String patientName, int procedureType) throws IOException
{
this.patientNo = patientNo; // variables in LHS are class members, RHS are method parameters
this.patientName = patientName;
this.procedureType = procedureType;
}
}
You use this to access to the non-static members of the class, whereas ClassName is used to access the static members. The non-static fields of a class are unique to each instance of the class, whereas the static fields are common to all instances.
class Test{
String txt;
static String sTxt;
public Test(String t) {
this.txt = t; // accessing the instance variable using this
}
}
class Test2{
void someMethod(){
Test t = new Test("someString");
Test.sTxt; // Accessing the static member, using classname
}
}
this is used to access Object properties. It is typically used to access non-static variables of the class, as they are associated with the object.
className is typically used to access static variables, as static variables are associated with the class.
Static variable are initialized when class loads where as object variable are initialized only when object of class is created.

Using constants across the application

I have few constant values which I refer across my application. I am creating a class something like below snippet.
public class Styles {
public static final String tableStyle = "TableGrid";
public static final String fontFamily = "Calibri";
public static final String headerStyle = "Heading2";
public static final String footerStyle = "Heading3";
public static final String tableHeaderStyle = "Heading1";
public static final String tableDataFontFamily = "Cambria";
public static final int tableHeaderFontSize = 16;
public static final int tableDataFontSize = 12;
}
I am assigning the values in it and I am referring them like Styles.headerStyle . My doubt is, is this the good way or is there any better approach to achieve this? something like Enum ?
Thanks in advance.
It depends on the nature of your application, in most cases it is not a good practice to have a collection of constants in that way, but it is difficult to tell without knowing the context of your application. BTW, are sure that you'll never (or almost never) change things like "fontFamily"?
Of course an enum would be a little less verbose and more functional:
public enum Styles {
TABLE_STYLE("TableGrid"),
FONT_FAMILY("Calibri"),
HEADER_STYLE("Heading2"),
FOOTER_STYLE("Heading3"),
TABLE_HEADER_STYLE("Heading1"),
TABLE_DATA_FONT_FAMILY("Cambria"),
TABLE_HEADER_FONT_SIZE("16"),
TABLE_DATA_FONT_SIZE("12");
private String value;
private Styles(String value) {
this.value = value;
}
public String getStringValue() {
return value;
}
public int getIntValue() {
return Integer.valueOf(value);
}
}
1) You can use an external file as a Property File.
2) You can use an enum as #morgano answer
3) I would change your class declaration to
public final class Styles { // final class can't have childs
private Styles(){} // you cannot instanciate
public static final String tableStyle = "TableGrid";
.
.
.
}

Java XML Serializing, Missing fields in file

this is the issue at hand, when trying to serialize the class below with the code below i'm getting is the below xml file without all the strings in the class.
The Class (some static values have changed but basically it), I left out all the generated get\set but they are all there with public access modifiers.
public class NotificationConfiguration implements Serializable
{
public static final String PORT_KEY = "mail.smtp.port";
public static final String DEFAULT_PORT_VALUE = "587";
public static final String TTL_KEY = "mail.smtp.starttls.enable";
public static final String DEFAULT_TTL_VALUE = "true";
public static final String AUTH_KEY = "mail.smtp.auth";
public static final String DEFAULT_AUTH_VALUE = "true";
public static final String MAIL_SERVER_KEY = "mail.smtp.host";
public static final String DEFAULT_MAIL_CLIENT_HOST = "smtp.gmail.com";
public static final String DEFAULT_MAIL_CLIENT_USERNAME = "*********";
public static final String DEFAULT_MAIL_CLIENT_PASSWORD = "*********";
public static final String DEFAULT_MAIL_CLIENT_ADDRESS = "*********";
public static final String DEFAULT_ADMIN_EMAIL = "*********";
public static final long DEFAULT_MAIL_INTERVAL = 24*60*60*1000; //One time a day default
public static final String SAVED_FOLDER_NAME = "C:\\Library";
public static final String SAVED_FILE_NAME = "C:\\Library\\NotificationCfg.xml";
private String portValue = DEFAULT_PORT_VALUE;
private String ttlValue = DEFAULT_TTL_VALUE;
private String authValue = DEFAULT_AUTH_VALUE;
private String mailClientHost = DEFAULT_MAIL_CLIENT_HOST;
private String mailClientUserName = DEFAULT_MAIL_CLIENT_USERNAME;
private String mailClientPassword = DEFAULT_MAIL_CLIENT_PASSWORD;
private String mailClientAddress = DEFAULT_MAIL_CLIENT_ADDRESS;
private String adminEMail = DEFAULT_ADMIN_EMAIL;
private boolean overdueSubsNotificationEnabled = false;
private boolean adminReportNotificationEnabled = false;
private long mailInterval =
}
The code used to serialize, which also creates the folder if missing.
public void storeChanges()
{
try
{
try
{
File f = new File(NotificationConfiguration.SAVED_FOLDER_NAME);
f.mkdir();
}
catch (Exception e){}
XMLEncoder encoder = new XMLEncoder( new BufferedOutputStream(new FileOutputStream(NotificationConfiguration.SAVED_FILE_NAME)));
encoder.writeObject(notificationConfig);
encoder.close();
System.out.println(LOG_CONFIGURATION_STORED);
}
catch (Exception ex)
{
System.out.println(LOG_CONFIGURATION_NOT_STORED + ex.getMessage());
}
}
The XML file received, with no exceptions thrown while serializing.
It basically just has the long value.
XMLEncoder encodes information about how to restore your object. If field values haven't changed from their defaults, XMLEncoder doesn't store anything.
This can cause confusion.
Hence, my rules of thumb when using XMLEncoder are:
1. don't initialize fields. don't do private String foo = DEFAULT_FOO;
2. don't do anything in the default constructor.
3. have some other method, or factory that will give you a "default" setup if needed.
I highly recommend to read again the XMLEncoder Javadoc
I will point out the main differences with the binary serialization we all know.
to restore the instance it need the class definition available to the JVM
It serializes only the data. And only the modified from default data.
As result of the 2 points above - is that there is no reason to serialize Static final values - they are part of the class definition.
The binary serialization on the other hand does serialize the class definition and can load from byte stream a class that was not available to the JVM before.
That is why you got results that you see. It Ok this is behavior by design and you use it right. It seems just not to be what you need.
By the way see what Xstream has to offer.
What is SAVED_FOLDER_NAME ? Is that like a factory object and did you by any chance call setMailInterval on that object?
Could that be that only mailInterval has a getter?
Just looked again the question apparently there is getter for all fields so ...

Categories