Enum static or non-static method - java

Consider the following enum class
public enum ClassA {
CHECK1("X", 0),
CHECK2("Y", 2),
CHECK3("Z", 1);
private final String id;
private final String cdValue;
private ClsA(String id, String cdValue) {
this.id = id;
this.cdValue = cdValue;
}
private String getId() {
return id;
}
private String getCdValue() {
return cdValue ;
}
private static final List<String> cdValues = new ArrayList<String>();
static {
for (ClassA clsA : ClassA.values()) {
cdValues.add(clsA.getCdValue());
}
}
public boolean isCdValue(String cdValue)
{
if clsValues.contains(cdValue)
return true;
else return false;
}
}
The question that I have is does the method isCdValue has to be static. I have to use this method isCdValue for every input given by the client. Therefore the method parameter cdValue changes for every input.
If it cannot be static then I would like to know how I can access this method. Please note I am primarily interested in learning about static of non-static method call. If it is a non-static call in a enum then how can we call this non static method. I am not trying to resolve the issue of how to get about checking the cdValue exists or not. It is just an example.

does the method isCdValue has to be static.
Yes, the method isCdValue has to be static here.
An enum is a special kind of class. An enum constant defines an instance of the enum type. An enum type has no instances other than those defined by its enum constants. Hence new can not be used to instantiate an enum.
An enum type has no instances other than those defined by its enum
constants. It is a compile-time error to attempt to explicitly
instantiate an enum type (§15.9.1).
Refer this

If you have to put the checking method in the Enum, I think it should be static
you can do this check:
ClassA.isCdValue(para)
Note that, you cannot new an Enum object. So if the method in your Enum, and it is not static, you cannot call it unless you have an Instance. but the goal of your method is checking if the string could be an instance.
another possibility is, use an immutable collection in your Enumm, and make it static and public. Then you could just call ClassA.CD_VALUES.contains(para)

If you want to access it from ClsA, you will have to make it static, if you want to access it from an instance of ClsSa then it doesn't.
A couple of other things: where do you declare clsValues in the first place?
There's no need for the complex if, you may replace this:
public boolean isCdValue(String cdValue)
{
if clsValues.contains(cdValue)
return true;
else return false;
}
with this
public boolean isCdValue(String cdValue){
return clsValues.contains(cdValue)
}
Last little thing, I'd strongly suggest you put curly braces around all your if and else's clauses, I've spent many a debugging hour because someone added a second line under the else, fooled by the indent and thinking it would only execute on the else.

You can use something like this, you do not need static List but the method has to be static as answered by Kent,
public static ClassA getClassAByCDValue(String cdValue)
{
for(ClassA value: ClassA.values())
{
if(value.cdValue.contains(cdValue))
{
return value;
}
}
return null;
}
public static boolean isCDValue(String cdValue)
{
for(ClassA value: ClassA.values())
{
if(value.cdValue.contains(cdValue))
{
return true;
}
}
return false;
}
Using above will be more appropriate as you just have to take care with adding/removing items in enum.

Related

How to access an object (already cast as its parent) as its actual object without reflection?

