Implement an interface with final fields or access fields directly? - java

Is there any advantage of NOT having a class implement an interface and instead use the final fields directly? For example:
public interface MyInterface {
int CONST_A = 16;
int CONST_B = 45;
}
Approach 1:
public class MyClass implements MyInterface {
MyClass() {
System.out.println("A = " + CONST_A);
System.out.println("B = " + CONST_B);
}
}
Approach 2:
public class MyClass {
MyClass() {
System.out.println("A = " + MyInterface.CONST_A);
System.out.println("B = " + MyInterface.CONST_B);
}
}
I was wondering if any of the approaches above has advantage of any kind over the other. One of the places this situation occurs is in Blackberry where you have your localized texts defined as an interface with keys to the strings and you need to call a system API with the key as the argument in various parts of the code.

It is considered a bad practice to put constants in interfaces and to implements those interfaces to access the constants. The reason is, many classes could implement the interface, thus providing many access points to the same constants.
So, to answer your question, I'd rather use the second solution. Even better, I'd put the constants in a final class, so that there is only a single point of access to the constants. It'd be clearer, and would be easier to refactor.

use enumeration for constants (Effective Java)
For example define like that and call KernelError.KE_UNDEFINED_CALLER
public enum KernelError {
KE_NO_ERROR(0), KE_UNDEFINED_SESSION(1), KE_UNDEFINED_CALLER(2), KE_SESSION_EXPIRED(
3), KE_NULL_VALUE_IN_SESSION(4), KE_N0_SUCH_METHOD(5);
private KernelError(int errorCode) {
setErrorCode(errorCode);
}
private int errorCode;
/**
* #return the errorCode
*/
public int getErrorCode() {
return errorCode;
}
/**
* #param errorCode
* the errorCode to set
*/
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
}

If you defined constants in interfaces and, for example, define MyInterface2 which has a constant CONST_A, they conflict. Personally I think that approach 2 is easier to read.

I prefer approach 2 as it does not pollute the namespace of the using class with all possible constants. This reduces the number of code completion choices. Also, when looking at a use of a constant, the qualified name makes it obvious that it is a constant, and where that constant is defined.
That is, I prefer
interface Constants {
static int A;
static int B;
}
void foo() {
System.out.println(Constants.A);
}
to
interface Constants {
static int Const_A;
static int Const_B;
}
void foo() {
System.out.println(Const_A);
}

Related

Enums as replacement of Constants in Java

