I am looking to pass an array of object from activity to activity in Android. I understand that the optimal way to do this is having your passed objects implement Parcelable or Serializable, as explained here.
However, if I am passing an array of these objects, will this still work, considering you are now passing an array of objects that implement those interfaces, rather than the object itself? If not, would I instead need to extend a class such as ArrayList and implement these interfaces, and pass that 'array' object instead?
As I understand it, calling serialize on an array causes the array to recursively call serialize on its members. However, it appears there may be a bug affecting this in Android versions prior to 5.0.1 https://stackoverflow.com/a/28720450/1541763
It seems that parceling an array follows this logically, but that unmarhsalling is a little more complicated: https://stackoverflow.com/a/10781119/1541763
Related
This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
I’m hoping to get some clarification on a topic which I find very confusing: The relationship between ArrayList / List / ObservableList, which also ties into the differences between Classes and Interfaces. I’ve read multiple texts on the subject, and the more I read, the more confused I become.
Here’s what I do know for certain: ArrayList is a Class, which means you can create as many ArrayList objects as you like. (This is good news for me, because I love working with them.) I’m also learning JavaFX, and there’s a lot of FX objects which take ObservableLists as input. But ObservableLists are Interfaces, not Classes, so forget about creating any ObservableList objects. At first, I assumed that ArrayList was a child class of List, and ObservableList is an Interface to List & any List child Classes. …But reading further, I see that List is actually an Interface, not a Class, and the parent Class of ArrayList is AbstractList. So that didn’t clear up a lot for me.
Another bit that is driving me crazy: In another forum post, a wiser coder gave me this snippet of code to help my ArrayLists accessible via the ObservableList interface:
List<myClass> myList = new ArrayList<myClass>();
While this method of declaring and initializing an ArrayList compiles and works great, I just plumb don’t understand what is going on here. I thought List was an Interface, not a Class, so how can I create a myList object of type List? If I had to guess, I’d suppose that there is an Interface named List and another, separate Class named List, and due to the context here, Java assumes I am referring to the Class.
On a side question, is there a recommended website or text that people could recommend I consult on this topic? I’ve read “Java in a Nutshell,” the Oracle website, different posts on this site, “Java for Dummies,” and “Java in a Nutshell Examples,” but no illumination yet. Any guidance on understanding this topic is wildly appreciated.
Many thanks!
-RAO
Brief (so brief) resume:
java.util.List is an Interface. That is, defines the contract that all clases implementing that interface should code (except abstract classes)
java.util.ArrayList is a class that implements that interface
As you can't instantiate any interface, you must use the implementing classes (f.i. ArrayList) but, you can manage that as an interface and no matter what is the real class behind it. You just know that your class implements all methods in the interface.
So,
List<myClass> myList = new ArrayList<myClass>();
Just means that you're instantiating a List (actually an ArrayList) and that means that you're going to manage that list through the methods defined in the java.util.List interface
Check this link for complete information about working with interfaces
If several books and articles haven't helped you, maybe a different perspective will. Let's take a look at the statement you've outlined:
List<myClass> myList = new ArrayList<myClass>();
You're not actually instantiating a List here. You're instantiating an ArrayList, and referencing that object with a reference of type List. This means that when you're working with myList, the compiler will treat the object as a List even though the Object it's referencing is an ArrayList. This line compiles because the compiler looks to the instantiation versus the reference type and says, "Yes, this ArrayList is a List, and so this is legal.(Doing this allows you to ensure type safety by always havingmyListconform to typeList, no matter what kind ofList` it references).
An ArrayList is a List because it implements the List interface. However, interfaces don't define their methods. So what happens when we do this?
myList.add(myObj);
Here's a simplified version of how it happens. The compiler looks at myList.add and says "Yes, myList is a List, and List has a method add, and so this code works." Well, List doesn't define how it works (the method is essentially abstract), so when this action is actually run, it looks to the type of list the object is, ArrayList, which tells the machine to add the object to the end of the list. And so it does. (This is also why you must define every method of an interface when implementing it.)
I can't say this story-form answer is completely accurate but it might help things click for you.
Hello i am trying to create a class called ParcelableObject in which i implement the Parcelable interface.
Then i will create other objects, which they will extend ParcelableObject.
I am doing it because i don't want to write the methods of Parcelable interface in each object.
As for now i have managed to do this for Objects containing other Objects (which all of them extend the ParcelableObject class) and for primitive Types.
I am having troubles doing it for Arrays and List of primitive Types and of course Arrays and Lists of Objects
I intend to expand this to cover Lists, Arrays.
The way i did it is by getting all the fields of the object given
So here is my question.
First of all
Is this possible?
Second i tried to expand it for arrays or lists of primitive types and i fail to do it.
To be more specific. Now i am trying to expand it to Arrays of Integers, or Lists of Integers.
As i see i fail to read from the parcel a List of Integers because i get cast errors etc.
So any help would be grateful.
Also the basic idea around this is to store to the ParcelableObject the object of its subclass.
Then if i get an object (not primitive type) i write its class name to parcel and then the object.
So when i want to read an object from the parcel, i read first the string with its class name, make a new instance of the class using (Class.forName() etc) and then assign the object read from parcel to the Object instantiated above. If there is any better way to get the Class Name of the ParcelableObject's subclass other than filling the parcel unnecessary Strings id like to know.
Here is the ParcelableObject.java
You can download the whole android ParcelableObject project to test it. Demonstration is included.
Tested it under virtual device Nexus S (4.2). Project is targeted to work for 4.0 and above.
https://github.com/tchar/ParcelableObject/blob/master/ParcelableObject/src/com/parcelableobject/ParcelableObject.java
UPDATE*** Added Support for primitive Object Lists.
Still having problems with primitive types (int, etc) not with Integers and list of ParcelableObjects
Thanks in advance.
In java.util.Arrays there is a private static class called "ArrayList" defined.
It is only referred from Arrays.asList method.
What is the benifit of doing this?
Why is java.util.ArrayList not referred instead?
Code below:
/**
* #serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
Despite the fact that the private static ArrayList class shares the same name as java.util.ArrayList, they behave differently by design. Given that, there's no reason that the implementations should be one and the same.
Arrays#asList() returns a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.) This method acts as bridge between array-based and collection-based APIs.
What is the benefit of doing this? Why is java.util.ArrayList not referred instead?
One reason is that the actual implementation class is not a public API detail. Doing this means that they can change the implementation class it in the future ... without any risk of breaking customer code.
Another reason for doing this is that this private class implements some operations differently to ArrayList. In particular operations that would involve changing the size of the list need to be implemented to throw an exception ... in order to conform to the behavior specified in the javadocs for the Arrays.asList(...) method.
In reality, the list returned by Arrays.asList(...) is a wrapper for the original array, and not a full-function, free-standing list. This is has advantages and disadvantages:
On the down-side, certain operations don't work; e.g. adding and removing elements.
On the up-side, creating a wrapper is a lot cheaper than creating a first-class list out of an array. (The latter entails copying the array contents into the list ... and that will be expensive for a large array.)
Also, there is the issue that changes to the original array are visible via the wrapper (and vice versa) ... which can be useful if that is what you need.
You asked this in a comment:
a) Why return non resizable list?
Because returning a regular resizable list entails copying the array contents at some point... which is expensive. (And if the implementation deferred the copying until a size-changing operation was performed, the relationship between the original array and the list would be really difficult to understand. Think about it ...)
b) Why not use Collections.unmodifiableList and pass the java.util.ArrayList object?
That doesn't achieve anything. You still have to copy the array contents to the ArrayList. The whole point of this "strange" behavioral spec is to avoid the need to copy.
Suppose I have an Employee class. How can I implement an ArrayList only containing Employee elements without using generics? That is, without Arraylist<Employee>, how can I restrict the ArrayList to add only Employee objects?
Extend ArrayList and customize add() and addAll() method to check the object being added is instanceof Employee
You could use a wrapper class that holds a private ArrayList field, say called employeeList, has a
public void add(Employee employee) {
employeeList.add(employee);
}
as well as any other necessary methods that would allow outside classes to interact with the ArrayList in a controlled fashion.
I find it much better to use composition for this than inheritance. That way if you wanted to change from an ArrayList to something else, say a LinkedList, or even something completely different, you would have an easier time.
You could use Collections.checkedList() - but why would you want to not use generics?
Subclass the ArrayList class and name it something like EmployeeArrayList.
If you're wanting to avoid generics for their own sake, e.g. for compatibility with very old versions of Java, then extending or wrapping ArrayList won't help - you probably want to find or make another array implementation that has the same functionality.
Basically, ArrayList is just a wrapper for a primitive array that copies and pastes its data into a larger array when necessary, so this isn't especially difficult to write from scratch.
What exactly do you want when you "restrict"? There are two possible places where one could place a restriction: at compile-time or runtime.
Generics is a purely compile-time thing. It helps you write correct code but you can still bypass it and put the wrong type in the array and it won't complain at runtime.
On the other hand, something like Collections.checkedList()is a runtime restrictions. It throws an error at runtime when an object of the wrong type comes. But it does not help you at compile-time if you do not have generics.
So the two things are orthogonal, and neither is a replacement for the other. What exactly do you want?
I am using an API that gives access to a certain set of subclasses with a common interface. I use the interface throughout my code, and the instances are resolved to the proper subclass based on user needs. My problem is that I need to create a copy of one of these objects, but I don't have access to the clone() method and the API doesn't provide a copy constructor.
ie:
ObjectInterface myObject = objectFromParameter.clone(); //Not possible...
Is there a workaround in Java?
iYou might be able to do what you want with reflection. Alternatively, If the object supports serialization, you can serialize to a byte array and then reconstruct a new instance from that.