I have the following class that is created with the usage of a builder:
public class Foo {
private String name;
private int age;
public String getName() { return name; }
public int getAge() { return age; }
private Foo(Builder b) {
name = b.name;
age = b.age;
}
public static final class Builder {
private String name;
private int age;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
}
}
Now I want to add a JUnit test for this where if this class were to change (via new field were to be added, some other changes made to this) that would also be reflected once the class got serialized, I want that test to fail to catch that change. I am not aware of any libraries that can do this, how can this be done?
Related
I am using Jackson to save my java object (Person.class) as a json file and load from it using jackson as well.
This is what I am saving at the moment:
public class Person {
private String name;
private int yearOfBirth;
public Person(String name, int yearOfBirth) {
this.name = name;
this.yearOfBirth = yearOfBirth;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getYearOfBirth() {
return yearOfBirth
}
public void setYearOfBirth(int yearOfBirth) {
this.yearOfBirth = yearOfBirth;
}
}
Even though a person's name (in this case) CANNOT be changed, nor can their year of birth, I have to have the getters and setters for Jackson to recognise the values otherwise it will give an exception:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "name"
How can i make my fields name and yearOfBirth (without making them PUBLIC ofcourse) final fields uneditable after initialisation.
This is my saving and loading using jackson:
saving:
public void savePerson(File f, Person cache) {
ObjectMapper saveMapper = new ObjectMapper()
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
saveMapper.setVisibilityChecker(
saveMapper.getSerializationConfig().
getDefaultVisibilityChecker().
withFieldVisibility(JsonAutoDetect.Visibility.ANY).
withGetterVisibility(JsonAutoDetect.Visibility.NONE).
withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)
);
ObjectWriter writer = saveMapper.writer().withDefaultPrettyPrinter();
writer.writeValue(f, cache);
}
loading:
public Person load(File f) {
return new ObjectMapper().readValue(f, Person.class);
}
User #JsonProperty and it will work.
import com.fasterxml.jackson.annotation.JsonProperty;
public class Person {
private final String name;
private final int yearOfBirth;
public Person(#JsonProperty("name") String name, #JsonProperty("yearOfBirth") int yearOfBirth) {
this.name = name;
this.yearOfBirth = yearOfBirth;
}
public String getName() {
return name;
}
public int getYearOfBirth() {
return yearOfBirth;
}
}
I have an abstract class which contains a variable 'name' that I want my child classes to initialize. Which of these would be the best way to do so.
Option 1. Use superclass constructor for initialization
#Getter
abstract class A {
private final String name;
protected A(String name) {
this.name = name;
}
}
class B extends A {
private static final NAME = "Raylan";
private final int age;
public B(int age) {
super(NAME);
this.age = age;
}
}
Option 2. Use a getter method.
abstract class A {
private final String name;
public abstract String getName();
}
class B extends A {
private static final NAME = "Raylan";
private final int age;
public B(int age) {
this.age = age;
}
#Override
public String getName() {
return NAME;
}
}
Having a private name in A without a way to access it is useless. Assuming a fully functional getName() in A, consider multiple constructors in B:
class B extends A {
private static final String NAME = "Raylan";
private final int age;
public B(String name, int age) {
super(name);
this.age = age;
}
public B(int age) {
this(NAME, age);
}
public int getAge() {
return age;
}
}
This allows re-use of A, otherwise there doesn't seem much point in B extending A. Composition, instead of inheritance, could be another option.
I want to use a generic setter method which will take Object as argument and inside the setter I'll set the value of the property. For example, in place of
public class Student {
private Long id;
private String name;
private int age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
I want to use this :
public class Student {
private Long id;
private String name;
private int age;
public Long getId() {
return id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setValues(Object propertyValue) {
if(propertyValue instanceof Long){
this.id = (Long) propertyValue;
}else if(propertyValue instanceof String){
this.name = (String) propertyValue;
}else if(propertyValue instanceof Integer){
this.age = (Integer) propertyValue;
}
}
}
Note: In my POJO, all the property have unique type (No duplicate type for multiple properties).
For one, casting should always be avoided.
Second it's slower than having setters (no need to check instanceof)
Third it's even taking up more memory! You use 10 lines to replace 3 setters which would require only 9 lines :P
Fourth it's very ugly! But hey, that's just my opinion
Fifth it's not flexible, if you add anything to your pojo, you have to carefully add the check or maybe even revert to setters anyway
Sometimes it serializes without annotations in xml and the other times it doesnt?Someone please enlighten me regarding the necessity of Annotations.
#XmlRootElement
public class Test {
public void setAge(int age) {
this.age = age;
}
private int age;
private String name;
private Cat cat;
public Test()
{
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
}
class Cat
{
private String name="catttttttttttttttt";
public Cat()
{
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
In the above code,it works fine,but sometimes if dont add #XMLElement above the getCat(),it doesnt serialize.
I googled through some sites and got the best explanation here:
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
Its not required to put annotations and it depends completely on #XmlAccessorType.
Thanq
public class MainClass {
public static void main(String[] args) throws Exception {
JAXBContext contextObj = JAXBContext.newInstance(Test.class);
Marshaller marshallerObj = contextObj.createMarshaller();
marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Test test = new Test();test.setAge(25);test.setName("Sriharsha");test.setCat(new Cat());
marshallerObj.marshal(test, new FileOutputStream("/home/pankaj/Downloads/Emp.xml"));
System.out.println();
}
}
I have a class which is identical to enum. The only difference is that I create the class so that I can dynamically create the enums. What I want is to override the cast operation of enum so that I can give the enum instance to a method where it gets the class instance.
Example:
public enum SpecialEnum {
FIRST("First"), SECOND("Second");
private String name;
SpecialEnum(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class SpecialClass {
private String name;
public SpecialClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public void displayName(SpecialClass specialClass) {
System.out.println(specialClass.getName());
}
Lets say that the SpecialClass instances are coming from a server where I display them. But I also want to use my pre-defined Special enum classes as well. I know that I could create static instances of SpecialClass and use them but not that it looks messy, also using enums are beneficial to my occasion as well. Is there a way to override casting operation of the enum class of a work around maybe?
Extract an interface:
public interface Named {
public String getName();
}
public class SpecialClass implements Named {
private String name;
public SpecialClass(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
public enum SpecialEnum implements Named {
FIRST("First"), SECOND("Second");
private String name;
SpecialEnum(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
public void displayName(Named specialClass) {
System.out.println(specialClass.getName());
}