Java - When member variable is set, how to set other members - java

I have the following legacy code as shown below. I'm wondering is there a way to set BikeName and BikeModel when BikeGroup is being set? Basically, as the user is setting BikeGroup, how can we automatically set Foo's version of BikeName and BikeModel? Without using a constructor to set values. I'm setting the BikeGroup using a Validator (spring framework)... so I cannot use a constructor or setter to set the values.
Class Foo{
private BikeGroup; // 1. when this is set
private String bikeName; // 2. set this with value in BikeGroup
private String bikeModel; // 3. and set this with value in BikeGroup
//getters/setters
}
Class BikeGroup{
private String bikeName;
private String bikeModel;
//getters/setters
}

Yes. But, the constructor for Foo must be named Foo (and you want to pass a BikeGroup to that constructor, so it needs a parameter). And you don't put () at class declaration. Something like,
class Foo {
public Foo(BikeGroup bg) {
this.bikeName = bg.getBikeName();
this.bikeModel = bg.getBikeModel();
}
private String bikeName;
private String bikeModel;
}
Or, using a setter...
class Foo {
public void setBikeGroup(BikeGroup bg) {
this.bikeName = bg.getBikeName();
this.bikeModel = bg.getBikeModel();
}
private String bikeName;
private String bikeModel;
}

Related

How to get all field's title of object

I need to write a method. The meaning is to send any object(Entity etc) as parameter and get all fields names as return values. Something like that.
Example of method
public String getFieldsTitle(Object obj){
return obj.getListOfFields();
}
Entity for example:
public class Human{
private String name;
private String fam;
private String patr;
}
Expectation value of method
[name,fam,patr]
You can return a list of List<String> from your getFieldsTitle method and then print the list.
Using Java 8
public static List<String> getFieldsTitle(Object obj){
return Arrays.stream(obj.getClass().getDeclaredFields())
.map(Field::getName)
.collect(Collectors.toList());
}
There are two methods for this
// returns inherited members but not private members.
Field[] fields = ClassName.class.getFields();
// returns all members including private members but not inherited members.
Field[] fields = ClassName.class.getDeclaredFields();
See oracle docs of classMembers for more details.

Kotlin - How can we access private property with getter and setter? Is access methods are calling internally? [duplicate]

This question already has answers here:
Getters and Setters in Kotlin
(8 answers)
Closed 4 years ago.
class Sample1 {
private var test = ""
get() = field
set(value) {
field = value
}}
This is my class. I want to keep the property as private and have to access the property through getter and setter.
var sample1 = Sample1()
I tried to create an object and access the property, but fails.
When I go through the docs, I could found one interesting thing,
"Getters always have the same visibility as the property". link
What's the correct approach with kotlin?
Kotlin groups a field, its getter and its setter (if applicable) into the single concept of a property. When you're accessing a property, you're always calling its getter and setter, just with a simpler syntax, which happens to be the same as for accessing fields in Java. But the actual field backing the property is private, and all calls go through the getters and setters, which have the same visibility as the property itself, in your case, private. So your class would translate to this:
public final class Sample1 {
private String test = "";
private String getTest() { return test; }
private void setTest(String test) { this.test = test; }
}
And your call to Sample1().text would look like this in Java (and you can actually do this from Java code that calls this Kotlin class):
new Sample1().getText();
All that to say is that the solution is to change the visibility of the property to whatever you'd set the getter and setter visibilities to in Java, for example, to the default public visibility:
class Sample1 {
var test = ""
get() = field
set(value) {
field = value
}
}
Note that if you don't have an explicit getter and setter declared, you'll get ones automatically which do the same thing as the implementations above, so you can shorten your code to this:
class Sample1 {
var test = ""
}
This final code is equivalent to this Java class:
public final class Sample1 {
private String test = "";
public String getTest() { return test; }
public void setTest(String test) { this.test = test; }
}

How to access a value of a private instance variable from a different class?