I heard now a day that We should use Enums instead of Constants .
Is it possible in all cases ? Whether enums are replacement of Constants ?
In Below Example I have Constants defined in Constants file and ConstantsTest uses them
public final class Constants {
private Constants(){
}
public static final String ACCOUNT="Account";
public static final String EVENT_ITEM ="EventItem";
public static final int MULTIPLIER_ONE = 1;
public static final int MULTIPLIER_NEGATIVE_ONE = -1;
public static final String BALANCE_AFTER_MODIFICATION = "BalanceAfterModification";
public static final String COMMA = ",";
public static final String DOTPSV =".psv";
public static final String NEW_LINE = "\n";
}
// Test Class
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ConstantsTest {
private static File rootDir = new File(".");
public static void main(String[] args) throws IOException {
Map<String,Integer> accountBalance = new HashMap<String, Integer>();
accountBalance.put("123",55000);
accountBalance.put("223",15000);
writeToFile(Constants.ACCOUNT, accountBalance, true, 2000);
// do operation
}
/**
*
* #param fileType
* #param inputData
* #param add if true add balance else substract the balance
* #return
* #throws IOException
*/
private static File writeToFile(String fileType , Map<String,Integer>accountBalance ,boolean add, int amount) throws IOException{
File file = null;
FileWriter fw = null;
try{
if(Constants.ACCOUNT.equals(fileType)){
file = new File(rootDir,Constants.ACCOUNT+Constants.DOTPSV);//creating a fileName using constants
fw = new FileWriter(file);
fw.write(Constants.ACCOUNT+Constants.COMMA+Constants.BALANCE_AFTER_MODIFICATION);//Writing Header in file using constant values
updateBalance(accountBalance, add, amount);
for(String key:accountBalance.keySet()){
fw.write(Constants.NEW_LINE);
fw.write(key+Constants.COMMA+accountBalance.get(key));
}
}
else if(Constants.EVENT_ITEM.equals(fileType))
{
// write to EventItem.psv
}
} finally{
if (null!=fw){
fw.close();
}
}
System.out.println("File created successfully");
return file;
}
private static void updateBalance(Map<String, Integer> accountBalance,
boolean add, int amount) {
for(String key:accountBalance.keySet()){
int currentBal = accountBalance.get(key);
if(add){
accountBalance.put(key,currentBal+amount*Constants.MULTIPLIER_ONE); // do lot of calculations
}else{
accountBalance.put(key,currentBal+amount*Constants.MULTIPLIER_NEGATIVE_ONE);// do a lot of calculations
}
}
}
}
Please suggest in my sample example enums would be better or my current approach of using constants is good enough ?
In your particular case the using enums is classic solution.
First, let's re-write your Constants as an enum:
public enum Constants {
ACCOUNT,
EVENT_ITEM,
;
}
public enum Operation {
MULTIPLIER_ONE {
public int action(int value) {
return value;
}
},
MULTIPLIER_NEGATIVE_ONE {
public int action(int value) {
return value * (-1);
}
},
;
private Operation(int coef) {
this.coef = coef;
}
public abstract int action(int value);
}
Now instead of writing:
if(Constants.ACCOUNT.equals(fileType)){
} else if(....)
you can either use switch/case or even better define: define method (let's call it action() into the enum and call it from your code. See example in Operation enum above. In this case you code becomes trivial: no more if/else or switch statements. Everything is simple. Validation is done at compile time: you defined abstract method in enum you cannot add yet another element to enum without implementing this method for it. This does not happen when using if/else structures maintenance of which is a programmer's responsibility.
I know only one limitation of enums: using string contstants in annotations. There are a lot of annotations with string attributes. For example XmlElement(name="foo"). Even if you define enum
enum FooBar {
foo, bar
}
you cannot use it in annotations:
#XmlElement(name=FooBar.foo) // is wrong because String type is required
#XmlElement(name=FooBar.foo.name()) // is wrong because annotations do not support method invocation
In all other cases I prefer enum.
You should use enums this code
enum Constants {
ACCOUNT,
EVENT_ITEM ,
COMMA ,
DOTPSV ,
BALANCE_AFTER_MODIFICATION ;
#Override
public String toString() {
switch(this) {
case ACCOUNT: return "Account";
case EVENT_ITEM : return "EventItem";
case COMMA : return ",";
case DOTPSV : return ".psv";
case BALANCE_AFTER_MODIFICATION : return "BalanceAfterModification";
default: throw new IllegalArgumentException();
}
}
}
Only we can use Enums for the constant values which are in the single group.
Let us suppose: Weeks, Months, Colours, Gender, Process states
It is not the good idea to use single enum for storing all constants. Instead we can use one enum for each group of constants.
Let us suppose you have maintaining some colour codes then better to have Colour enum instead of saving as constants.
An Enum doesn't define a contract for the class using it, an interface does. A class which uses an Enum isn't of the type an Enum. A class which implements an Interface is effectively of the same type as the interface (the Interface is the parent.. and the reference could be changed). Considering these design issues. Tell me, is your approach correct?
You got enum wrong, it's not like you should create an enum instead of constant: an enum is a group of constants that are related, for example:
enum Days {
SUNDAY, MONDAY, TUESDAY, ...
}
From the docs:
An enum type is a special data type that enables for a variable to be
a set of predefined constants.
Constants will be better for the example provided. Interface variables are public static final by default.
public static final String ACCOUNT="Account";
See Why are interface variables static and final by default?

Are enums less maintainable than public static final constants?

I was recently discussing enums vs public static final constants with a friend. I told him that public static final constants are more maintainable than enums, sometimes faster (android developer docs confirm this), and more convenient as well. I also said that you lose functionality when using enums as well:
You cannot extend an enum.
You cannot instantiate an enum.
He then said you shouldn't be using an enum if you need to instantiate or extend an enum. I then replied that's why we should just use constants because it is more maintainable; What if mid project we need to instantiate an enum or extend it? Then we would have to change everything.
An example demonstrating enums vs constants I made to illustrate my point:
public enum WeekDay {
/*
* We will start at 1 for demonstration
*/
SUNDAY("Sunday", 1), MONDAY("Monday", 2), TUESDAY("Tuesday", 3), WEDNESDAY(
"Wednesday", 4), THURSDAY("Thursday", 5), FRIDAY("Friday", 6), SATURDAY(
"Saturday", 7);
/*
* Notice we cannot do this...This is where enums fail.
*/
// LUNES("lunes",1), MARTES("martes",2);
private String dayName;
private int dayIndex;
private WeekDay(String dayName, int dayIndex) {
this.dayName = dayName;
this.dayIndex = dayIndex;
}
public String getDayName() {
return dayName;
}
public void setDayName(String dayName) {
this.dayName = dayName;
}
public int getDayIndex() {
return dayIndex;
}
public void setDayIndex(int dayIndex) {
this.dayIndex = dayIndex;
}
#Override
public String toString() {
return this.dayName + ": " + this.dayIndex;
}
}
What if we need Spanish week days as well? The enum falls short because you cannot extend it (you would have to do some copy and paste action).
Contrast the enum with this:
public class WeekDayClass {
private int dayIndex;
private String dayName;
public WeekDayClass(int dayIndex, String dayName) {
super();
this.dayIndex = dayIndex;
this.dayName = dayName;
}
public int getDayIndex() {
return dayIndex;
}
public void setDayIndex(int dayIndex) {
this.dayIndex = dayIndex;
}
public String getDayName() {
return dayName;
}
public void setDayName(String dayName) {
this.dayName = dayName;
}
#Override
public String toString() {
return this.dayName + ": " + this.dayIndex;
}
abstract static class Constants {
}
public static void main(String[] args) {
WeekDayClass init = new WeekDayClass(10, "I can init new days here");
}
}
And then I can extend it and make AmericanWeekDays:
public class AmericanWeekDay extends WeekDayClass {
public AmericanWeekDay(int dayIndex, String dayName) {
super(dayIndex, dayName);
}
static class AmericanConstants extends Constants {
public static final WeekDayClass SUNDAY = new WeekDayClass(1, "Sunday");
public static final WeekDayClass MONDAY = new WeekDayClass(2, "Monday");
/*
* And so on...
*/
}
}
Or Spanish Week Days:
public class SpanishWeekDays extends WeekDayClass {
public SpanishWeekDays(int dayIndex, String dayName) {
super(dayIndex, dayName);
}
static class SpanishConstants extends Constants {
public static final SpanishWeekDays LUNES = new SpanishWeekDays(2, "lunes");
/*
* And so on...
*/
}
}
Also to go even further:
public class WeekDayClass {
private int dayIndex;
private String dayName;
public WeekDayClass(int dayIndex, String dayName) {
super();
this.dayIndex = dayIndex;
this.dayName = dayName;
}
public int getDayIndex() {
return dayIndex;
}
public void setDayIndex(int dayIndex) {
this.dayIndex = dayIndex;
}
public String getDayName() {
return dayName;
}
public void setDayName(String dayName) {
this.dayName = dayName;
}
#Override
public String toString() {
return this.dayName + ": " + this.dayIndex;
}
static class AmericanConstants {
/*
* Insert Constants Here
*/
}
static class SpanishConstants {
/*
* Insert Constants Here
*/
}
}
I understand with an enum you could perhaps make a workaround using data structures (Lists) so you accommodate this shortcoming but why bother? With using public static constants I gain inheritance from the base class, cleaner code, possibly shorter code, and easier maintainability.
I also read that you can use enum's to better design "input parameters" but you could also do the same with the public static final constants as shown above.
Enums have the advantage of being able to be used in switch statements and have the inherited enum methods like values(). These methods can also be replicated if needed in "public static final constant" classes. Aside from the switch I don't see any enum advantages.
In conclusion, is an enum really better than public static final constants? If so, where did I go wrong? Is their something I am missing?
EDIT:
You cannot use generics in enums as well.
Enums get you a lot more than you seem to give them credit for, and while sometimes constants are required, this case is probably a win for enums.
First of all, there is no real difference between an "English weekday" and a "Spanish weekday", they represent the same values. Therefore, the best solution would be to do the conversion to string independently of what the values actually are through some kind of localization method. The values don't change with the language, their representation does.
This is entirely doable quickly and easily with enums. Just write it like this (a little pseudocode-y):
public enum Weekday {
MONDAY,
TUESDAY,
WEDNESDAY,
...;
public String toLocalizedString(Language l) {
// interact with localization files
}
}
You are conflating the ideas of external representation and internal representation. Your data should be as homogenous as possible because there is only ever going to be one Monday. It might be called different things, but it's still the same value.
Enums also get you a lot of niceness for free, though, which makes your code much clearer and more maintainable in the long run. Type checking, == comparison, and usability in switch are a few, with no boilerplate to speak of.
I think you're taking the usage of enums way to far and then come to a conclusion that they are not useful.
Enums are simply telling you that there's a limited and predefined number of options to choose from. Nothing more than that. For example, when you see a parameter that is an enum (let's say State) and it has 3 values (Pending, InProgress, Closed), you know that a state of some object can have one of those and only one of those values.
Enums provide an easy way of validating that a proper value is used as you cannot easily select a value that is not proper when coding. They are also a way of documenting as you can easily see what options are available.
Enumerations wouldn't exist if they weren't useful - the same can be said of constants. Just like a screwdriver can remove a screw while a hammer can remove a nail - different tools in your programmer "toolbox" can be used for unique and important purposes. I suggest reading more about enumerations and constants and I think you will find why they exist and when to use them.