How do I access the property of a child class instead of the abstract class, when handling objects by their parent/abstract class? Like in this example:
public class WordCategories {
public static abstract class Noun {
public static final String TYPE = null;
//... and so on, methods
}
public static class Person extends Noun {
public static final String TYPE = "Person";
// ...
}
}
/* ... then we build a collection with members like: */
nouns.add(new WordCategories.Person("Bill Clinton");
/* now later we need to access a mixed list of nouns: */
for(WordCategories.Noun n: nouns) {
if(n.TYPE.equals("Person") ){ // this is always null
}
Obviously I could just specify (WordCategories.Person) n but that assumes that it is a Person. I need the cast to come from the parent class, and it would be most elegant if it did not involve interpreting the TYPE constant or the use of reflection, for that matter.
You don't have to use reflection at all. If you understand what type it is you like, you can use instanceof to get the specific class instance you care about.
for(WordCategories.Noun n: nouns) {
if(n instanceof WordCategories.Person) {
// cast to WordCategories.Person and perform whatever action you like
WordCategoriesPerson actualPerson = (WordCategories.Person) n;
}
}
This trumps the usage of the field to determine the object type, since the class contains enough metadata for you to want to use in this scenario. While many people would also discourage the use of instanceof due to performance (and frankly, if you wanted a list containing WordCategories.Person, just ask for one), its use in this instance would be cleaner than forcing each child class of WordCategories.Noun to create a method to inform us of what type it is.
static fields are always looked up by static type, so it doesn't matter what you assign to n; n.TYPE will always be WordCategories.Noun.TYPE. Heck, n could even be null:
System.out.println(((WordCategories.Noun) null).TYPE); // Doesn't cause an exception.
There is no way to get n.TYPE to behave the way you want with a static TYPE field. You will need to either make it non-static (and make all your objects bigger in the process), or you will need to change the way you access this data.
Instead of trying to access this through a static field, I recommend using an instance method:
public class WordCategories {
public static abstract class Noun {
public static final String TYPE = null;
public abstract String getType();
//... and so on, methods
}
public static class Person extends Noun {
public static final String TYPE = "Person";
public String getType() {
return TYPE;
}
// ...
}
}
...
for(WordCategories.Noun n: nouns) {
if(n.getType().equals("Person") ){
...
}
}
Try the test case:
public static void main(String[] args) {
Base sub1 = new Sub();
System.out.println(sub1.TYPE); // will print 'BASE'
Sub sub2 = new Sub();
System.out.println(sub2.TYPE); // will print 'SUB'
}
static class Base {
static String TYPE = "BASE";
}
static class Sub extends Base {
static String TYPE = "SUB";
}
If you access static field by the instance, it is decided by instance's declare Class, not the instance's real Class.
In your code for(WordCategories.Noun n: nouns) {, n's declare Class is Noun,so whatever n's real Class is,n.TYPE will only be null.
So, either use directly Class to access static fields, or use non-static field or method. Your usage is not wise, you should just take a different way.
Maybe you just need a non-static method:
public String getType() {
return TYPE;
}

How can I refer the objcet that calls a method in the method in Java? [duplicate]

This question already has answers here:
When should I use "this" in a class?
(17 answers)
Closed 7 years ago.
I'm trying to get an understanding of what the the java keyword this actually does.
I've been reading Sun's documentation but I'm still fuzzy on what this actually does.
The this keyword is a reference to the current object.
class Foo
{
private int bar;
public Foo(int bar)
{
// the "this" keyword allows you to specify that
// you mean "this type" and reference the members
// of this type - in this instance it is allowing
// you to disambiguate between the private member
// "bar" and the parameter "bar" passed into the
// constructor
this.bar = bar;
}
}
Another way to think about it is that the this keyword is like a personal pronoun that you use to reference yourself. Other languages have different words for the same concept. VB uses Me and the Python convention (as Python does not use a keyword, simply an implicit parameter to each method) is to use self.
If you were to reference objects that are intrinsically yours you would say something like this:
My arm or my leg
Think of this as just a way for a type to say "my". So a psuedocode representation would look like this:
class Foo
{
private int bar;
public Foo(int bar)
{
my.bar = bar;
}
}
The keyword this can mean different things in different contexts, that's probably the source of your confusion.
It can be used as a object reference which refers to the instance the current method was called on: return this;
It can be used as a object reference which refers to the instance the current constructor is creating, e.g. to access hidden fields:
MyClass(String name)
{
this.name = name;
}
It can be used to invoke a different constructor of a a class from within a constructor:
MyClass()
{
this("default name");
}
It can be used to access enclosing instances from within a nested class:
public class MyClass
{
String name;
public class MyClass
{
String name;
public String getOuterName()
{
return MyClass.this.name;
}
}
}
"this" is a reference to the current object.
See details here
The keyword this is a reference to the current object. It's best explained with the following piece of code:
public class MyClass {
public void testingThis()
{
// You can access the stuff below by
// using this (although this is not mandatory)
System.out.println(this.myInt);
System.out.println(this.myStringMethod());
// Will print out:
// 100
// Hello World
}
int myInt = 100;
string myStringMethod()
{
return "Hello World";
}
}
It's not used a lot unless you have code standard at your place telling you to use the this keyword. There is one common use for it, and that's if you follow a code convention where you have parameter names that are the same as your class attributes:
public class ProperExample {
private int numberOfExamples;
public ProperExample(int numberOfExamples)
{
this.numberOfExamples = numberOfExamples;
}
}
One proper use of the this keyword is to chain constructors (making constructing object consistent throughout constructors):
public class Square {
public Square()
{
this(0, 0);
}
public Square(int x_and_y)
{
this(x_and_y, x_and_y);
}
public Square(int x, int y)
{
// finally do something with x and y
}
}
This keyword works the same way in e.g. C#.
An even better use of this
public class Blah implements Foo {
public Foo getFoo() {
return this;
}
}
It allows you to specifically "this" object in the current context. Another example:
public class Blah {
public void process(Foo foo) {
foo.setBar(this);
}
}
How else could you do these operations.
"this" keyword refers to current object due to which the method is under execution. It is also used to avoid ambiguity between local variable passed as a argument in a method and instance variable whenever instance variable and local variable has a same name.
Example ::
public class ThisDemo1
{
public static void main(String[] args)
{
A a1=new A(4,5);
}
}
class A
{
int num1;
int num2;
A(int num1)
{
this.num1=num1; //here "this" refers to instance variable num1.
//"this" avoids ambigutiy between local variable "num1" & instance variable "num1"
System.out.println("num1 :: "+(this.num1));
}
A(int num, int num2)
{
this(num); //here "this" calls 1 argument constructor within the same class.
this.num2=num2;
System.out.println("num2 :: "+(this.num2));
//Above line prints value of the instance variable num2.
}
}
The keyword 'this' refers to the current object's context. In many cases (as Andrew points out), you'll use an explicit this to make it clear that you're referring to the current object.
Also, from 'this and super':
*There are other uses for this. Sometimes, when you are writing an instance method, you need to pass the object that contains the method to a subroutine, as an actual parameter. In that case, you can use this as the actual parameter. For example, if you wanted to print out a string representation of the object, you could say "System.out.println(this);". Or you could assign the value of this to another variable in an assignment statement.
In fact, you can do anything with this that you could do with any other variable, except change its value.*
That site also refers to the related concept of 'super', which may prove to be helpful in understanding how these work with inheritance.
It's a reference of actual instance of a class inside a method of the same class.
coding
public class A{
int attr=10;
public int calc(){
return this.getA()+10;
}
/**
*get and set
**/
}//end class A
In calc() body, the software runs a method inside the object allocated currently.
How it's possible that the behaviour of the object can see itself? With the this keyword, exactly.
Really, the this keyword not requires a obligatory use (as super) because the JVM knows where call a method in the memory area, but in my opinion this make the code more readeable.
It can be also a way to access information on the current context.
For example:
public class OuterClass
{
public static void main(String[] args)
{
OuterClass oc = new OuterClass();
}
OuterClass()
{
InnerClass ic = new InnerClass(this);
}
class InnerClass
{
InnerClass(OuterClass oc)
{
System.out.println("Enclosing class: " + oc + " / " + oc.getClass());
System.out.println("This class: " + this + " / " + this.getClass());
System.out.println("Parent of this class: " + this.getClass().getEnclosingClass());
System.out.println("Other way to parent: " + OuterClass.this);
}
}
}
Think of it in terms of english, "this object" is the object you currently have.
WindowMaker foo = new WindowMaker(this);
For example, you are currently inside a class that extends from the JFrame and you want to pass a reference to the WindowMaker object for the JFrame so it can interact with the JFrame. You can pass a reference to the JFrame, by passing its reference to the object which is called "this".
Every object can access a reference to itself with keyword this (sometimes called the this
reference).
First lets take a look on code
public class Employee {
private int empId;
private String name;
public int getEmpId() {
return this.empId;
}
public String getName() {
return this.name;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public void setName(String name) {
this.name = name;
}
}
In the above method getName() return instance variable name.
Now lets take another look of similar code is
public class Employee {
private int empId;
private String name;
public int getEmpId() {
return this.empId;
}
public String getName() {
String name="Yasir Shabbir";
return name;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public void setName(String name) {
this.name = name;
}
public static void main(String []args){
Employee e=new Employee();
e.setName("Programmer of UOS");
System.out.println(e.getName());
}
}
Output
Yasir Shabbir
this operator always work with instance variable(Belong to Object)
not any class variable(Belong to Class)
this always refer to class non static attribute not any other parameter or local variable.
this always use in non static method
this operator cannot work on static variable(Class variable)
**NOTE:**It’s often a logic error when a method contains a parameter or local variable that has the
same name as a field of the class. In this case, use reference this if you wish to access the
field of the class—otherwise, the method parameter or local variable will be referenced.
What 'this' does is very simply. It holds the reference of current
object.
This keyword holds the reference of instance of current class
This keyword can not be used inside static function or static blocks
This keyword can be used to access shadowed variable of instance
This keyword can be used to pass current object as parameter in function calls
This keyword can be used to create constructor chain
Source: http://javaandme.com/core-java/this-word

Identifying the specific enum within the constructor

public enum Batman
{
Rat, Cat, Bat;
private boolean isMatch;
// Constructor
Batman()
{
this.isMatch = (this.compareTo(Bat) == 0) ? true : false;
}
public boolean isMatch()
{
return this.isMatch;
}
}
For the constructor line I get the error:
Cannot refer to the static enum field Batman.Bat within an initializer
I am primarily trying to figure out if the specific ENUM can be identified in the constructor.
Also the reason I am thinking of saving the "isMatch" value, is that I don't want to evaluate what it should be every time.
I know form the very beginning, so I just want to save the value, and thus when a call is made it is not an evaluation
but simply passing the value back
I know there are other ways to solve this:
Modify the constructor to accept parameter:
Rat(false), Cat(false), Bat(true);
// Constructor
Batman(boolean isMatch)
{
this.isMatch = isMatch;
}
Change isMatch()
public boolean isMatch()
{
return (this.compareTo(Bat) == 0) ? true : false;
}
Any advice would be great.
Thanks
As others have said, you can not reference a specific Enum value in the constructor. The obvious solution would be to write this:
public enum Batman
{
Rat, Cat, Bat;
public boolean isMatch()
{
return this == Bat;
}
}
(BTW, you don't need equals with Enum)
But if the evaluation this == Bat really bothers you, you can override isMatch for Bat:
public enum Batman
{
Rat, Cat,
Bat {
#Override
public boolean isMatch() {
return true;
}
};
public boolean isMatch()
{
return false;
}
}
This way, you have no comparison, instead you use methods overrided by enum values.
And a variation on this, just for the fun:
public enum Batman
{
Rat, Cat,
Bat {{
this.isMatch = true;
}};
protected boolean isMatch = false;
public boolean isMatch()
{
return isMatch;
}
}
(note the notation{{ }} and the fact that isMatch must be protected instead of private so the Bat instance can access it.)
From Book Effective Java:
Enum constructors aren’t permitted to access the enum’s static fields,
except for compile-time constant fields. This restriction is necessary
because these static fields have not yet been initialized when the
constructors run.
You definitely can't reference any specific ENUM in the constructor, since it needs to be created when you want to refernece it and you are just creating it!
I would go with option 1, as you make the particular knowledge you rely on external to the internal implementation of the enum itself.

Let a constructor access a static variable

Right now I have two .java files.
The Main.java:
public class Main {
static int integer = 15;
NeedInteger need = new NeedInteger();
}
and the NeedInteger.java
public class NeedInteger {
System.out.println(integer);
}
This is of course very simplified, but is there any way I can accomplish this?
As many have answered, the correct method is to pass the value in to the constructor of the new class.
If for some reason you cannot do that, then you can use a public static accessor method in Main to access the value (this would be slightly better than just making the field public).
E.g.
public class Main
{
private static int integer = 15;
public static int getInteger()
{
return integer;
}
}
public class NeedInteger
{
public NeedInteger()
{
int integer = Main.getInteger();
}
}
Add a constructor to NeedInteger (and optionally a member if you need to also store it):
public class NeedInteger {
private int integer;
public NeedInteger(int integer) {
this.integer = integer;
System.out.println(integer);
}
}
Then pass your value when you create the instance:
public class Main {
static int integer = 15;
NeedInteger need = new NeedInteger(integer);
}
You would have to do some bad juju moves (like using a global variable) or pass it to the constructor.
NOTE: your
public class NeedInteger {
System.out.println(integer);
}
has no method in it. I would recommend all this to be rewritten as such:
public Class NeedInteger {
NeedInteger(int integer) {
System.out.println(integer);
}
}
If you really want the work to be done on construction.
EDIT: From your comment above.
Instead, have the class structured so:
public Class NeedStringArray {
NeedStringArray(String[][][] stringArr) {
//work with String array here
}
}
That has no real additional overhead, since the actual array will not be passed, but only a reference to it. You WILL likely want to set the array to be final or something, to avoid it being edited in the NeedStringArray constructors.
integer is private, so it cannot be accessed by NeedInteger. you'll have to make it public or use a setter or getter and you'll need to use Main.integer since it's static.
Generally, you set in the Constructor.
Pass in the variable to the class constructor.
An array reference would be just that--a reference.
Or you could pass in the class itself, or use a static (meh).
Per your comment I'd say you can either host your array in a singleton
or as others suggested have the second class accept the reference to the array in the constructor. You can then use Dependency Injection framework (e.g. Guice) to get wire them up

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