this is really basic I know, but I just can't see what the problem is... all I want to do is set the value of a variable from one class into an "intermediary" class and retrieve it in a third class (because filterArray will get called from other classes as well, and I want them all to read the same data). But if I do:
b =new GetSet()
b.setBdl(extras);
JSONArray arr= getData.filterArray();
using
class GetSet {
private Bundle params;
public GetSet() {
}
public Bundle getBdl() {
return this.params;
}
public void setBdl(Bundle bdl) {
params = bdl;
}
}
then in the filterArray method, if I try
Bundle params = new GetSet().getBdl();
I get all sorts of run time errors, and if I try
Bundle params = GetSet.getBdl();
it tells me I can't make a static reference to a non-static method.
Where am I going wrong?
The errors are because you are using it in a wrong way
look at your signature of getBdl its a public Bundle method its a non static method so can't be accessed by the classname.
it should be accessed through the bean object that is b,
second error is also related,
you wrote/set the property of the bean with the object b but when you access it , you are again creating a new GetSet().getBdl so it says Null pointer exception
so do like this
GetSet b=new GetSet();
b.setBdl(bundle object);
so now b contains the value
pass the b...
so get the bundle through b,,if you need to access it from another class pass b into its constructor and get it their
SomeClass class=new SomeClass(b);
now in that class you can get the bundle via b
hope it all helps you.
You should pass b to filterArray method.
First change filterArray to get one parameter of type GetSet:
public JSONArray filterArray(GetSet b)
Then, call it like:
getData.filterArray(b);
And inside filterArray just use:
Bundle params = b.getBdl();
The problem is that you create an object and sets a value, then you need to get the value from the same object.
When working with objects, you can create a new object of whatever class you want, set its internal value and when you access the same object from different places, the internal value will be the same (Im talking here both on GetSet and getData.
Another option is to use static value (and static getters and setters), if the value is same for all objects of the class. This usually not needed and may be used due to bad design. In your case you don't really need it, but it will work.
Related
I have a POJO with a field marked as transient. GSON does not serialize it. Great. But when it is deserialized it wipes out the the field's initial settings.
For example, if I have this object:
public class ObjWithTransient {
public String name;
public transient List<String> listOStrings = new ArrayList();
}
And I run this test:
#Test
public void testSerializeWithTransient() throws Exception {
ObjWithTransient obj = new ObjWithTransient();
obj.name = "Foobar";
String json = gson().toJson(obj);
// Deserialize
ObjWithTransient obj2 = GsonUtil.gson().fromJson(json, ObjWithTransient.class);
Assert.assertEquals(obj2.name, "Foobar");
Assert.assertNotNull(obj2.listOStrings); // <--- Fails here
Assert.assertEquals(obj2.listOStrings.size(), 0);
}
By marking it transient, I assume I am telling GSON to ignore it, but that doesn't seem to be the case. What is the best way to retain the initial settings here?
EDIT:
I believe the issue is because there is not a declared constructor. This does not work with an inner class, but with a normal class or a static inner class it appears to work. Reading the GSON code, it trys multiple ways to create the object, but ultimately uses a UnsafeConstructor to create it if nothing else works. This creates an object with null entries across the board. I could also add an InstanceCreator to tell Gson how to create the object.
I believe the issue is because there is not a declared constructor. This does not work with an inner class, but with a normal class or a static inner class it appears to work. Reading the GSON code, it trys multiple ways to create the object, but ultimately uses a UnsafeConstructor to create it if nothing else works. This creates an object with null entries across the board. I could also add an InstanceCreator to tell Gson how to create the object.
To make a immutable class , Effective Java has one last condition.
To make a class immutable, follow these five rules:
5- Ensure exclusive access to any mutable components. If your class has any fields that refer to mutable objects, ensure that clients of the class cannot obtain references to these objects. Never initialize such a field to a client-provided object reference nor return the object reference from an accessor. Make defensive copies (Item 24) in contructors, accessors, and readObject methods
public final class ImmutableClass {
private MutableObject mutableObject;
// If I should not provide getter for this object. Then what is the use of this variable after I have
//initalised in the constructor
}
Can somebody explain me this point?
It's actually reasonably simple.
Basically, it's saying to not...
1- Make available any reference to any mutable object that your object might contain.
So if your Class contained a java.util.List as one of it's fields, there should be no way for any client using your Class to gain a reference directly to the List field, either via public deceleration or getter of some kind.
For example...
public class BadImmutableExample {
public List<String> myStrings; // This can not be referenced by the client
/*...*/
}
Would be bad, because the field myStrings is accessible to any body to make modifications to...
In the case you had to return the values in the List you would either be required to return a copy of the List (not a reference to it) or return an array of the values, for example.
For example...
public class BadImmutableExample {
private List<String> myStrings; // This can not be referenced by the client
/*...*/
public List<String> getMyStrings() {
return myStrings;
}
}
Would expose the List myStrings to any clients, which would allow them to modify it.
In this case, you could also use Collections.unmodifiableList(myStrings) to make the list unmodifiable, or return new ArrayList<String>(myStrings) or return an array of String instead...
2- Never initialise such a field to a client provided object...
Basically this means that if your Class requires the client to seed it with some kind of value or values, you should never maintain a reference directly them, instead, again, make a copy for you own reference...
For example...
public class BadImmutableExample {
private List<String> myStrings; // This can not be referenced by the client
public ImmutableExample(List<String> clientStrings) {
myStrings = clientStrings;
}
}
Would break this rule, as any changes to clientStrings would be immediately reflected within you class.
Instead, you could do something like...
public class BetterImmutableExample {
private List<String> myStrings; // This can not be referenced by the client
public ImmutableExample(List<String> clientStrings) {
myStrings = new ArrayList<String>(clientStrings);
}
}
Instead, which will make a copy of the client supplied list, but which will no longer reflect changes made to it (the client supplied list)
I'm a bit confused about the use of getter/setters and constructors (see the below code for an example)
public class ExampleClass {
private int value = 0;
public ExampleClass () {
value = 0;
}
public ExampleClass (int i) {
this.value = i;
}
public int getValue() {
return value;
}
public void setValue(int val) {
this.value = val;
}
public static void main(String[] args) {
ExampleClass example = new ExampleClass (20);
example.setValue(20);
//Both lines above do same thing - why use constructor?
System.out.println(example.getvalue());
}
}
All I've learned is that we need getters/setters for security and that they can also be used to change or edit values later on.
My question is that if the constructor is the point of initialization and a default constructor is always present, why use a constructor with parameters to initialize values instead of getters/setters?. Wouldn't using the getter and setter provide security as well being able to easily change values at any stage. Please clarify this point for me.
default constructor is always there
Well actually its not always there. A default constructor is the one which is provided by the compiler (of course it is a no-arg constructor ) Only if there is no other constructor defined in the class
why we use constructor with parameters to initialize values instead of set get
Because there could be a condition that an object can always be created only when all the values are provided at the time of initialization itself and there is no default value. So all values must be provided otherwise code will not compile.
Consider this Book class
public class Book {
private String title;
private String author;
public Book(String title, String author){
this.title = title;
this.author = author;
}
//getters and setters here
}
Consider a condition where a book can be created only if it has title and author.
You cannot do new Book() because no-arg constructor is absent and compiler will not provide one because one constructor is already defined.
Also you cannot do new Book() because our condition does not meet as every book requires a title and author.
This is the condition where parameterized constructor is useful.
Sometimes, when creating a new object of a class, some values HAVE TO be provided. For an example, when connecting to database and creating Connection class object you have to provide a connection string, so that it knows what are you connecting to. Creating new connection without specyfing target database would be pretty useless, right?
Also, take a look at this
Foo foo=new Foo(1,2,3,4,5,6,7);
and this
Foo foo=new Foo();
foo.setP1(1);
foo.setP2(2);
foo.setP3(3);
foo.setP4(4);
foo.setP5(5);
foo.setP6(6);
foo.setP7(7);
First one looks better, right?
My question is that if constructor is point of initialization and
default constructor is always there so why we use constructor with
parameters to initialize values instead of set get.
If you think about an object transitioning into different states then it makes sense to have a parameterized constructor alongwith setters and getters. Let me try to put a real life scenario: Think about an Employee class, a new employee joins, you don't know many details but few and you create the object of Employee with defualt and base value of its attributes. You need to register the employee in the system and hence you used the parameterized constructor. Once you get more details about the employee, you use getters and setters to update the attributes.
this is purely upto your coding style. But IMO, I would use parametrized constructor:
to initialize those values which should not be changed. (like username parameter for a person object)
to initialize those values, without setting which, the object will be in invalid state.
Say, you are sending login parameters to a method. You can use in these to ways
Login obj = new Login();
obj.setUsername("user");
obj.setPassword("pw")// what if someone commented this out, or you forget to call it
and otherway,
Login obj = new Login("user", "pw");
while you can send Login object just after setting username in 1st case, it would be invalid at recieving end. but the second method is less prone to bugs, bcz it becomes necessary to pass all the required parameters.
Just to make it easier. It takes less code to use a constructor than to create an object and use the setters.
Sometimes you don't need to set all the fields to specific values at the time of creating. For examle, when you make an array. Also, as already said, it's safer when you use getters -- you can't get nullpointer.
Remember to write the default constructor when you've defined constructor with parameters. Or be sure not to use it.
First, both methods: Constructor and Setter are safe ways to change object's attributes. Are expected from Class author to expose or not safe ways to modify an instance.
The default constructor is always provided if you have not written one:
// Example of a Class with a Default Constructor
public class GetSet {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public static void main(String[] args) {
// Theres a implicit Default Constructor here
// Its ok to do that
// GetSet obj = new GetSet();
GetSet obj = new GetSet();
}
}
// Example of a Class without a Default Constructor
public class GetSet2 {
public GetSet2(String value) {
this.value = value;
}
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public static void main(String[] args) {
// GetSet2 obj = new GetSet2(); // compile time error
// Default constructor is not provided, since u wrote one
}
}
2. About which is better: Using a constructor or via setter, it depends on what u want. If you will only modify an attribute of a existing object, u may use the setter, or for a completely filled object you may prefer the constructor instead.
// Example of modifing an obj via Setter and Constructor
public class GetSet3 {
public GetSet3(String value1, String value2, String value3, String value4) {
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
this.value4 = value4;
}
private String value1;
private String value2;
private String value3;
private String value4;
// ... Getters and Setters
public static void main(String[] args) {
// Its easier to this
GetSet3 obj;
obj= new GetSet3("j", "a", "v", "a");
// instead that
// its also easy to forget or do something wrong
// when u have a lot of attributes to set
obj.setValue1("j");
obj.setValue2("a");
obj.setValue3("v");
obj.setValue4("a");
}
}
It's easier and safer to initialize your object variables via your constructor to avoid nullpointers.
If you instantiate your object without initializing your variables first and you do a get operation on one of your null variables, you might get a nullpointer exception at runtime because you forgot to manually set its value.
On the flipside of that, if you always initialize your object variables in your default constructor, you have a seriously reduced risk of getting nullpointer exceptions during runtime because none of your variables can be null unless you specifically set them via a setter (which is not recommended).
Constructor with arguments makes you get the object fully constructed. If you want to use default one, you will have to make sure the fields are set using setters. During set of some property, assume the exception is thrown, now you have an object which is not usable. In several cases, setter wouldn't be exposed but getters. In those cases, having constructor with arguments or a named constructor is the right option. In a nutshell, getters and setters do have their own importance rather than initializing the object.
Why use getters and setters?
Because you write it using less, more elegant and better readable code when you set the values as parameters in a constructor. Moreover, sometimes some fields are indispensable for the object, so a parameter constructor prevents the user from creating an object omitting necessary fields for the object's functionality. One is though not "oblidged" to call the setters.
To answer this question, I say by writing getters/setters, we create a provision to add any validation method in the future, currently, there is no validation, but if anything goes wrong in the future we just add validation logic in the setter.
we can also write the logic/validation in constructors but it's not a good practice. The constructor should be used only to initialize your object's state/fields. You should delegate the responsibility of other things to other methods.
Note that a constructor is called only once i.e, whenever you create a new object With a sufficiently large input, you can cause an exception in your constructor.
This is one of several reasons why you should not use a constructor to contain "business logic".
I have Spring Web Services project, where I have access to the logged in username.
The processes then takes place via several classes, but what I want to do is, set the username in a User class/bean when I first receive it in the first class.
i.e. the following:
My first web services class:
// Set the Spring Security Name of the user
user.setSpringSecurityUsername(request.getUserId());
String springSecurityUsername = user.getSpringSecurityUsername();
My User class
private String springSecurityUsername = "";
private final String windowsUsername = System.getProperty("user.name");
public String getSpringSecurityUsername() {
return springSecurityUsername;
}
public void setSpringSecurityUsername(String springSecurityUsername) {
this.springSecurityUsername = springSecurityUsername;
}
public String getWindowsUsername() {
return windowsUsername;
}
I want to be able create a new instance of the User bean and set the SpringSecurityUsername. I then wish to pass the user object to the other processing classes, but I don't what them to have access to the setter method in the user (e.g. don't want other classes to be able to use the .setSpringSecurityUsername.
I only want to be able to set it the once.
Can anyone help with this?
I only want to be able to set it the once.
It sounds like you should be passing it to the constructor then. You've referred to the class as a bean in some cases - does it have to be a strict JavaBean with a parameterless constructor? Or should everything still work for you if you just add a constructor?
The benefit of putting it into the constructor over ignoring/throwing on a second setSpringUsername call is that you simply can't express the incorrect code. It's always better to make something impossible than to have to tell people not to do it :)
(It also means you can make it a final field, too.)
It sounds like the initializing value should just be a constructor parameter and there should be no setter method at all. In the case it's also valid to never call the setter, include both a constructor without the argument and one with the argument.
Initialize it internally with some value, then in your setter check to see if it still has that value. If it does, allow it to be set. If it doesn't it has already been set - simply do nothing in that case.
You can't prevent the method from being called, but you can check whether it got called previously:
boolean usernameSet = false;
public synchronized void setSpringSecurityUsername(String springSecurityUsername) {
if (!usernameSet) {
this.springSecurityUsername = springSecurityUsername;
usernameSet = true;
}
}
This is actually a requirement of the builder pattern. You have each setter return "this" and when you want to finalize it you call a method like "finish" to disable all the setters. Goes like this:
new MyClass()
.setAge(20)
.setWeight(200)
.setHeight(6.0)
.finish();
Not a bad pattern at all, kind of gives you named parameters for java without losing the advantages of a immutability.
I would say go for setting it in constructor and no setter methods.
public User(String userName){
this.springSecurityUsername = userName;
}
Here's some code that will allow it to be set once:
private Object v;
public void setV(Object o) {
if (v == null)
v = o;
}
Or if null is a possible value zfor the first set, do this:
private Object notSer = new Object();
private Object v = notSer;
public void setV(Object o) {
if (v == notSer)
v = o;
}
I am trying pass class as value in hashmap. I need to get the class(value) using particular key and instantiate an object for the retrieved class. but in order to create object, i need to pass parameters.
My flow goes here, when i call the getExpo method from another class passing the key value. using the key value, i need to get the correct class and using that class need to instantiate the object and need to return the object. Inorder to create object, i need to pass the arguments since the class doesnot have default constructors.
The purpose of this procedure is in future, i need to add another key ,pair value, i shouldnot do any change........the implementation is same for all class ie creating the object
My class goes here
public class ExampleFactory {
static {
HashMap<String,Class<?>> hmap = new HashMap<String,Class<?>>();
hmap.put("jxpath", JXPathExpression.class);
hmap.put("spel", SpelExpression.class);
}
public Predicate getExpo(String key,String expression) {
// Need to get the class using key value and instantiate the object for the class
// but i need to pass parameters in order to create the object.something like this
//JXPathExpression object = new JXPathExpression(expression);
return null;
}
}
Try
Class aClass = hmap.get(key);
Constructor constructor = aClass.getConstructor(new Class[]{String.class});
return (Predicate) constructor.newInstance(expression);