Regarding alternative to interfaces and acessing with static imorts

I was going through a research in which I dont want to store the constants in the interface itself, so I was looking for alternatives like enums but another approach I have found is that ....t instead of using an interface, use a final class with a private constructor. (Making it impossible to instantiate or subclass the class, sending a strong message that it doesn't contain non-static functionality/data. and we can also take the advantage of static import in that case
Public final class KittenConstants
{
private KittenConstants() {}
public static final String KITTEN_SOUND = "meow";
public static final double KITTEN_CUTENESS_FACTOR = 1;
}
two independent things. 1: use static imports instead of abusing inheritance. 2: If you must have a constants repository, make it a final class instead of an interface . Please advise is this approach is correct..!!
To avoid some pitfalls of the constant interface (because you can't prevent people from implementing it), a proper class with a private constructor should be preferred (example borrowed from Wikipedia):
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
And to access the constants without having to fully qualify them (i.e. without having to prefix them with the class name), use a static import (since Java 5):
import static Constants.PLANCK_CONSTANT;
import static Constants.PI;
public class Calculations {
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT / (2 * PI);
}
}
Please show how we can do same ting with enum also..!
You can achieve your "constants" via an enum:
public enum Animal {
Kitten("meow", 1),
Puppy("woof", 2);
private final String sound;
private final double cuteness;
Animal (String sound, double cuteness) {
this.sound = sound;
this.cuteness = cuteness;
}
public String getSound() {
return sound;
}
public double getCuteness() {
return cuteness;
}
}
To use:
String sound = Animal.Kitten.getSound();
double cuteness = Animal.Kitten.getCuteness();
The simple answer is that you can't do that with an enum. An enum defines a set of related constants with the same type.
What you have in the KittenConstants case is a set of constants with fundamentally different types. This doesn't fit the enum model. (If you change the problem a bit; e.g. by generalizing over different kinds of SFA, you can make it fit ... as #Bohemian does ... but if that's not what you are trying to achieve, enum is not the right solution.)
What you have in the Constants case is a bunch of named floating point constants that you want to use as values. (All the same type ... which helps!) Now you could declare them as an enum as follows:
public enum Constants {
PLANCK_CONSTANT(6.62606896e-34),
PI(3.14.59);
public final double value;
Constants(double value) {this.value = value);
}
The snag is that you need to use ".value" to access each named constant's numeric value; e.g.
import static Constants.*;
....
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT.value / (2 * PI.value);
}
.... which is kind of ugly, and I don't think there is any way around the ugliness.
Bottom line - enums are not an ideal replacement for all kinds of constant.