I am creating a simple GUI game (number guessing) in Java.
Apparently, I have a button called Give Up.
When I click the Give Up button, I want to display the answer on a textarea.
However, the targetNumber variable is declared as private:
public class GameUtility {
private String targetNumber = "2543";
//rest of the code
}
class GiveUpButton implements ActionListener { //Inner class
public void actionPerformed(ActionEvent gEvent) {
GameUtility utility = new GameUtility();
textArea.append(utility.targetNumber); //How to access the value of targetNumber?
}
}
How can I access a value of a private variable?
To make the state of the managed bean accessible, you need to add setter and getter methods for that state.
Once the setter and getter (accessor) methods have been added, you can update and access the value of the private instance. The code should look like the following example:
public class AccessorExample {
private String attribute;
public String getAttribute() {
return attribute;
}
public void setAttribute(String attribute) {
this.attribute = attribute;
}
}
Letting access the information inside the private instance from outside of the class, only if they ask through a provided mechanism we will call method. The mechanisms for asking an object to reveal information about itself we can call the getter method (e.g. accessorExample.getAttribute();).
The private modifier implies that you don't have access to the property directly. But perhaps more importantly, private implies that you shouldn't have access to the property directly. Create a getter for providing access to external classes:
public class GameUtility {
private String targetNumber = "2543";
public String getTargetNumber() {
return targetNumber;
}
//rest of the code
}
class GiveUpButton implements ActionListener {
public void actionPerformed(ActionEvent gEvent) {
GameUtility utility = new GameUtility();
textArea.append(utility.getTargetNumber());
}
}
See also: Java Documentation on Access Control
The recommended way is to create appropriate Getters and Setters.
See this post to get more insights as how do getters and setters work?
public class AccessorExample {
private String attribute;
public String getAttribute() {
return attribute;
}
public void setAttribute(String attribute) {
this.attribute = attribute;
}
}
Most of the IDEs provide support to directly generate getters and setters.
Generate Getters and setters in Netbeans.
Generate Getters and setters in Eclipse.

Need to pass multiple (20+) parameters in a Java method. Any efficient way of doing this?

