What are the correct rules to write a JavaBean class?
I'm confused because some books use MUST while other user SHOULD or COULD to describe
the writing rule:
i.e.
a bean class MUST implements Serializable or SHOULD?
the instance variables MUST be private or SHOULD BE?
A JavaBean is defined by its properties (i.e. its getter and setter methods), not it's fields. Although the terms are used interchangably, that is actually not correct. The Introspector mechanism ignores fields completely.
Example
Take this (awfully designed) Javabean:
public class TestBean {
private int baz;
private char[] phleem;
public String getFoo() {
return new String(phleem);
}
public void setFoo(final String foo) {
this.phleem = foo.toCharArray();
}
public long getBar() {
return baz;
}
public void setBar(final long bar) {
this.baz = (int) bar;
}
}
You'd think the properties are:
"baz" (int)
"phleem" (char[])
but now let's inspect it with the Javabeans introspector:
for (PropertyDescriptor descriptor : Introspector
.getBeanInfo(TestBean.class, Object.class)
.getPropertyDescriptors()) {
System.out.println("Name: " + descriptor.getName() +
", type: " + descriptor.getPropertyType());
}
Here's the output:
Name: bar, type: long
Name: foo, type: class java.lang.String
Conclusion:
Getters and setters are what define a Javabeans property. It's a convention that they are backed by fields of the same name and type, but the fields are not actually part of the Javabean properties (although many documentations will suggest otherwise).
On re-reading my answer: it is meant as an addendum to the other answers. If you want a short and simple answer, go with skaffman's.
It is a public class.
It has a public parameterless constructor (though it may have other constructors
as well)
It implements Serializable interface (i.e. it can be made persistent, so its state can
be saved)
It has properties with “getter” and “setter” methods named by following
JavaBeans naming patterns
It has events which follow the standard Java event model with the registration
methods named by following the JavaBeans naming patterns
It may have other methods which do not follow the naming patterns. These
methods are not exposed by a builder tool.
Adding to the previous poster - skaffman. It is always a good practice to override, toString(), hashCode(), equals() and finally write a overloaded constructor that has all the fields (that this class has) as input.
Be sure not to use other references (like List, HashMaps etc) in the toString() and hashCode()'s implementation.
On a side note, eclipse has built-in functionality to generate them for you..
A Java Bean is a Java class that should follow the following conventions:
It should have a no-arg constructor.
It should be Serializable.
It should provide methods to set and get the values of the properties, known as getter and setter methods.
All the above and it should not cross the boundaries of Java API . It means it should not extend or implement any classes or interface,but one relaxation is there it can implement only one serializable interfce why because it is a marker interface
Related
I have a model class which has around 45 properties. I have created another DTO class which has exactly the same properties.
At runtime, some requirements dont need me to show all the properties to the user. Hence i want to copy some properties from my model class to my DTO class and then send that object to the client.
I am using Spring.s BeanUtils.copyproperties. But here i only see the option to ignore properties which i dont want. as the my list of unwanted properties is long, is there a way in which i can specify only the list i want.
I searched on the net and found a solution
"org.springframework.beans.BeanUtils.copyProperties(Object source, Object target, Class editable) throws BeansException
Ensure the target implements the interface editable which defines the properties which would be copied."
But i am not able to work my head around this editable interface. I tried using an interface which has all the properties I want and tried to use it here, but it gave me an error saying that it is expecting a class. Can some body help me with the editable interface stuff
I think creating another DTO with just the properties you wanted will be a lot easier.
Instead of creating copies of the object containing only a few properties, you could define various Interfaces that provide only the getter methods to the properties that you want to expose to the consumer of your object. Your DTO can implement all the different interfaces. And you hand over the interface to the consumer instead of a concrete class.
public class MyDTO implements Fooable, Barable {
private String foo;
private String bar;
public String getFoo() {
return foo;
}
public String getBar() {
return bar;
}
}
public interface Fooable {
String getFoo();
}
public interface Barable {
String getBar();
}
We're trying to figure out a robust way of persisting enums using JPA. The common approach of using #Enumerated is not desirable, because it's too easy to break the mappings when refactoring. Each enum should have a separate database value that can be different than the enum name/order, so that you can safely change the name or internal ordering (e.g. the ordinal values) of the enum without breaking anything. E.g. this blog post has an example on how to achieve this, but we feel the suggested solution adds too much clutter to the code. We'd like to achieve a similar result by using the new AttributeConverter mechanism introduced in JPA 2.1. We have an interface that each enum should implement that defines a method for getting the value that is used to store the enum in the database. Example:
public interface PersistableEnum {
String getDatabaseValue();
}
...
public enum SomeEnum implements PersistableEnum {
FOO("foo"), BAR("bar");
private String databaseValue;
private SomeEnum(String databaseValue) {
this.databaseValue = databaseValue;
}
public void getDatabaseValue() {
return databaseValue;
}
}
We also have a base converter that has the logic for converting enums to Strings and vice versa, and separate concrete converter classes for each enum type (AFAIK, a fully generic enum converter is not possible to implement, this is also noted in this SO answer). The concrete converters then simply call the base class that does the conversion, like this:
public abstract class EnumConverter<E extends PersistableEnum> {
protected String toDatabaseValue(E value) {
// Do the conversion...
}
protected E toEntityAttribute(Class<E> enumClass, String value) {
// Do the conversion...
}
}
...
#Converter(autoApply = true)
public class SomeEnumConverter extends EnumConverter<SomeEnum>
implements AttributeConverter<SomeEnum, String> {
public String convertToDatabaseColumn(SomeEnum attribute) {
return toDatabaseValue(attribute);
}
public SomeEnum convertToEntityAttribute(String dbData) {
return toEntityAttribute(SomeEnum.class, dbData);
}
}
However, while this approach works very nicely in a technical sense, there's still a pretty nasty pitfall: Whenever someone creates a new enum class whose values need to be stored to the database, that person also needs to remember to make the new enum implement the PersistableEnum interface and write a converter class for it. Without this, the enum will get persisted without a problem, but the conversion will default to using #Enumerated(EnumType.ORDINAL), which is exactly what we want to avoid. How could we prevent this? Is there a way to make JPA (in our case, Hibernate) NOT default to any mapping, but e.g. throw an exception if no #Enumerated is defined on a field and no converter can be found for the type? Or could we create a "catch all" converter that is called for all enums that don't have their own specific converter class and always throw an exception from there? Or do we just have to suck it up and try to remember the additional steps each time?
You want to ensure that all Enums are instances of PersistableEnum.
You need to set a Default Entity Listener (an entity listener whose callbacks apply to all entities in the persistence unit).
In the Default Entity Listener class implement the #PrePersist method and make sure all the Enums are instances of PersistableEnum.
Is there some way of using magic methods in Java like there is in PHP with __call?
For instance:
class foo {
#Setter #Getter
int id;
#Getter
Map <String, ClassInFoo> myMap;
protected class ClassInFoo {
#Setter #Getter
String name;
}
#Setter
String defaultKey;
}
I'm using Project Lombok annotations for getter and setter methods to simplify the code.
Let's consider that that my map contains several items mapped by String and the defaultKey defines the default one.
What I would like is to be able to call foo.getName() which would return the default name as foo.myMap.get(defaultKey).getName().
The reason I can't just write all the getters manually is that the Foo class is in fact inherited with generics and the the inner class might be different.
I sort of need something like:
function Object __call(method) {
if (exist_method(this.method)
return this.method();
else
return this.myMap.get(defaultKey).method();
}
Is this somehow possible in Java?
EDIT:
I made a more precise example of what I am trying to achieve here: https://gist.github.com/1864457
The only reason of doing this is to "shorthand" the methods in the inner class.
You absolutely can through reflection by using its features like
public Method getMethod(String name, Class<?>... parameterTypes)
that can be used to see if a class has some methods defined but I don't see how your problem couldn't be solved with a proper use of interfaces, inheritance and overriding of methods
Features like reflection are provided to manage certain, otherwise unsolvable, issues but Java is not PHP so you should try to avoid using it when possible, since it's not in the philosophy of the language.
Isn't it the whole point of inheritance and overriding?
Base class:
public Object foo() {
return this.myMap.get(defaultKey).method();
}
Subclass:
#Overrides
public Object foo() {
return whateverIWant;
}
Is there any way to read and print the object attribute dynamically(Java) ? for example if I have following object
public class A{
int age ;
String name;
float income;
}
public class B{
int age;
String name;
}
public class mainA{
A obj1 = new A();
method(A);
method(B);
}
the output should be like
While running method(A):
Attribute of Object are age,name,income;
While executing method(B):
Attribute of Objects are age,name;
My question is I can pass various object in method(), is there any way I can access the attribute of the differnt object in general.
You want to use The Reflection API. Specifically, take a look at discovering class members.
You could do something like the following:
public void showFields(Object o) {
Class<?> clazz = o.getClass();
for(Field field : clazz.getDeclaredFields()) {
//you can also use .toGenericString() instead of .getName(). This will
//give you the type information as well.
System.out.println(field.getName());
}
}
I just wanted to add a cautionary note that you normally don't need to do anything like this and for most things you probably shouldn't. Reflection can make the code hard to maintain and read. Of course there are specific cases when you would want to use Reflection, but those relatively rare.
Using org.apache.commons.beanutils.PropertyUtils we can do this. If the proper getters and setters are defined for the bean we can also dynamically set the value:
import org.apache.commons.beanutils.PropertyUtils;
import java.beans.PropertyDescriptor;
public class PropertyDescriptorTest {
public static void main(String[] args) {
// Declaring and setting values on the object
AnyObject anObject = new AnyObject();
anObject.setIntProperty(1);
anObject.setLongProperty(234L);
anObject.setStrProperty("string value");
// Getting the PropertyDescriptors for the object
PropertyDescriptor[] objDescriptors = PropertyUtils.getPropertyDescriptors(anObject);
// Iterating through each of the PropertyDescriptors
for (PropertyDescriptor objDescriptor : objDescriptors) {
try {
String propertyName = objDescriptor.getName();
Object propType = PropertyUtils.getPropertyType(anObject, propertyName);
Object propValue = PropertyUtils.getProperty(anObject, propertyName);
// Printing the details
System.out.println("Property="+propertyName+", Type="+propType+", Value="+propValue);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
To set the value of a particular property:
// Here we have to make sure the value is
// of the same type as propertyName
PropertyUtils.setProperty(anObject, propertyName, value);
Output will be:
Property=class, Type=class java.lang.Class, Value=class genericTester.AnyObject
Property=intProperty, Type=int, Value=1
Property=longProperty, Type=class java.lang.Long, Value=234
Property=strProperty, Type=class java.lang.String, Value=string value
You can use reflection to get every field from your object (if security configuration allows you).
If you need it not for the sake of self-education, then it may be worth using ReflectionUtils from Apache Commons.
You can use reflection, but the API is not very nice to use. But what you are trying to do is not at all object-oriented. The A and B should have method "print yourself" which would output their values (you should specify the method in superclass/interface to call the method using polymorphism).
I think I would consider a different approach.
If you really want to treat these like data is there any reason they couldn't be hashtables (Do they have associated code)?
Reflection will do it but it's a last resort--you should always seriously consider different approaches before dropping to reflection.
Cases where you must access variables like that exist--like database mapping (Hibernate) and injection (Spring). You might want to consider if a packaged solution like that fits your need so that future programmers can understand what you did without learning everything about your specific solution.
Also, Spring injection can do things that might fit your needs.
Also also if you are going to use reflection, seriously consider annotations so that you aren't tying your functionality to what should be simple arbitrary attribute names.
I'm using NetBeans's Web Service generation tools. I've looked at the tutorials available, but cannot find anything on how to use a custom class as a return type. Most of the tutorials I've read are no more complex than Hello World: they take and return simple types like Strings.
So say I want a class that has 3 fields: a String, an int and a double[]. So far, the only way I can pass my own classes is by creating "envelope classes", with no methods, a parameter-less constructor, and with all fields declared public. I'd prefer to write standard Java classes. Obviously I cannot send the methods across SOAP, but I would have thought there was a way to ignore the methods when Marshalling the class, and only Marshall the fields.
Somebody has told me there are Annotations that facilitate this, but I can't find any tutorials on how to implement them. Any guidance would be greatly appreciated.
If you are using NetBeans interface to design your ws.
Click on add new operation
Select return type, browse for your class (as shown)
JAX-WS uses JAXB for mapping types, so classes should conform to that specification. You can find JAXB annotations in the java.xml.bind.annotations package.
If you want to marshal a non-annotated class, conform to the rules for JavaBeans should work:
public class Foo {
private String bar;
public String getBar() { return bar; }
public void setBar(String bar) { this.bar = bar; }
public static void main(String[] args) {
Foo foo = new Foo();
foo.setBar("Hello, World!");
ByteArrayOutputStream out = new ByteArrayOutputStream();
JAXB.marshal(foo, out);
foo = (Foo)
JAXB.unmarshal(new ByteArrayInputStream(out.toByteArray()), Foo.class);
System.out.println(foo.getBar());
}
}
If you want to use constructors with arguments, etc. look at the parts of the spec about factory methods and adapters.