Eclipse, short way to initialize object via setters - java

For example I have the following object:
public class Dog{
private String name;
private int age;
private int legs;
private Color color;
/*getters and setters*/
}
And I want to initialize it and set all properties not by constructor but by using setters:
Dog dog = new Dog();
dog.setName("Rex");;
dog.setAge(4);
...
Can I generate code which set all fields from above in the easy way?

It's cumbersome, but what I do:
Use Eclipse's Source -> Generate Getters and Setters... function (also ALT + SHIFT + S) and then just replace all '=' characters with '(' and ';' with ');'. finally I go through every line and press ctrl-space to let Eclipse finish the method call with proper casing (configure Eclipse to overwrite instead of insert code assist suggestions).
That or do a regex replacement if it is a lot.

You can introduce a setAllValues method, that should take all the attributes of your class as parameters. And simply call the setters inside that method.

You can create a new template in eclipse in Preferences/Java/Editor/Templates and then just use it (similar to 'syso' ctrl+space that produces System.out.println)

Related

Java helper class to dynamically create member variables and getter methods

I am trying to create a helper method that will take in the names (type String) of the member variables (could be any number of member variables) and automatically initialize/create the member variables as well as the getter methods. So I would call something like:
helperClass("hello", "myName", "is", "bob")
and the helperClass would look something like this:
public class helperClass {
helperClass(String ...a) {
for (String s: a)
//create member variables and getter methods dynamically
}
So, in the end, the caller of the function would have something like this:
public class helperClass {
private String hello
private String myName
private String is
private String bob
//getter methods below
...
}
Coming from Python so wasn't sure if this type of stuff is doable in Java.
Yes. You can create the getter and setter methods dynamically.
Tutorial for Java Dynamic POJO creation . But this method will involve you creating a predefined string which contains the method declaration.
Eg :
String s= "public void doSonething(String ... args){ // Function Body }" .
You can then convert this string into a function at runtime. Based on your need, you can define a custom string that contains the method declaration which you need. See some examples in the above tutorial link I have attached.
i think the answer is to use an IDE. They all have "add property" functions which will generate the declaration and appropriately named getters and setters.
Should you prefer to manually enter your properties, They all also have generate getter/setter functions which will look at the properties you have entered (work out which getters and setters are missing) and offer to create approporiately named getters and setters in bulk for the ones you've selected.
To answer your specific question, yes you can write your own class that takes a list of strings (i.e. property names) and print them out as a series of getters and setters, this is basic string concatenation:
private String generateGetter(String propName) {
return String.format(" public String get%s()\n return this.%s;\n }", StringUtils.capitalize(propName), propName);
}
To convert the first letter of the propName to upper case (the convention for getter and setter methods, you can do it yourself or use apache's string utils.

Mockito when checking for specific object property value

I have the following in a working test:
when(client.callApi(anyString(), isA(Office.class))).thenReturn(responseOne);
Note that client is a Mock of class Client.
I want to change "isA(Office.class)" to tell it to match where the "id" property of an Office instance is "123L". How can I specify that I want a specific argument value in the method of a mocked object?
Edit: Not a duplicate because I'm trying to use it on a "when" and the linked question (and other resources I've found) are using ArgumentCaptor and ArgumentMatcher on "verify" and "assert". I'm thinking I can't actually do what I'm trying and will try out another way. Of course, I'm willing to be shown otherwise.
Reopening as requested, but the solution (use an ArgumentMatcher) is identical to the one in the linked answer. Naturally, you can't use an ArgumentCaptor when stubbing, but everything else is the same.
class OfficeWithId implements ArgumentMatcher<Office> {
long id;
OfficeWithId(long id) {
this.id = id;
}
#Override public boolean matches(Office office) {
return office.id == id;
}
#Override public String toString() {
return "[Office with id " + id + "]";
}
}
when(client.callApi(anyString(), argThat(new IsOfficeWithId(123L)))
.thenReturn(responseOne);
Because ArgumentMatcher has a single method, you can even make it a lambda in Java 8:
when(client.callApi(anyString(), argThat(office -> office.id == 123L))
.thenReturn(responseOne);
If you're already using Hamcrest, you can adapt a Hamcrest matcher using MockitoHamcrest.argThat, or use the built-in hasProperty:
when(client.callApi(
anyString(),
MockitoHamcrest.argThat(
hasProperty("id", equalTo(123L)))))
.thenReturn(responseOne);
I ended up going with "eq". This was ok in this case because the objects are pretty simple. First I created an object that is the same as what I expect to get back.
Office officeExpected = new Office();
officeExpected.setId(22L);
Then my 'when' statement becomes:
when(client.callApi(anyString(), eq(officeExpected))).thenReturn(responseOne);
This allows me to have better checking than "isA(Office.class)".
adding an answer for anyone with a more complex object.
answer from OP uses eq which works for simple objects.
However, I had a more complex object with many more fields. Its quite painful to create Mock object and fill in all the fields
public class CreateTenantRequest {
#NotBlank private String id;
#NotBlank private String a;
#NotBlank private String b;
...
...
}
I was able to use refEq to achieve the same thing without setting a value of each field.
Office officeExpected = new Office();
officeExpected.setId(22L);
verify(demoMock, Mockito.atLeastOnce()).foobarMethod(refEq(officeExpected, "a", "b"));

How to mass annotate constructor arguments?

I've got a problem where I want to make a lot of classes in our project de-serializable via jackson. The problem is that most of classes look like this:
public class FinalFieds{
private final String field;
private final String secondField;
public FinalFieds(String field, String secondField)
{
this.field = field;
this.secondField = secondField;
}
public String getField()
{
return field;
}
public String getSecondField()
{
return secondField;
}
}
So what I found is that in jackson you can do something like this:
public FinalFieds(#JsonProperty("field") String field, #JsonProperty("secondField") String secondField)
And that works nice. The problem is that I cannot make structural replace in intellij to work for me. When I try:
All my matches are in "Unclassified matches" section.
Furthermore when I try to replace, Intellij just removes a constructor from the class.
Any idea on what I'm doing wrong or is it a known bug in intellij?
Even an overcomplicated regex that will help me replace this (for single argument constructors I can create it myself; the problem is that our constructors in those classes have multi-argument constructors).
It's a bug or a missing feature depending on how you look at it.
https://youtrack.jetbrains.com/issue/IDEA-141143
However, it is possible to do it in two steps. First search for the constructor parameters you want to annotate:
class $Class$ implements OurCommonInterface {
$Class$($Type$ $parameter$);
}
where $parameter$ min: 1 max: unlimited, This variable is target of the search checked.
Then replace the parameter with an annotated parameter in scope Previous Search Results:
$Type$ $parameter$
Replacement template:
#JsonProperty("$parameter$") $Type$ $parameter$

Optional in Lombok

I have a class called Address which looks like this:
#Value
class Address {
#NotNull String userId;
#NotNull String line1;
String line2;
private Address(Builder b) {
// copy everything from builder
}
// override getter for line2 so that it returns Optional<String>
public Optional<String> getLine2() {
return Optional.ofNullable(this.line2);
}
// and a Builder
public static class Builder {
// builder methods
}
}
Here I am forced to write Builder and a Getter because, if I want to return an Optional while using Lombok, I will have to declare line2 as Optional<String>. And that will generate a builder method which accepts Optional<String>!
Is there any other way to use lombok with Optional?
The answer is no, and it probably never will.
You're probably doing it wrong :-) Optional is not a replacement for null nor a fancy way to prevent NullPointerException. It is to indicate that the question is unanswerable, like: what is the average age of an empty list of persons.
Optionals should never be passed on, but unboxed by the calling code as soon as possible.
See also https://www.voxxed.com/blog/2015/01/embracing-void-6-refined-tricks-dealing-nulls-java/
Since these scenarios are just a handful, and Lombok likes to enable programmers to write better code, I don't expect there will ever be support for it in Lombok.
Disclosure: I am a Lombok developer.

When should I override toString()?

I know that the Javadocs says:
Returns a string representation of the object. In general, the
toString method returns a string that "textually represents" this
object. The result should be a concise but informative representation
that is easy for a person to read. It is recommended that all
subclasses override this method.
But when should I spend time overriding the toString method for my classes? Should it be one of the first things I do along with overriding equals and hashCode? Or should I wait until it's actually needed?
I know Eclipse can auto generate toString methods for you, so should I just have Eclipse auto generate them once I know the fields for my class?
Josh Bloch gives a good explanation in Effective Java, in item 10.
[...] providing a good toString implementation makes your class much more pleasant to use.
It really makes it easier to output debugging traces, or makes better logging messages, since you can use the object's string representation provided by toString() directly; you don't have to manually build a string that gives the information needed on the object.
As stated in the book, you should include all the interesting information in the resulting String. You should also document properly your method; you may document the resulting String format or not, but you should at least document your intent (whether the format is subject to change, or not likely to change).
In the end, it is up to you (and your company's standards) to decide if overriding it in every class should be part of your habits or not. Personally, I don't override toString () in every classes, only in the ones which are most at risk of being used in a debuging trace.
I would implement toString() method on any class that holds human understandable non confidential data. Ex: Transfer Object, Beans, Data Object, Wrappers. For such classes just go on to implement 'toString()' method.
Classes that represent a service, process with transient states need not implement the method.Here, You can wait until it is actually needed.
Make sure you do not expose any variables with "transient" keyword in 'toString()'!
Typically, I override it when I want to assign a default format of displaying an object, often formatting a compact/digestable display of relevant attributes. So that I can simply, for example, display it in debug or log by doing:
MyClass myClsInst = new MyClass();
...
System.out.println(myClsInst);
In general, It's used to show or see what the object has.
For instance, Let's say there is a Student class and you created objects.
Student class has age, grade, gpa, name, country, address.
class Student{
private int age;
private int grade;
private double gpa;
private String name;
private String country;
private String address;
Student(...){
// ...
}
public String toString(){
String str = "age is "+age+ ", grade is " + grade + ...
return str;
}
}
And you created A student, and B student ( and maybe more )
You just need to 'toString()' for checking its inside like this:
System.out.println(aStudent.toString());
System.out.println(bStudent.toString());
or You can just write the object name, it automatically calls 'toString()'
System.out.println(aStudent);
System.out.println(bStudent);
It removes the redundant works & faster.
Then, you will see like this:
Output:
age is 13, grade is 3, ...
age is 15, grade is 5, ...
It's useful when you see what A student or B student has when you debug.
And also, It's useful when you make your own form like JSON.
It will be easier to manipulate its data with JSON format.
I am trying to demonstrate in simple way.
package com.web.doamin;
public class User {
String name;
long id;
/*#Override
public String toString() {
return "User [user = " + name + ", id="+ id + "]";
}*/
public static void main(String[] args) {
User user = new User();
System.out.println(" : user : " + user );
}
}
If we did't Override toString() method we will get Object Hash code in sysout
O/P without Override toString() method - com.web.doamin.User#7852e922
if We Override the ToString() method we will get O/P - User [user = null, id=0]
Note - It is a good idea to override toString() as we get get proper output when an object is used in System.out.println();

Categories

Resources