Why use method local abstract inner classes

One of the legal modifiers you can use with method local inner classes is abstract.
For example:
public class Outer {
public void method(){
abstract class Inner{
}
}
}
Is there any situation where you would actually use this?
You have to know this for the SCJP exam.
The are some invalid assumptions in the original question. That something is legal/valid Java doesn't mean that it is something that you need to use, or need to know.
I can't recall that the SCJP contains odd corner case questions.
I tried to come up with a case where I would have used an abstract class declared in a method, but everything looks very odd, and reeks of bad design.
Here's however a code example that I came up with (still bad code design IMHO)
public class BatchExecutor {
public static enum ResultNotification {
JMS,
MAIL
};
public Runnable createRunnable(ResultNotification type) {
abstract class Prototype implements Runnable {
public void run() {
performBusinessLogic();
publishResult();
}
abstract void publishResult();
}
switch (type) {
case JMS: {
return new Prototype() {
void publishResult() {
//Post result to JMS
}
};
}
case MAIL: {
return new Prototype() {
void publishResult() {
//Post result to MAIL
}
};
}
}
return null;
}
private void performBusinessLogic() {
//Some business logic
}
}
I can think only in this case
class Outer {
public void method() {
abstract class A {
void bar(){}
abstract void foo();
}
class B extends A {
#Override
void foo() {
}
}
final class C extends A {
#Override
void foo() {
}
}
A a1 = new B();
A a2 = new C();
}
}
But I can't imagine real usage
IMHO, this feature has NO real use. There's a couple of possible abuses, but there are many other ways to write bad code, you needn't learn this one. :D
Whenever you try to make use of an abstract method-local class, you need to define at least two concrete method-inner classes. This means you end up with a method containing at least three classes, the method gets quite long and that's quite a bad style.
You have to know this for the SCJP exam.
I really hope not. Method-local inner classes are already useless enough to be considered a corner case (you should understand them but probably never use them).
IMHO, a person asking this in an exam misunderstood Java badly. There can't be accessibility modifiers on a local class since (lacking method literals) the class can't be accessed from the outside anyway. There can be abstract and final modifiers, since there's no reason to forbid them. There are good reasons to allow them: orthogonality and the Principle of least astonishment.
Is there any situation where you would actually use this?
Let S1 denote all situations in which you need an abstract class.
Let S2 denote all situations in which you need a local class.
The answer to your question can be found by examining S1 ∩ S2
Related questions:
What benefit do method-local inner classes provide in Java?
Use of Java [Interfaces / Abstract classes]
Clarification: My point is that the two features (abstract classes and local classes) are two completely orthogonal features of the language. Understanding when each feature is useful is the key to understanding when they are both useful at the same time.
You can get the use here http://java-questions.com/InnerClass_interview_questions.html
which says
The inner class declared inside the method is called method local inner class. Method local inner class can only be declared as final or abstract. Method local class can only access global variables or method local variables if declared as final
ie You can declare the static variables in the inner call and use them in the methods.
EDIT: Why abstract:
Because if you dont want to create the objects of the inner class. If you create the object in the method then it will be stored in the heap and it is not freed even if the method execution completes as there might be an external reference for this object when it is returned from the method.
So it depends on whether you want to create an instance or not. If you want to create then use final modifier.
the only real use I can imagine is for nodes in a data structure
that way you can differentiate methods from sentinel nodes and normal data nodes which can be really handy in recursive algorithms and you don't have to null check each time
No, there is no good use for abstract classes (or classes in general) inside methods.
It would only make sense if only that particular method would need that particular class and would also implement it. Actually having that situation maybe happens once in trillions of methods you write.
Check out the section titled "Hierarchies of Inner Classes" on this page.
The gist is that you can treat the inner class as just another abstract member that needs to be overridden/implemented. I don't necessarily agree with it (I would probably just define the inner class separately), but I've seen things like this in the wild.
Here's their example code:
public abstract class BasicMonitorScreen {
private Dimension resolution;
public BasicMonitorScreen(final Dimension resolution) {
this.resolution = resolution;
}
public Dimension getResolution( ) {
return this.resolution;
}
protected abstract class PixelPoint {
private int x;
private int y;
public PixelPoint(final int x, final int y) {
this.x = x;
this.y = y;
}
public int getX( ) {
return x;
}
public int getY( ) {
return y;
}
}
}
public class ColorMonitorScreen extends BasicMonitorScreen {
public ColorMonitorScreen(final Dimension resolution) {
super(resolution);
}
protected class ColorPixelPoint extends PixelPoint {
private Color color;
public ColorPixelPoint(final int x, final int y, final Color color) {
super(x, y);
this.color = color;
}
public Color getColor( ) {
return this.color;
}
}
}
I think it can be useful to reduce the scope of methods in certain conditions.
For exemple, I use it in unit tests. Sometimes you need an utility method to reduce the verbosity of a test. But this utility method may be related to the current test dataset, and can't be reused outside of this test.
#Test
public void facetting_is_impacted_by_filtering() {
// given
String userId = "cd01d6b08bc29b012789ff0d05f8e8f1";
DocumentSolrClient client = solrClientsHolder.getDocumentClient(userId);
//
final SolrDocument doc1 = createDocument(userId);
doc1.setAuthorName("AuthorName1");
doc1.setType("Type1");
doc1.setUserTags(Arrays.asList("UserTag1", "UserTag1bis","UserTag1bisbis"));
doc1.setSenderTags(Arrays.asList("SenderTag1", "SenderTag1bis"));
doc1.setCreationDate( new Date(EnumDateRange.CURRENT_DAY.getBegin().getTime()+1000) );
doc1.setLocation(DocumentLocation.INBOX);
client.index(doc1);
//
final SolrDocument doc2 = createDocument(userId);
doc2.setAuthorName("AuthorName2");
doc2.setType("Type2");
doc2.setUserTags(Arrays.asList("UserTag2"));
doc2.setSenderTags(Arrays.asList("SenderTag2"));
doc2.setCreationDate( new Date(1000) ); // cree il y a tres longtemps
doc2.setLocation(DocumentLocation.SAFE);
client.index(doc2);
//
final List<DateRange> facettedRanges = Arrays.<DateRange>asList(
EnumDateRange.CURRENT_DAY,
EnumDateRange.CURRENT_YEAR,
EnumDateRange.BEFORE_CURRENT_YEAR
);
class TestUtils {
ApiSearchRequest baseFacettingRequest(String userId) {
ApiSearchRequest req = new ApiSearchRequest(userId);
req.setDocumentTypeFacets(true);
req.setSenderNameFacets(true);
req.setSenderTagsFacets(true);
req.setUserTagsFacets(true);
req.addDateCreationFacets(facettedRanges);
return req;
}
void assertDoc1FacettingResult(ApiSearchResponse res) {
assertThat(res.getDocuments().size()).isEqualTo(1);
assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(2);
assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(3);
assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc1),facettedRanges) );
}
void assertDoc2FacettingResult(ApiSearchResponse res) {
assertThat(res.getDocuments().size()).isEqualTo(1);
assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(1);
assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(1);
assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc2),facettedRanges) );
}
}
TestUtils utils = new TestUtils();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
ApiSearchRequest req = utils.baseFacettingRequest(userId);
ApiSearchResponse res = documentSearchService.search(req);
// then
assertThat(res.getDocuments().size()).isEqualTo(2);
assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(2);
assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(2);
assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(3);
assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(4);
assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc1,doc2),facettedRanges) );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.addLocation(DocumentLocation.SAFE);
res = documentSearchService.search(req);
// then
utils.assertDoc2FacettingResult(res);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.addUserTag("UserTag1");
res = documentSearchService.search(req);
// then
utils.assertDoc1FacettingResult(res);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.addSenderTag("SenderTag2");
res = documentSearchService.search(req);
// then
utils.assertDoc2FacettingResult(res);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.setDocumentType("Type1");
res = documentSearchService.search(req);
// then
utils.assertDoc1FacettingResult(res);
}
In this real-life exemple, I could have done a regular inner class, but someone could have been tempted to reuse it in other tests, while it was not designed to.
By the way, you will notice the ability to "capture" the dataset build in the test directly inside the utility class. Using a regular inner class, it couldn't work without creating the test specific dataset outside the test too... so you end up with a lot of things shared with other tests, while they are used (should be used) by only one.
In the end, I don't think a feature permitting to reduce the visibility is useless.
You can build a perfectly working application without using encapsulation at all, and can argue the same thing, saying the private modifier is useless...
But yes, the private modifier is certainly more useful than method local innerclasses ;)
package dto;
public class Outer {
public void method(int x, int y){
abstract class Inner{
abstract void performAction(int x,int y);
}
class InnnerA extends Inner{
#Override
void performAction(int x,int y) {
int z =x+y;
System.out.println("addition :" + z);
}
}
class InnnerB extends Inner{
#Override
void performAction(int x,int y) {
System.out.println("multiply :"+x*y);
}
}
Inner inner1 = new InnnerA();
inner1.performAction(x,y);
Inner inner2 = new InnnerB();
inner2.performAction(x,y);
}
public static void main(String args[]){
Outer outer = new Outer();
outer.method(10,20);
}
}
You can use it like this.