I have multiple methods in a Java class where every method has 20+ parameters. I will create an object for this class in another class and call each and every method. Typically I'm using the POM (Page Object Model) in Selenium Java.
So in every Page object class, there are multiple(20+) parameters in every method, which I will call in the Test Class.
Page Object Class :
public void enterShipInfo(String IMO,String Vstat,String Vcode,String Vname,
String Vtype,String Officialno,String Buildyr,String Shipyard,String Hullno,String Layingdate,
String Launcheddate,String Deliverdate,String Reportinclude,String Portregistry,String VFlag,
String Vstatus,String Classification,String Classid,String Classnotation,String PI,String HM,
String Regowner,String Shipmanager,String Comoperator,String Callsign,String SSR,String Factor,
String ELOG,String Vcomments,String VsisIMO,String Chartertype,String Showonweb){
}
.... Other Methods with similar long list of parameters
Then in Test Class, again I'm creating parameters for these:
public class VesTest {
#Test(dataProvider="Ves",priority=1)
public void createVesTest(String IMO,String Vstat,String Vcode,String Vname,
String Vtype,String Officialno,String Buildyr,String Shipyard,String Hullno,String Layingdate,
String Launcheddate,String Deliverdate,String Reportinclude,String Portregistry,String VFlag,
String Vstatus,String Classification,String Classid,String Classnotation,String PI,String HM,
String Regowner,String Shipmanager,String Comoperator,String Callsign,String SSR,String Factor,
String ELOG,String Vcomments,String VsisIMO,String Chartertype,String Showonweb
Mdr_Vessel obj_Mdr_Vessel = page(Mdr_Vessel.class);
obj_Mdr_Vessel.clickSubmenu();
.....
}
Any efficient way to reduce typing the parameters again in Test Class???
I don't want to break the method into multiple methods. So please suggest me a way of passing parameters in an efficient way
You can create new objects to group your parameters and then use them in your method signature.
For example :
public class VParameter {
String Vstat;
String Vcode;
String Vname;
String Vtyp;
I don't know if this counts as "breaking up the method into multiple methods", but what you can do is collect the parameters in a single object. Then for example
void method(Type1 parameter1, Type2 parameter2, Type3 parameter3) { ... }
becomes:
public class Parameters {
private Type1 parameter1;
private Type2 parameter2;
private Type3 parameter3;
// getters and setters
}
void method(Parameters params) { ... }
This kind of pattern is often used in a fluent style:
public class Parameters {
private Type1 parameter1 = /* convenient default value */;
private Type2 parameter2 = /* convenient default value */;
private Type3 parameter3 = /* convenient default value */;
public Parameters setParameter1(Type1 parameter1) {
this.parameter1 = parameter1;
return this;
}
// other setters in the same style and getters
}
Then you can call your method like:
method(new Parameters().setParameter1(...).setParameter3(...));
(where you only set the parameters with non-default values).
Can you create a class to regroup all parameters ?
You should read about the Prameter object patter which deals with that type of problem. In brief, it suggests you to crate a wrapper object for all parameters that the method accepts and use it instead the long list of arguments.
public class YourClassName {
private String IMO;
private String Vstat;
private String Vcode;
// other parameters
public YourClassName(String IMO, String Vstat, String Vcode, /* other params*/) {
this.IMO = IMO;
this.Vstat = Vstat;
this.Vcode = Vcode;
// assign other params
}
/getters
}
You can use the builder factory pattern https://jlordiales.wordpress.com/2012/12/13/the-builder-pattern-in-practice/

Assign each enum instance a growing ID

I'm just starting my first steps with Java, learned all the basics but then found a problem with an enum I need, so forgive me, if the solution to my problem is something very obvious:
So I've got this enum and want to add a unique id to each instance counting from 0 upwards, but without having to add another parameter to each constructor calling (because this can later on lead to errors ofc).
public enum TerrainTile{
WATER(1), GRASSLAND(1), HILL(2), FORREST(2), BLANK(99);
private final int id;
private final int moveCost;
private boolean hidden = true;
private TerrainTile(int moveCost) {
this.moveCost = moveCost;
}
And I thought to just add a
static int nextID = 0;
and edit the constructor to
private TerrainTile(int moveCost) {
this.id = nextID++;
this.moveCost = moveCost;
}
But I get an error message that it can not refer to a static field inside the initializer.
Is there any workaround?
You can use the ordinal() method for it. It is based on the order in which the members are declared in the source-code and counted from zero. So I guess, exactly what you need.
Just a note:
You can get your original enum member from ordinal number by calling .values()[index]
example:
int hillOrdinal = TerrainTile.HILL.ordinal(); // 2
TerrainTile hill = TerrainTile.values()[hillOrdinal];
It sounds like you are trying to combine class features into an enum. I'd be particularly wary of non-final, non-static member fields in an enum declaration. The behaviour you want seems to be best served by using a TerrainTile class (possibly a flyweight if you truly want the single-instance-per-type behaviour) and a TerrainTileType (or TerrainTile.Type) enum. Something like this:
public class TerrainTile {
public enum Type {
WATER(1), GRASSLAND(1), HILL(2), FORREST(2), BLANK(-1);
public final int MOVE_COST;
private TerrainTile(int moveCost) {
this.MOVE_COST = moveCost;
}
public boolean isTraversable() {
return (MOVE_COST > 0);
}
}
private final Type type;
private final Image texture;
...
private TerrainTile(Type type) {
this.type = type;
}
private static final Map<Type, TerrainTile> tiles = new EnumMap<>();
static {
// instantiate one TerrainTile for each type and store into the tiles Map
for (Type type: Type.values()) {
// Eventually, also load tile textures or set Color in this step
tiles.put(type, new TerrainTile(type));
}
}
public static TerrainTile getTile(Type type) {
// return the reference to the TerrainTile of this type
return tiles.get(type);
}
...
}

Categories

Resources