I have classes Osoba(Person) and Zawodnik(Constestant)
Contestant extends Person and Person implements Serializable. Does Constestant automatically implements Serializable too? I think so.
The extension (ArrayList ekstensja) of class Person contains objects of different classes extending class Person. Will the method zapiszEkstensje() in the Person class work correctly? I think so.
Example:
public abstract class Osoba implements Serializable {
/....something..../
private static ArrayList<Osoba> ekstensja = new ArrayList<Osoba>();
private void dodajZawodnik(Osoba osoba) {
ekstensja.add(osoba);
}
private void usunZawodnik(Osoba osoba) {
ekstensja.remove(osoba);
}
public static void pokazEkstensje() {
for (Osoba zawodnik : ekstensja)
System.out.println(zawodnik + "\n");
}
public static void zapiszEkstensje() {
try {
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("osoba.ser"));
outputStream.writeObject(ekstensja);
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
#SuppressWarnings("unchecked")
public static void wczytajEkstensje(){
try {
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("osoba.ser"));
ekstensja = (ArrayList<Osoba>) (inputStream.readObject());
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class Zawodnik extends Osoba { }
// DO I NEED TO MAKE THIS CLASS IMPLEMENT SERIALIZABLE TOO?
According to java doc of Serializable interface, all the subtypes of a serializable class are themselves serializable.
So, the answer is yes, if Person implements Serializable all its children will be serializable.
Related
I'm trying to create an object using reflection like this
(maybe this is not a good architecture but I'm just doing some tests)
package com.interfaces;
public interface IEmployee {
List<entities.Employee> getEmployees();
}
then
package com.personnel;
public class Employee implements IEmployee{
public Employee(){}
public List<entities.Employee> getEmployees(){
...
}
}
then in another class
package com.factory;
import java.lang.reflect.Constructor;
public final class EmployeeFactory {
private static String path = "com.personnel";
public EmployeeFactory() {}
public static interfaces.IEmployee CreateEmployee(){
String className = path + ".Employee";
try {
Class<?> cls = Class.forName(className);
Object object = cls.newInstance();
return (interfaces.IEmployee)object;
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
}
then in another class
public final class PersonnelService {
private static interfaces.IEmployee employeeFactory = com.factory.EmployeeFactory.CreateEmployee();
public List<entities.Employee> getEmployees(){
return employeeFactory.getEmployees();
}
}
finally in my main method
public static void main(String[] args) {
List<entities.Employee> employees = new com.services.PersonnelService().getEmployees();
for(entities.Employee employee : employees){
System.out.println(employee.getEmployeeName());
}
when the code arrives to Class cls = Class.forName(className) it throws the exception message "com.personnel.Employee.(java.lang.String)" with "NoSuchMethodException".
UPDATE
I found the problem. In fact, it was a bad naming convention. I had a serializable Employee class (my pojo) and an Employee class which implements my interface IEmployee which is intended to perform DB operations. I renamed this last one as EmployeeDAL and it worked. Even I defined the full class name as you can see in the example, it looks like that I was trying to instantiate my serializable pojo (I still don't get it, but...). Thanks for your time.
I tried to reproduce your code and not found any error on this code. I only get NoSuchMethodException message when I change Employee constructor with String argument
package com.agit.example.test;
import java.util.ArrayList;
import java.util.List;
public class TestClass {
public static void main(String[] args) {
List<Employee> employees = new PersonnelService().getEmployees();
for(Employee employee : employees){
System.out.println(employee);
}
}
}
interface IEmployee {
List<Employee> getEmployees();
}
class Employee implements IEmployee{
public Employee(){}
public List<Employee> getEmployees(){
List<Employee> x = new ArrayList<>();
x.add(this);
return x;
}
}
final class EmployeeFactory {
private static String path = "com.agit.example.test";
public EmployeeFactory() {}
public static IEmployee CreateEmployee(){
String className = path + ".Employee";
try {
Class<?> cls = Class.forName(className);
Object object = cls.newInstance();
return (IEmployee)object;
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
}
final class PersonnelService {
private static IEmployee employeeFactory = EmployeeFactory.CreateEmployee();
public List<Employee> getEmployees(){
return employeeFactory.getEmployees();
}
}
I am getting a issue i have below code
public void columnsList(List<TableRecord> records){
for(TableRecord record : records){
Table table = record.getTable();
//Do sort here on stampDate
Field[] fields = table.fields();
for(Field field : fields){
field.getName();
record.getValue(field);
}
}
}
and records object contain Object of different class type
List<TableRecord> records = new List<TableRecord>();
records.add(new AddressRecord());
records.add(new CityRecord());
records.add(new UserRecord());
Now how i need to sort them by stampDate variable which is in each class how can we do it when we have different classes in list
If your code above is correct, that means AddressRecord, CityRecord and UserRecord all extend TableRecord:
class AddressRecord extends TableRecord {
// other fields and methods here
}
class CityRecord extends TableRecord {
// other fields and methods here
}
class UserRecord extends TableRecord {
// other fields and methods here
}
You only have to write a Comparator for this class. It should look something like this:
class TableRecord {
private Date timeStamp;
public Date getTimeStamp() {
return timeStamp;
}
// other fields and methods here
}
class RecordStampDateComparator implements Comparator<TableRecord>{
public int compare(TableRecord tr1, TableRecord tr2) {
Date tr1Date = tr1.getTimeStamp();
Date tr2Date = tr2.getTimeStamp();
return tr1Date.compareTo(tr2Date);
}
}
If you can't change the classes write your comparator( Comparator<Object>), that will try to find the field stampDate and compare them. Than use it for sorting the list.
Comparator implementation:
import java.util.Comparator;
import java.util.Date;
public class StampDateComparator implements Comparator<Object> {
#Override
public int compare(Object o1, Object o2) {
try {
Date d1 = (Date) o1.getClass().getDeclaredField("stampDate").get(o1);
Date d2 = (Date) o2.getClass().getDeclaredField("stampDate").get(o2);
return compare(d1, d2);
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Missing variable stampDate");
}catch (ClassCastException e) {
throw new RuntimeException("stampDate is not a Date");
} catch (IllegalArgumentException e) {
//shoud not happen
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
Just write abstract class Record with protected field stampDate, that implements Comparable and override compareTo method.
public abstract class Record implements Comparable<Record> {
protected Date stampDate;
#Override
public int compareTo(Record anotherRecord){
return this.stampDate.compareTo(anotherRecord.stampDate);
}
}
Then extend this class with your record classes:
public class AddressRecord extends Record{
...
}
public class CityRecord extends Record{
...
}
public class UserRecord extends Record{
...
}
Use following Comparator class on List.
class TableRecordCompare implements Comparator<TableRecord>{
if(TableRecord instanceof AddressRecord){
// return compareTo for sample data of address.
}
else if(TableRecord instanceof CityRecord){
// return compareTo for sample data of CityRecord.
}
else{
// return compareTo for sample data of UserRecord.
}
}
In java serialization class Mp3player extends ElectronicDevice implements Serializable in this code super class electronicdevice is not implemented serializable. here super class is also getting serialized. my understanding is super class is also gets serialized due to extends.let me know my understanding is correct or not.
import java.io.*;
class ElectronicDevice {
ElectronicDevice()
{
System.out.print("ed ");
}
}
class Mp3player extends ElectronicDevice implements Serializable {
Mp3player()
{
System.out.print("mp ");
}
}
class MiniPlayer extends Mp3player {
MiniPlayer()
{
System.out.print("mini ");
}
public static void main(String[] args) {
MiniPlayer m = new MiniPlayer();
try {
FileOutputStream fos = new FileOutputStream("dev.txt");
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(m); os.close();
FileInputStream fis = new FileInputStream("dev.txt");
ObjectInputStream is = new ObjectInputStream(fis);
MiniPlayer m2 = (MiniPlayer) is.readObject();
is.close();
System.out.println();
} catch (Exception x) {
System.out.print("x ");
}
}
}
No.During the process of serialization only the fields of Serializable objects are written out and restored.
According to javadocs
During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class.
Where as the fields of serializable subclasses will be restored from the stream.
Please look into this example
Here ElectronicDevice is not Serializable,where as Mp3player is Serializable.Observe the fields of respected classes behaviour in serialization process.
import java.io.*;
class ElectronicDevice {
public int i = 0;
protected ElectronicDevice()
{
System.out.println("ed ");
}
}
class Mp3player extends ElectronicDevice implements Serializable {
int j =0;
Mp3player()
{
System.out.println("mp ");
}
}
class MiniPlayer extends Mp3player {
MiniPlayer()
{
System.out.println("mini ");
}
public static void main(String[] args) {
MiniPlayer m = new MiniPlayer();
m.i = 30;
m.j = 40;
try {
System.out.println("i value before serialization: "+m.i);//prints 30
System.out.println("i value before serialization: "+m.j);//prints 40
FileOutputStream fos = new FileOutputStream("dev.txt");
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(m); os.close();
FileInputStream fis = new FileInputStream("dev.txt");
ObjectInputStream is = new ObjectInputStream(fis);
MiniPlayer m2 = (MiniPlayer) is.readObject();
is.close();
System.out.println("i value after serialization: "+m2.i);//prints o
System.out.println("j value after serialization: "+m2.j);//prints 40
System.out.println();
} catch (Exception x) {
x.printStackTrace();
System.out.print("x ");
}
}
}
Since super class doesn't implement Serializable contents of the super class wont get serialized. Only the contents of the subclass would get serialized. When you deserialize the default constructor of the superclass would get executed and the fields of the superclass initialized as if you invoked the default constructor.
Following example illustrates this.
public class SerializationTest {
public static class Base {
private String name;
public Base() {
this.name = "johnDow";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static class Sub extends Base implements Serializable {
private static final long serialVersionUID = 1L;
private String age;
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
public static void main(String[] args) throws Exception {
ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteArrayOS);
Sub s = new Sub();
s.setName("name");
s.setAge("10");
out.writeObject(s);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(byteArrayOS.toByteArray()));
Sub d = (Sub) ois.readObject();
System.out.println(d.getName() + "-" + d.getAge());
}
}
What gets printed is
johnDow-10
This is the rule for superclass serialization:
If you are a serializable class, but your superclass is NOT
serializable, then any instance variables you INHERIT from that
superclass will be reset to the values they were given during the
original construction of the object. This is because the
nonserializable class constructor WILL run.
Therefore, if you add some instance variables to ElectronicDevice, be aware that the superclass 's state will be not serialized. (unless the superclass implements Serializable)
my understanding is super class is also gets serialized due to
extends.let me know my understanding is correct or not.
The short answer is NO.
In java, every class is a subclass of Object. Does Object itself implement Serializable?
To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields”
Reference -
http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
Is there a way to implement something like
List<Class<? implements MyInterface>> ClassList = new ArrayList<Class<? implements MyInterface>>();
my goal is to create a hashmap from that list, where the keys are the toString methods of the class (defined in MyInterface) and the values are the classes itself. The toString method of every object of this class returns the same result. This way I could create Instances of the classes using the map by searching the right strings.
thank you for trying to help,
greetings
List<Class<? implements MyInterface>> ClassList = new ArrayList<Class<? implements MyInterface>>();
should be
List<Class<? extends MyInterface>> ClassList = new ArrayList<Class<? extends MyInterface>>();
there is no implements keyword in the world of generics. if you want a type parameter that implements an interface , use the extends keyword to represent it.
Since you seem interested by the way I explained, here is a quick implementation, to verify it can be done...
import java.util.ArrayList;
import java.util.List;
enum NumberClass
{
ONE("One"),
TWO("Two"),
THREE("Three");
private final String className;
NumberClass(String name)
{
className = name;
}
String getName()
{
return className;
}
}
public class Test
{
public static void main(String[] args)
{
List<NumberClass> numbers = new ArrayList<NumberClass>();
numbers.add(NumberClass.ONE);
numbers.add(NumberClass.THREE);
numbers.add(NumberClass.TWO);
numbers.add(NumberClass.ONE);
numbers.add(NumberClass.THREE);
numbers.add(NumberClass.ONE);
numbers.add(NumberClass.TWO);
SomeNumber[] nbs = new SomeNumber[numbers.size()];
int i = 0;
for (NumberClass nbC : numbers)
{
SomeNumber nb;
try
{
nb = (SomeNumber) Class.forName(nbC.getName()).newInstance ();
nbs[i++] = nb;
}
// Cleanly handle them!
catch (InstantiationException e) { System.out.println(e); }
catch (IllegalAccessException e) { System.out.println(e); }
catch (ClassNotFoundException e) { System.out.println(e); }
}
for (SomeNumber sn : nbs)
{
System.out.println(sn.getClass().getName() + " " + sn.getValue());
}
}
}
// The following must be in their own files, of course
public interface SomeNumber
{
int getValue();
}
public class One implements SomeNumber
{
public int getValue() { return 1; }
}
public class Two implements SomeNumber
{
public int getValue() { return 2; }
}
public class Three implements SomeNumber
{
public int getValue() { return 3; }
}
If it doesn't answer your question, consider it as educational material, I hope. :-)
public abstract class Parent {
private Parent peer;
public Parent() {
peer = new ??????("to call overloaded constructor");
}
public Parent(String someString) {
}
}
public class Child1 extends parent {
}
public class Child2 extends parent {
}
When I construct an instance of Child1, I want a "peer" to automatically be constructed which is also of type Child1, and be stored in the peer property. Likewise for Child2, with a peer of type Child2.
The problem is, on the assignment of the peer property in the parent class. I can't construct a new Child class by calling new Child1() because then it wouldn't work for Child2. How can I do this? Is there a keyword that I can use that would refer to the child class? Something like new self()?
I'm not sure if it is possible to do this without running into cycles. I am convinced that it would be a lot clearer to write this using factory methods instead of constructors.
public abstract class Parent implements Clonable{
private Object peer;
// Example 1
public Parent() {
try {
peer = this.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
// Example 2
public Parent(String name) {
try {
peer = this.getClass().getConstructor(String.class).newInstance(name);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public <T extends Parent> T getPeer() {
return (T)peer;
}
}
public class Child01 extends Parent { }
public class Child02 extends Parent { }
It seems that the code may be more simple.
I'll start by saying that I think it's probably a really bad design. And the class names are also bad, but I'll stick with them.
However, one way of dealing with it:
public abstract class Parent {
interface PeerFactory {
Parent create(Parent peer);
}
private final Parent peer;
protected Parent(Parent peer) {
super();
this.peer = peer;
}
protected Parent(PeerFactory peerFactory) {
super();
this.peer = peerFactory.create(this);
}
}
public class Child1 extends parent {
private static final PeerFactory peerFactory = new PeerFactory {
public Parent create(Parent peer) {
return new Child1(peer);
}
};
public Child1() {
super(peerFactory);
}
private Child1(Peer peer) {
super(peer);
}
}
Something like this:
public class Peer {
public static abstract class Parent {
private Parent peer;
protected Parent(boolean needPeer) {
if (needPeer) {
try {
peer = getClass().newInstance();
}
catch (Throwable e) {
System.err.println(e);
}
}
}
public String getPeerClass() {
return peer.getClass().toString();
}
}
public static class Child1 extends Parent {
public Child1() {
this(false);
}
public Child1(boolean needPeer) {
super(needPeer);
}
}
public static class Child2 extends Parent {
public Child2() {
this(false);
}
public Child2(boolean needPeer) {
super(needPeer);
}
}
public static void main(String[] args) {
Parent p1 = new Child1(true);
Parent p2 = new Child2(true);
System.out.println(p1.getPeerClass());
System.out.println(p2.getPeerClass());
}
}
This one works with default constructor, there's a bit more trickery involved if you want to construct a new peer with a non-default constructor. See The javadoc for Class.
Edit: fixed the infinite recursion :)
Note that without an accessor in the parent class you cannot get the peer object (you cannot instantiate Parent), so this design only makes sense as concept proof.
I would suggest replacing this whole thing with a Factory pattern, where you have complete control over what gets a peer added and you don't have to do it in the constructor.
Replying for answer of Leonid Kuskov
Your example 2 will always throw a StackOverflowException. I fiddled around with the code a bit an below is the correct implementation for that. Though thanks to you to give me pointers in that direction.
public class AbstractClassDemo {
public static void main(String[] args) {
Child1 c1 = new Child1();
System.out.println(c1.getPeer().getClass().getName());
}
}
abstract class Parent {
private Object peer;
public Parent() {
}
public Parent(String s) {
try {
setPeer(this.getClass().getConstructor(String.class)
.newInstance(""));
} catch (Exception e) {
e.printStackTrace();
}
}
public Object getPeer() {
return peer;
}
public void setPeer(Object peer) {
this.peer = peer;
}
}
class Child1 extends Parent implements Cloneable {
public Child1() {
super("Child1");
}
public Child1(String child1) {
}
}
class Child2 extends Parent implements Cloneable {
public Child2() {
super("Child2");
}
public Child2(String child2) {
}
}
public abstract class Parent implements Clonable {
private Object peer;
// Example 1
public Parent() {
try {
peer = this.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
// Example 2
public Parent(String name) {
try {
peer = this.getClass().getConstructor(String.class).newInstance(name);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public <T extends Parent> T getPeer() {
return (T)peer;
}
public class Child01 extends Parent { }
public class Child02 extends Parent { }
public abstract class Parent {
private Parent peer;
public Parent(Parent peer) {
this.peer = peer;
}
public Parent(String someString) {
}
}
public class Child1 extends parent {
public Child1() {
super(new Child1())
}
}
public class Child2 extends parent {
public Child2() {
super(new Child2())
}
}
Here's the simplest way I can think of. You could probably do it in the parent class using some of the java reflection API though (so ask the 'this' reference what class it is and construct a new class of that type. It may not work depending on how java constructors work though. In C++, the 'this' pointer in a constructor is of the same type as the constructors class)