Emulate C++ enum integer with Java Enums

I'm attempting to translate some C++ code into Java. I'm looking for the best way to emulate this type of C++ paradigm in Java -- I think enums are probably the answer but I'm open to anything
C++ code:
typedef UInt32 Type;
enum { UNKNOWN, QUIT, SYSTEM, TIMER, LAST }
...
Type newType = UNKNOWN;
Type nextType = LAST + 1;
...
// "Register" the new type
newType = nextType;
nextType++;
...
switch (newType) {
case UNKNOWN:
case QUIT:
...
case LAST:
// Ignore unset or predefined types
default:
// Some type other than the predefined. Do something special
Essentially I'm looking for a way to "expand" the values of a Java enumeration.
enum Type { UNKNOWN, QUIT, SYSTEM, TIMER, LAST }
doesn't quit cut it.
I like the idea of making a new object for strong typing.
Again, I'm looking for the best pattern to use here. I could easily float by with a few public static final int UNKNOWN, etc
One advantage of Java enums is, that they are essentially objects like all others. In particular, you can have methods on the constants, and make your enum implement interfaces:
interface Useful {
void doStuff();
}
enum Foo implements Useful {
DEFAULT {
public void doStuff() {
...
}
},
MAGIC {
public void doStuff() {
...
}
}
}
So, instead of taking arguments of the enum type, your methods could accept any implementation of the interface, and in particular, provide the default stuff by having the enum constants implement whatever is necessary.
They can also have members:
enum Explicit {
FIRST(0), SECOND(1), THIRD(2);
private final int value;
private Explicit(int v) {
this.value = v;
}
}
Note, that constants have an internal numeric value (reflecting the position of the constant among its peers) which is accessible using the ordinal method:
assert Explicit.FIRST.ordinal() == 0;
But relying on this is a little bit dangerous. If you are going to (say) persist enum constants in a database, then the following change would break the code:
enum Explicit {
FIRST(0), NEWELT(-1), SECOND(1), THIRD(2);
private final int value;
private Explicit(int v) {
this.value = v;
}
}
when using ordinal values. For this reason, the serialization machinery uses the constant's name instead of its position when serializing enum values.
So:
Type.X + 1
would be
Enum.values()[Enum.X.ordinal() + 1]
and the switch could be modelled using interfaces implemented by the enum itself (you can use enums in switch statements in Java, but often, making the enum implement the necessary code yields more maintainable code)
If each value of Type is just an int, then I'd probably go for a bunch of static final ints in a class.
Just for the record, something like this works more or less type-safely. I can't determine if the complexity is warranted without knowing more about the problem.
public class abstract Type
{
public static final Type UNKNOWN = registerStd("UNKNOWN");
...
public static final Type TIMER = registerStd("TIMER");
// use this to keep track of all the types
private static final List<Type> REGISTERED = ...
//This will do your switch statement for you, implemented by
// anonymous subclasses
public abstract void dispatch(Type onMe);
// here's how you make the standard ones
private static Type registerStd(String name)
{
Type heresOne = new Type(name)
{
// note, it's a no-op
public void dispatch(DoStuffer algorithm) {}
};
REGISTERED.add(heresOne);
return heresOne;
}
//here's how you make the non-standard ones
public static Type registerNew(String name)
{
Type heresOne = new Type(name)
{
public void dispatch(DoStuffer algorithm) {algorithm.execute(this)}
};
REGISTERED.add(heresOne);
return heresOne;
}
}
public interface DoStuffer
{
public void execute(Type onMe);
}
//Then your code becomes
Type newType = Type.registerNew("NewType");
newType.dispatch
(
new DoStuffer()
{
public void algorithm(Type forMe) { ... }
}
);
Maybe this is a little esoteric. But it does allow for "easy dispatch" at the caller site and an extensible enum, in some sense.

Categories

Resources