I am trying to clone a DTO. I have taken a DTO Object as shown:
public class Employee implements Cloneable
{
String name;
String dept;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
}
But this line is giving me Error :
public class Test
{
public static void main(String args[]) {
Employee emp1 = new Employee();
emp1.setDept("10");
emp1.setName("Kiran");
Employee emp2 = (Employee) emp1.clone(); // This Line is giving error .
}
}
My query is that clone method is from Object, so why can't we use it directly like we do the `toString Method?
You have to override Object.clone(), which is protected. See the
java.lang.Cloneable and Object.clone() documentation.
More complete example here: How to implement Cloneable interface.
Unfortunately cloning in Java is broken. If you have an option, either try to define your own clone interface, one which actually has a clone method or use copy constructors to create copies of object.
Actually, never mind. You need to override the clone method in your class since its protected in java.lang.Object. Don't forget to remove the CloneNotSupportedException in the method signature, so that you don't have to handle it everywhere in your code.
Related
Learning Java here and I try to cast on a super class and i cant access to subclass methods, is it possible, I am doing something wrong.
I have this:
public class Musician {
public String name;
public String surname;
}
public class Instrumentist extends Musician{
public String getInstrumento() {
return instrumento;
}
public void setInstrumento(String instrumento) {
this.instrumento = instrumento;
}
private String instrumento;
public Instrumentist(String nombre, String name, String surname){
this.name = nombre;
this.surname = surname;
}
}
public class Main {
public static void main(String[] args) {
Musician m = new Instrumentist("Antonio", "Vivaldi", "none");
System.out.println(m);
}
}
I know I can do Instrumentist i = new Instrumentist("Antonio", "Vivaldi", "none")
but then what is the purpose of Cast to superclass?
The concept is like this:
The superclass/interface provides general implementation or a contract. The subclass overrides/implements that contract.
To make sure that you can assign different implementations of that contract at runtime, you use reference of a Superclass and assign object of a subclass to it.
Musician m = new Instrumentist("Antonio", "Vivaldi", "none");
Here, with m, you can call methods defined in Musician class, but if your subclass has any other methods apart from those defined superclass, you can not access them using m. If subclass overrides any method, then even after using reference of superclass, say m, java would make sure that at runtime, overridden method in subclass is called.
How to clone a Java object with the clone() method
I have a question regarding properly implementing the clone() method for a class in java.
I know that this is bad practice, but I need to know this for an exam..
In the above discussion they say to call super.clone() - but I don't udnerstand what happens if the super function doesn't implement Clonable.
For example, say I have a class X that extends Y. X implements Clonable and Y doesnl't. Y's clone() method should throw an Exception. Then what do we do in this case?
All the explanations I could find somehow assume that all superclasses implement Clonable, or at least that's what I understood..
EDIT:
Check out this code please:
public class Employee implements Cloneable {
private String name;
public Employee(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Object clone()throws CloneNotSupportedException{
return (Employee)super.clone();
}
public static void main(String[] args) {
Employee emp = new Employee("Abhi");
try {
Employee emp2 = (Employee) emp.clone();
System.out.println(emp2.getName());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
It is taken from here: https://www.javacodegeeks.com/2018/03/understanding-cloneable-interface-in-java.html
Similar code can be found in many tutorials.
Why can they use super.clone() when the superclass (which in this case is Object) does not implement Clonable - that would result in an Exception.
If you have this structure:
class Y {}
class X extends Y implements Cloneable {
#Override
public X clone() {
try {
return (X) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
}
Then clone on instances of X will work fine.
It won't work on direct instances of Y, because they are not declared cloneable. But the Cloneable interface on X is an indicator to the mechanisms of the default clone() implementation that they should be made to work.
Alternatively
You could also have a non-Cloneable class with a working clone() method, as long as you didn't rely on the default implementation of clone().
For instance:
class Y {
#Override
public Y clone() {
// Don't call super.clone() because it will error
return new Y(...); // whatever parameters
}
}
However, with this mechanism, if you called super.clone() from a subclass of Y, you would get an instance of Y, which is probably not what you would want.
As others have pointed out, the Cloneable mechanism is awkward and confusing, and usually copying mechanisms using new are easier to work with.
The Cloneable-interface is generally regarded as broken (and won't be fixed). At the core, the argument revolves around the fact that clone() is a method defined on Object, instead of being a method of the interface Cloneable.
I would not recommend using it at all. A better solution would be to provide copy-constructors. If one does not have the capability to fully recreate a parent-class object, then cloning is impossible.
Refactoring the code provided would lead to a result similar to this:
public class Employee implements Cloneable {
private String name;
public Employee(String name) {
this.name = name;
}
public Employee(Employee that) {
this.name = that.name;
}
public static void main(String[] args) {
Employee emp = new Employee("Abhi");
Employee emp2 = new Employee(emp);
System.out.println(emp2.getName());
}
public String getName() {
return name;
}
}
A remark on your code:
public class Employee {
public Object clone()throws CloneNotSupportedException{
return (Employee)super.clone();
}
}
The type cast is superfluous since the methode returns an Object.
Employee Class
public class Employee {
protected String name;
protected String jobsheetnumber;
public Employee(String n,String j){
this.name = n;
this.jobsheetnumber = j;
}
public Employee(String name)
{
this.name = name;
}
public String getName() {
return name;
}
public String getJobsheetnumber() {
return jobsheetnumber;
}
public void setName(String name) {
this.name = name;
}
public void setJobsheetnumber(String jobsheetnumber) {
this.jobsheetnumber = jobsheetnumber;
}
}
Mechanic Class
public class Mechanic extends Employee{
public Mechanic(String name,String jobsheetnumber){
super(name,jobsheetnumber);
}
}
Supervisor Class
public class Supervisor extends Employee{
public Supervisor(String name){
super(name);
}
}
Company Class [snippet]
public class Company {
private String companyname;
private String companyaddress;
private String postalcode;
private String city;
private String country;
private String telephonenumber;
private String faxnumber;
private String province;
private Employee supervisor;
private Employee mechanic;
public Company(String companyname,String companyaddress,String postalcode,String city,String country,String telephonenumber,String faxnumber,String province,String supervisorname,String jobsheetnumber,String mechanicname)
{
this.companyname = companyname;
this.companyaddress=companyaddress;
this.postalcode = postalcode;
this.city=city;
this.country=country;
this.telephonenumber=telephonenumber;
this.faxnumber=faxnumber;
this.province=province;
supervisor = new Supervisor(supervisorname);
mechanic = new Mechanic(mechanicname,jobsheetnumber);
}
Employee Class is the superclass of both Mechanic and Supervisor class .. right now i am using the attributes of Employee i.e name and jobsheetnumber in the subclasses Mechanic and Supervisor Class
the code works fine .. but what if i want to add extended functionality in Mechanic and Supervisor ? then i cannot access those variables because the reference is to the Employee type object.
is this the correct use Of Polymorphism ? that we have to use super() as the constructor each time we create a reference of Supervisor/Mechanic Object ?
can we not use extended functionality inside Supervisor and Mechanic Class ?
If you want to call a superclass non-zero-arg constructor then yes, you have to call it explicitly. If the superclass constructor has no arguments then the call will be inserted for you.
The point of polymorphism is so that objects can take care of themselves without having to have the rest of the program micro-manage them, so the outside program refers to them by a reference with the type of an interface or superclass without having to know the exact concrete type. For instance all employees might have a work method, where that work takes a different form for a supervisor than it does for a mechanic; the work method would be overridden by the specific subclasses, and might call the specific methods on the subclasses. So the company can iterate through all the employees and call work on each of them, while work is defined differently for different subclasses of employee.
(In practice using subclasses to describe roles is too inflexible to work, since an employee could have multiple roles, or those roles can change over time. It's usually better to use composition, here assigning Role objects to an Employee.)
A better use of polymorphism would be the same interface (methods) for different implementations. So you can decide which implementation will be used in runtime.
To explain my point i will give a example using your classes.
public class Employee{
public void work(int hours){ doNothing();}
}
public class Supervisor extends Employee{
private Object pen;
private Object note;
#Override
public void work(int hours){
observations = superviseWorkers();
note.write(observations, pen);
}
}
public class Mechanic extends Employee{
private Tool tool;
private TaskBoard taskBoard;
#Override
public void work(int hours){
task = taskBoard.getPendent()
if(task.canSolveWithTool(tool))
{
solveTask(task, tool)
}
}
}
Using example:
employees = new List<Employee>();
employees.add(new Supervisor("foo"));
employees.add(new Mechanic("bar"));
foreach(employee in employees){
//you don't need to know which kind of employee you are treating here because you are only calling a behavior that all employees have.
employee.work(8);
}
If in many places in your code you are trying to figure out which object you are dealing with probably you are doing it wrong.
I used your classes in my examples to facilitate your understanding but as Nathan Hughes suggested in this case would be better to use composition instead of inheritance.
I will handle above scenario in two ways.
Solution 1: ( Interface as roles)
You can have "state" in Employee object and you can implement role as interface.
Employee will have all common attributes & methods. You can override base class method like doWork() in respective Employee implementations.
You can add specific behaviour of Mechanic, Supvervisor with use of interfaces.
public interface ISupervise{
public void doSupervise();
}
public class Supervisor extends Employee implements ISupervise{
public void doSupervise(){
}
}
public interface IMechanic{
public void doMechanicWork();
}
public class Mechanic extends Employee implements IMechanic{
public void doMechanicWork(){
}
}
Solution 2: (Decorate role)
Implement Decorator pattern for Employee to play multiple roles. Mechanic and Supervisor will decorate Employee behaviour. Refer to this example for better understanding of Decorator pattern.
Sample code can be found #
When to Use the Decorator Pattern?
I'm having an issue that I can't find the right way to resolve by myself.
Basically I have two objects Object1 & Object2 where both of these have two properties of the same type:
public class Object1 {
...
private String name;
private String description;
...
Object1 () {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
public class Object2 {
...
private String name;
private String description;
...
Object2 () {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Now obviously I made them properties as strings here in the example but in reality they're other types.
NOTE: Object1 and Object2 are actually generated classes from XML models that I need for SOAP servces. So I can't modify them.
In some point in my code I have to access say the 'name' property of either Object1 or Object2 depending on different factors. This point is an event handler so in a certain moment of time it catches an event called with Object1 and other times with Object2.
My guess was to make a single class that would enclose both these types and expose one single "name" property and one single "description" property.
What would a standard way of doing this be?
There basically are two ways to do this:
Use a common interface that expose the getters and setters. Then let both classes implement that interface and let the handler use it.
If possible (both objects don't already extend other superclasses) you could use an abstract superclass and put the properties as well as the getters and setters there. The handler then uses that superclass.
Note that both approaches can be combined, i.e. use an interface for the handler and use an abstract superclass that implements that interface as an adapter class, i.e. you could extend that adapter when possible or just implement the interface when extending the adapter is not possible.
Example:
interface Common {
String getName();
}
abstract class CommonAdapter implements Common {
String name;
String getName() {
return name;
}
//setter as well
}
//just extend the adapter and enjoy
class Object1 extends CommonAdapter {
//specific code for Object1
}
//extending not possible, so implement the interface directly
class Object2 extends SomeOtherClass implements Common {
String name;
String getName() {
return name;
}
}
class Handler {
void handle( Common c ) {
c.getName();
...
}
}
Update:
If the classes are generated, you could create those objects as wrappers and delegate all calls to the actual class, e.g.
class Object1CommonWrapper implements Common {
Object1 delegate;
String getName() {
return delegate.getName();
}
}
make an abstract class and let both classes extend from it
Use interface or abstract class
public interface CommonObject {
//gettter and setter
}
public Class Object1 implements CommonObject { ... }
public Class Object2 implements CommonObject { ... }
public Class MainClass {
public void someMethod() {
if(someCondition) {
CommonObject obj1 = new Object1();
//use obj1
} else {
CommonObject obj2 = new Object1();
//use obj2
}
}
}
Use factory pattern
it depends a bit on the behaviour of said methods. So if:
Both Object1/ Object2 have the absolut identical code for those methods i would go with inheritance, have a superclass that defines those fields/ methods and the two objects extend it.
Both Object1/ object2 must have the same method signature but have to handle the internal logic in different ways i would go with a interface defining the method signature that both Object1/2 must implement.
You can define an interface that both Object1 and Object2 implement. The interface would include the methods that you need to call, but each class can implement them in its own way.
For example, it might look something like this:
public interface Describable {
String getName();
String getDescription();
}
public class Object1 implements Describable {
... implements the methods in some way
}
public class Object2 implements Describable {
... implements the methods in another way
}
With that, whatever code needs to deal with both of these types of objects can refer to them as Describable and take advantage of polymorphism. For example:
Describable eventObject = ...get the object...
eventObject.getName();
eventObject.getDescription();
Or even something like:
public void handle(Describable describable) {
describable.getDescription();
... more stuff...
}
That code doesn't know (or care) what type of object is actually passed in to the method, only that it can interact with it as a Describable.
This is a common idiom in Java and OO design in general. The core libraries use it all over the place.
By the way, inheritance (ie, using a common base super class) is another option. Just be aware that the technique of implementation inheritance has some trade-offs and is often abused/misused. For example see this discussion.
When i try to clone a generic Object i get compile time error . why?
Object obj=new Object();
obj.clone(); // Here compile time error "The method clone() from the type Object is not visible"
Every class extends Object class and clone method is protected in Object class.
protected methods can be accessed in same package as well as by subclasses and all classes are child of java.lang.Object.
Because clone is protected in the Object class. It's not public.
The only way to get access to an object's clone() method is to know it has a compile-time type that has a public clone() method.
This will be the minimum to get clone working:
public class SubObj implements Cloneable {
public Object clone() { return super.clone(); }
}
Per the Java SE docs:
The class Object does not itself implement the interface Cloneable, so
calling the clone method on an object whose class is Object will
result in throwing an exception at run time.
protected fields can be accessed only from inside the same package, thus clone() method of Object class can be accessed only from any class that is located in java.lang package.
You must explicitely implements Cloneable interface.
see this thread which give explanations.
If you use Groovy so that you can bypass the java compilation error, you get this:
Exception in thread "main" java.lang.CloneNotSupportedException: java.lang.Object
at java.lang.Object.clone(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:912)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:756)
at org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:766)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:754)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:170)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethod0(ScriptBytecodeAdapter.java:198)
at regexTests.main(regexTests.groovy:19)
ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2
JDWP exit error AGENT_ERROR_NO_JNI_ENV(183): [../../../src/share/back/util.c:820]
If you read the clone API (I will link it) it says that if the Interface isn't implemented, then calling *.clone() will throw a CloneNotSupportedException.
Link to the clone API for java.lang.Object
http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#clone%28%29
[EDIT]
The Original Question™ asked for why this method is visible in the way it is. This is because it only accessible to methods within the java.lang package. It isn't intended for a programmer to be able to clone an Object. Throwing a CloneNotSupportedException is exactly what you want to do if you don't want your OWN object cloned.
void method() {
Object obj=new Object(); //Object is a parent class, it's not inherit from any other class...
obj.clone(); // compile time error
}
We can't access the protected method of "Has A" relationship from different package, because your Class package is (com.xxx.yyy) and an Object class package is (java.lang) both the classes are in different package.
protected methods can be accessed in same package as well as by subclasses(IS A relationship)
I tried this code :
public final class User {
private String name;
private boolean isActive;
private String userId;
private Address address;
// can be constructed using this constructor ONLY !
public User(String name, boolean isActive, String userId, Address address) {
this.name = name;
this.isActive = isActive;
this.userId = userId;
this.address = address;
}
public String getName() {
return name;
}
public boolean isActive() {
return isActive;
}
public String getUserId() {
return userId;
}
public Address getAddress() {
return address;
}
protected Object cloneMe() throws CloneNotSupportedException {
return super.clone(); // throws CloneNotSupportedException
}
}
public class CloneNotSupportedException
extends Exception
Thrown to indicate that the clone method in class Object has been
called to clone an object, but that the object's class does not
implement the Cloneable interface. Applications that override the
clone method can also throw this exception to indicate that an object
could not or should not be cloned.
Object doesn't implement any interface and to make my User class work it must implement Cloneable
Object class clone() method has modified by protected access modifier in the API level. So we can't access it anywhere without inheritance. So before we invoke object class clone() method you need to implements Cloneable interface. Then Code will run at runtime properly. Otherwise it will generate CloneNotSupportedException at runtime.
/*Subclass is my implementing class */
public class SubClass implements Cloneable {
#Override
public SubClass clone() throws CloneNotSupportedException {
return (SubClass) super.clone();
}
}
import java.util.Scanner;
import java.util.jar.Attributes.Name;
import java.util.Arrays;
public class Main{
public class man{
protected void name() {
System.out.println("hei");
}
}
public class people extends man{
public int age;
public int getAge() {
name();
return age;
}
public void setAge(int age) {
this.age = age;
}
#Override
public String toString() {
return "people [age=" + age + "]";
}
public Object myclone() throws CloneNotSupportedException {
return this.clone();
}
}
public void test() throws CloneNotSupportedException {
people p1 = new people();
p1.setAge(10);
System.out.println(p1);
// NG:
people p2 = (people)p1.clone();
// Ok
people p3 = (people)p1.myclone();
p1.setAge(10);
System.out.println(p1);
System.out.println(p2);
}
public static void main(String args[]) throws CloneNotSupportedException{
new Main().test();
}
}
see the NG code and ok code.
// NG for:The method clone() from the type Object is not visible
people p2 = (people)p1.clone();
// Ok
people p3 = (people)p1.myclone();
why?
cause test() is not belong to the subclass.
so even though call clone() by peopel object p1,it is not the place of peopel object.
The myclone() is the exactly the place of people object.