I'm attempting to create a copy method, but what I have seems too simple and I think it's essentially doing nothing.
public Validation copy(Validation newValidation){return newValidation;}
so if implemented like so:
Validation x = new Validation();
Validation y = x.copy(x);
And then make sure that y has all the methods/variables of x and that when working with the variables in y, I don't affect the variables in x. I have a feeling what I want is a "deep copy" method and I found a post about it here: Creating a deep copy method, Java but that person has no argument for their method so I don't know how it is actually copying.
Yes, it does nothing except returning the same reference that has been passed.
Probably, you are looking for the Object#clone()* method:
public Validation copy(Validation newValidation) {
return newValidation.clone();
}
In 95% cases, that is the most appropriate and proper solution for different types of tasks. You should not reinvent the wheel if there isn't a need of it.
As the Java documentation says:
... this method performs a "shallow copy" of this object, not a "deep copy" operation.
... it may be necessary to modify one or more fields of the object returned by super.clone before returning it.
Validation y = x.copy(x);
You shouldn't pass an x to a copy method because when you are calling this method on an x instance, inside the class you have an access to this which, in this case, represents your x.
Validation y = x.clone();
For a "shallow copy" the preceding example is good, but for a "deep copy" you need to override a default Object#clone() behaviour:
class A implements Cloneable {
public #Override A clone() throws CloneNotSupportedException {
return (A)super.clone(); // or or another implementation
}
}
class Validation implements Cloneable {
// an example of a reference-type field
private A a; // with a setter
public #Override Validation clone() throws CloneNotSupportedException {
Validation newClone = new Validation();
// note that the `A` class has to implement the `Cloneable`
// and override the `clone` method making it `public`
newClone.setA(this.a.clone());
return newClone;
}
}
*Don't forget to implement the Cloneable interface to allow cloning.
To read: Effective Java, Item 11: Override clone judiciously.
The Java api has a Cloneable Interface.Object has a clone method that can only be accessed when it's overridden in the subclass, that also implements the Cloneable interface. Your method does not really create a copy, since the "copy" points to the original instance.
Let's say I make a copy of Validation :
Validation v = new Validation();
v.setId(1);
Validation valid = v.copy(v);
valid.setId(2);
Now the id in v will change as well, because valid points to v.
But the clone-Method makes a deep-copy. Here is a small example :
public class Product {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Product{" + "id=" + id + ", name=" + name + '}';
}
#Override
protected Object clone() throws CloneNotSupportedException {
Product p = new Product();
p.setId(id);
p.setName(name);
return p;
}
}
public static void main(String[] args) {
Product p = new Product();
try {
Product clone = (Product) p.clone();
System.out.println(clone.toString());
} catch (CloneNotSupportedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
Related
In this question and this post is explained how to clone objects with final fields by using protected copy constructors.
However, supposing that we have:
public abstract class Person implements Cloneable
{
private final Brain brain; // brain is final since I do not want
// any transplant on it once created!
private int age;
public Person(Brain aBrain, int theAge)
{
brain = aBrain;
age = theAge;
}
protected Person(Person another)
{
Brain refBrain = null;
try
{
refBrain = (Brain) another.brain.clone();
// You can set the brain in the constructor
}
catch(CloneNotSupportedException e) {}
brain = refBrain;
age = another.age;
}
public String toString()
{
return "This is person with " + brain;
// Not meant to sound rude as it reads!
}
public Object clone()
{
return new Person(this);
}
public abstract void Think(); //!!!!
…
}
Returns an error since we can't instantiate an abstract class. How can we solve this?
You don't implement the clone() method in the abstract class, only in the concrete sub-classes.
public class SomeConcretePerson extends Person
{
public SomeConcretePerson (SomeConcretePerson another)
{
super (another); // this will invoke Person's copy constructor
}
public Object clone()
{
return new SomeConcretePerson(this);
}
}
In some rare cases, we might not be able to use the copy constructor technique and have to use the clone() method. For these cases, it’s worth knowing that Java offers a work-around for the final field problem:
public abstract class Person implements Cloneable {
private final Brain brain;
private int age;
public Person(Brain aBrain, int theAge) {
brain = aBrain;
age = theAge;
}
#Override public String toString() {
return "This is person with " + brain;
// Not meant to sound rude as it reads!
}
#Override public Person clone() {
try {
Person clone = (Person)super.clone();
Field brainField=Person.class.getDeclaredField("brain");
brainField.setAccessible(true);
brainField.set(clone, brain.clone());
return clone;
} catch (CloneNotSupportedException|ReflectiveOperationException ex) {
throw new AssertionError(ex);
}
}
public abstract void think();
…
}
The possibility to override the final restriction was created for exactly such use cases, cloning or deserializing an object, where no constructor will be called. The Java Language Specification, §17.5.3. Subsequent Modification of final Fields states:
In some cases, such as deserialization, the system will need to change the final fields of an object after construction. final fields can be changed via reflection and other implementation-dependent means. The only pattern in which this has reasonable semantics is one in which an object is constructed and then the final fields of the object are updated. The object should not be made visible to other threads, nor should the final fields be read, until all updates to the final fields of the object are complete.
This is exactly how the example works, setting the final field right after the clone’s construction, before the clone is exposed to anyone, and not reading any field.
As said, cases in which this is required, are rare. As long as you can implement a copy constructor based solution, use that.
If you just want a new instance of the class without cloning the values of its members then you can use the following:
public static < T > T getNewInstance ( Class <T> type )
{
try
{
return type.newInstance() ;
} catch ( InstantiationException | IllegalAccessException e)
{
e.printStackTrace();
}
return null ;
}
For deep cloning of objects you can use com.rits.cloning.Cloner utility. For eg. :
private T clone(T resource){
Cloner cloner = new Cloner();
T cloneObject = (T) cloner.deepClone(obj);
return cloneObject;
}
We can't instantiate an abstract class but we can do it in the subClass
class Teacher extends Person {
public Teacher(Brain aBrain, int theAge) {
super(aBrain, theAge);
}
protected Teacher(Person another) {
super(another);
}
public Object clone() {
return new Teacher(this);
}
}
This is a question for Java. I have an interface called IMyObjectPredicate which implements a single test method to apply to an input:
public interface IMyObjectPredicate {
boolean test(MyObject x);
}
What I would like is to be able to pass an instance of IMyObjectPredicate around between objects and have the test function update its references to variables to those of the new object it is being passed to. For instance, consider a class which makes use of this predicate:
public class Tester {
MyObject o;
IMyObjectPredicate myTestFunction;
int myThreshold;
public Tester(/*stuff*/) {
/*Code here which initialises the Tester instance and 'myThreshold'*/
myTestFunction = new IMyObjectPredicate() {
#Override
public boolean test(MyObject o) {
return (o.value() > myThreshold);
}
};
}
public boolean isGood() {
return myTestFunction.test(o);
}
}
I would like to be able to perform a deep clone of the Tester object for reasons I won't go into here. But the idea is that the cloned instance of Tester should test the predicate against its own value of myThreshold, not reference the myThreshold of the first instance. But if I pass myTestFunction to a new instance of Tester, I guess it will still be referencing the myThreshold value of the first instance, instead of dynamically evaluating myThreshold based on the reference of the enclosing class.
How can I accomplish the passing of a IMyObjectPredicate object whose test function uses references to the fields of the new object it is passed to?
Edit:
A complicating factor is that, in general, it will not be possible to reconstruct myTestFunction solely from the fields within a Tester object. myTestFunction may be overwritten by other parts of the program in a way that does not correlate with the other fields of Tester. I can sacrifice this functionality if need be, but I would rather not for the sake of elegance.
Java does not have an API to replace enclosed context of anonymous class.
The simplest solution I can see from your simplified example is to add threshold to the signature of test function. As I understand the threshold is going to be there anyway.
public interface IMyObjectPredicate {
boolean test(MyObject x, int threshold);
}
Another approach would use some factory method that will create a predicate for provided threshold like
class PredicateFactory {
IMyObjectPredicate thresholdPredicate(int threshold) {
return new IMyObjectPredicate {
//...
}
}
}
then you can pas this factory to object that will use it's own threshold to construct new instance of predicate
factory.thresholdPredicate(myThreshold);
It is a lot easier if ImObjectPredicate is an class that simply stores a reference to a predicate instead of an interface. If you're able to make that change, each predicate can store its own threshold, which solves the issue.
public IMyObjectPredicate {
private int threshold;
private Predicate<MyObject> pred;
public int getThreshold() {
return threshold;
}
public Predicate<MyObject> getPredicate() {
return pred;
}
public IMObjectPredicate(int threshold, Predicate<MyObject> pred) {
this.threshold = threshold;
this.pred = pred;
}
public boolean test(MyObject o) {
return pred.test(o);
}
}
public class Tester {
MyObject o;
IMyObjectPredicate myTestFunction;
IMyObjectPredicate myTestFunctionCopyWithDiffThreshold;
int myThreshold;
public Tester(/*stuff*/) {
/*Code here which initialises the Tester instance and 'myThreshold'*/
myTestFunction =
new IMyObjectPredicate(myThreshold, o -> o.value() > getThreshold());
myTestFunctionCopyWithDiffThreshold =
new ImObjectPredicate(5, myTestFunction.getPredicate());
}
public boolean isGood() {
return myTestFunction.test(o);
}
}
This is the most sensible solution, as ImObjectPredicate should store its own threshold if that value uniquely refers to that ImObjectPredicate.
For everyone who is talking about the fact that the object is in an "unitialized state", please refer to the answer to this question which shows that an object reference can be passed around, dereferenced, have methods invoked from it, and have fields accessed before a constructor terminates and all fields have been assigned (including final fields).
So here's the use case:
public class Entity {
private final String name;
public Entity() {
this(toString()); //Nope, Chuck Testa
}
public Entity(String name) {
this.name = name;
}
}
The compiler error is:
Cannot refer to an instance method while explicitly invoking a constructor.
Note that toString() has not been overriden and is the default call from Object.
I'm certainly interested in the philosophical/technical reasons behind this, so if anyone can explain that, that would be an awesome bonus. But I'm looking for a way to call toString() from that default constructor as it refers down to the more specific one with more arguments. The actual use case is a bit more complicated and ends up referring all the way down to a constructor with four arguments, but that shouldn't really matter.
I know I could do something like this...
private static final String TO_STRING_CONSTRUCTOR_ARGUMENT = "aflhsdlkfjlkswf";
public Entity() {
this(TO_STRING_CONSTRUCTOR_ARGUMENT);
}
public Entity(String name) {
this.name = name == TO_STRING_CONSTRUCTOR_ARGUMENT ? toString() : name;
}
... but it seems like a pretty inelegant solution.
So, any way to pull it off? Or any recommended best practices to deal with this situation?
I would prefer not to pass this around until the object is created. Instead I would do this:
public class Entity {
private final String name;
public Entity() {
this(null); // or whatever
}
public Entity(String name) {
this.name = name;
}
public String getName() {
return name != null ? name : Objects.hashCode(this);
}
}
If you can live without the final name, you can use an initializer block:
public class Entity {
private String name;
{name = this.toString();}
public Entity() {
}
public Entity(String name) {
this.name = name;
}
}
this is only available after all calls to this() or super() are done. The initializer runs first after the constructors call to super() and is allowed to access this.
As for the reasons why that is a compiler error, please see section 8.8.7 of the JLS. The reasons why this was made a compiler error are not clear, but consider that the constructor chain has to be the first thing executed when new'ing an Object and look at the order of evaluation here:
public Entity() {
this(toString());
}
toString() is evaluated first before the even the super constructor is invoked. In general this leaves open all kinds of possibilities for uninitialized state.
As a personal preference, I would suggest that everything an object needs to have in order to create valid state should be available within its constructor. If you have no way of providing valid state in a default constructor without invoking other methods defined in the object hierarchy, then get rid of the default constructor and put the onus on the users of your class to supply a valid String to your other constructor.
If you are ultimately just trying invoke the other constructor with the value of toString(), then I would suggest the following instead:
public Entity() {
name = toString();
}
which accomplishes the same goal you set out to achieve and properly initializes name.
As explained in the JLS this is not allowed before the instance is initialized.
However, there are ways to handle your scenario in a consistent manner.
As I see your case, you want to signify either a generated value (toString()) or a user provided value, which can be null.
Given this constraints, using TO_STRING_CONSTRUCTOR_ARGUMENT is failing for at least one specific use case, however obscure it may be.
Essentially you will need to replace the String with an Optional similar to what exists in Google Guava and will be included in Java 8, and seen in many other languages.
Having a StringOptional/StringHolder or whatever you choose, similar to this:
public class StringOptional {
private String value;
private boolean set = false;
public StringOptional() {}
public StringOptional(String value) {
this.value = value;
this.set = true;
}
public boolean isSet() { return set; }
public String getValue() { return value; }
}
Then you can call constructors with the knowledge of the inferred path.
public class Entity {
public Entity() {
this(New StringOptional());
}
public Entity(String s) {
this(new StringOptional(s));
}
private Entity(StringOptional optional) {
super(optional);
}
}
And store this for subsquent need:
if (optional.isSet() ? optional.getValue() : toString();
This is how I usually would handle a maybe-null scenario, hope it augments as an answer.
You cannot 'use' an instance that has not been created yet. By calling a second constructor you are postponing the creation, you cannot use it before the call or in the action of calling.
You can use a static method factory in your class Entity, and put the constructor private:
public class Entity {
private String name;
private Entity() {
}
public Entity(String name) {
this.name = name;
}
public static Entity createEntity() {
Entity result = new Entity();
result.name = result.toString();
return result;
}
}
I'd like to write an exception class which is usable with different classes and specific behaviors. It works well with changing an object - like
a.setWeight(500)
- but it doesn't work in my constructor - like
Cheese b = new Cheese(500);
because the object is not being generated and null is inserted in my WeightException.
public class WeightException extends Exception {
private int attribute;
private Object object;
public WeightException(Object o, int a) throws WeightException {
object = o;
attribute = a;
}
public String getMessage() {
if(object instanceof Cheese)
return "Cheese is overweight.";
if(object instanceof Baggage)
return "Baggage is "+String.valueOf(attribute)+" kilos overweight.";
}
}
public class Cheese {
private int weight;
public Cheese(int weight) {
setWeight(weight);
}
public void setWeight(int weight) throws WeightException {
if(weight<200)
this.weight = weight;
else
throw new WeightException(this, weight);
}
}
Does anybody know a better approach to solve this than to insert a string with the class name in my exception class parameters?
Implement an interface in the classes you want to use with this exception.
The interface has a method to define a message, possible another to provide an attribute.
Alternatively, provide an array of attributes and use String.format to build the message.
Use that interface to define the object parameter passed in to the exception ctor.
Call that method in the exception to get the message.
Personally, I find this to be an anti-pattern, unless the classes you want to use with the exception are very tightly related. Otherwise you're giving up semantically-meaningful exception property names.
I'd rather see an app-specific superclass with subclasses with semantic meaning.
Here is a solution which would require that you use a "toy" project of mine (well, I already use it in other projects):
Make a base abstract class like this:
public abstract class WeightedItem
{
protected static final MessageBundle BUNDLE;
static {
// The day when you get serious, replace with a properties bundle
final MessageSource source = MapMessageSource.newBuilder()
.put(Cheese.class.getCanonicalName(), "cheese is overweight")
.put(Baggage.class.getCanonicalName(), "baggage is %d kilos overweight")
.build();
BUNDLE = MessageBundle.newBuilder().appendSource(source).freeze();
}
protected int weight;
protected final WeightException doException(final Object... params)
{
return new WeightException(BUNDLE.printf(getClass().getCanonicalName(),
params));
}
}
An implementation of Baggage would then do:
public class Baggage
extends WeightedItem
{
// ....
public void setWeight(int weight)
throws WeightException
{
if (overweight)
throw doException(weight);
}
}
As the implementation is both key-resistant (returns the key if missing) and format-resistant (returns the format string itself if format argument mismatch) you are guaranteed to have parameterized messages or quickly see where you got your messages wrong...
Have you actually tried running this code? The this variable is valid (non-null) within a constructor. Even if the constructor throws an exception, a new object has been created and can be referenced. See the JLS.
If you parameterize the exception with everything you need for the message, you can rid yourself of using instanceof, and make the exception usable by any class:
Also, it's not a good idea to hold a reference to the object that caused the exception - it's unnecessary, is a form of memory leak, but importantly if the exception is thrown from the constructor, will allow this to "escape" from the constructor (always bad).
public class WeightException extends Exception {
private final int attribute;
private final String className;
private final String units;
public WeightException(Object o, int a) {
this(o, a, null);
}
public WeightException(Object o, int a, String u) {
classname = o.getClass().getSimpleName(); // eg "Cheese"
attribute = a;
units = u == null ? "" : u + " ";
}
public String getMessage() {
return className " is " + attribute + " " + units + "overweight.";
}
}
You can now use this exception with any class without further modification of the exception or the client class, other than to provide the optional units:
From Cheese:
throw new WeightException(this, weight);
From Baggage:
throw new WeightException(this, weight, "kilos");
This question already has answers here:
How to call a method stored in a HashMap? (Java) [duplicate]
(3 answers)
Closed 8 years ago.
I have read this question and I'm still not sure whether it is possible to keep pointers to methods in an array in Java. If anyone knows if this is possible (or not), it would be a real help. I'm trying to find an elegant solution of keeping a list of Strings and associated functions without writing a mess of hundreds of if statements.
Cheers
Java doesn't have a function pointer per se (or "delegate" in C# parlance). This sort of thing tends to be done with anonymous subclasses.
public interface Worker {
void work();
}
class A {
void foo() { System.out.println("A"); }
}
class B {
void bar() { System.out.println("B"); }
}
A a = new A();
B b = new B();
Worker[] workers = new Worker[] {
new Worker() { public void work() { a.foo(); } },
new Worker() { public void work() { b.bar(); } }
};
for (Worker worker : workers) {
worker.work();
}
You can achieve the same result with the functor pattern. For instance, having an abstract class:
abstract class Functor
{
public abstract void execute();
}
Your "functions" would be in fact the execute method in the derived classes. Then you create an array of functors and populate it with the apropriated derived classes:
class DoSomething extends Functor
{
public void execute()
{
System.out.println("blah blah blah");
}
}
Functor [] myArray = new Functor[10];
myArray[5] = new DoSomething();
And then you can invoke:
myArray[5].execute();
It is possible, you can use an array of Method. Grab them using the Reflection API (edit: they're not functions since they're not standalone and have to be associated with a class instance, but they'd do the job -- just don't expect something like closures)
Java does not have pointers (only references), nor does it have functions (only methods), so it's doubly impossible for it to have pointers to functions. What you can do is define an interface with a single method in it, have your classes that offer such a method declare they implement said interface, and make a vector with references to such an interface, to be populated with references to the specific objects on which you want to call that method. The only constraint, of course, is that all the methods must have the same signature (number and type of arguments and returned values).
Otherwise, you can use reflection/introspection (e.g. the Method class), but that's not normally the simplest, most natural approach.
I found the reflection approach the cleanest -- I added a twist to this solution since most production classes have nested classes and I didn't see any examples that demonstrates this (but I didn't look for very long either). My reason for using reflection is that my "updateUser()" method below had a bunch of redundant code and just one line that changed (for every field in the user object) in the middle that updated the user object:
NameDTO.java
public class NameDTO {
String first, last;
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getLast() {
return last;
}
public void setLast(String last) {
this.last = last;
}
}
UserDTO.java
public class UserDTO {
private NameDTO name;
private Boolean honest;
public UserDTO() {
name = new NameDTO();
honest = new Boolean(false);
}
public NameDTO getName() {
return name;
}
public void setName(NameDTO name) {
this.name = name;
}
public Boolean getHonest() {
return honest;
}
public void setHonest(Boolean honest) {
this.honest = honest;
}
}
Example.java
import java.lang.reflect.Method;
public class Example {
public Example () {
UserDTO dto = new UserDTO();
try {
Method m1 = dto.getClass().getMethod("getName", null);
NameDTO nameDTO = (NameDTO) m1.invoke(dto, null);
Method m2 = nameDTO.getClass().getMethod("setFirst", String.class);
updateUser(m2, nameDTO, "Abe");
m2 = nameDTO.getClass().getMethod("setLast", String.class);
updateUser(m2, nameDTO, "Lincoln");
m1 = dto.getClass().getMethod("setHonest", Boolean.class);
updateUser(m1, dto, Boolean.TRUE);
System.out.println (dto.getName().getFirst() + " " + dto.getName().getLast() + ": honest=" + dto.getHonest().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
public void updateUser(Method m, Object o, Object v) {
// lots of code here
try {
m.invoke(o, v);
} catch (Exception e) {
e.printStackTrace();
}
// lots of code here -- including a retry loop to make sure the
// record hadn't been written since my last read
}
public static void main(String[] args) {
Example mp = new Example();
}
}
You are right that there are no pointers in java because a reference variables are the same as the & syntax in C/C++ holding the reference to the object but no * because the JVM can reallocate the heap when necessary causing the pointer to be lost from the address which would cause a crash. But a method is just a function inside a class object and no more than that so you are wrong saying there are no functions, because a method is just a function encapsulated inside an object.
As far as function pointers, the java team endorses the use of interfaces and nested classes which all fine and dandy, but being a C++/C# programmer who uses java from time to time, I use my Delegate class I made for java because I find it more convenient when I need to pass a function only having to declare the return type of the method delegate.
It all depends on the programmer.
I read the white pages on why delegates are not support but I disagree and prefer to think outside the box on that topic.