Well, option 1 creates an unnecessary ArrayList object when you call the second constructor. In most cases that won't make much of a difference, but still - I don't like it, if only from an esthetical point of view.
But what I would actually use is
BTW, neither option 2 nor option 3 have anything to do with lazy initialization. That would be option 4:
In most cases that is total overkill.
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
I think there's a more subtle issue which is quite possibly far more significant. All the code so far is accepting a List argument, exact type unknown, and then using that same List for... something. We don't know. What operations are going to be performed on it? None are shown. I would have to guess that add() is one, because otherwise, what possible use would there be for creating an instance with an empty list? So, you want to add() at least - but how do you know that the List you've been passed even supports add()? It's an optional method, after all. Maybe the user used Arrasy.asList(), or Collections.unmodifiableList(), to create a List that you can't add to. Oops.
Alternately, what if they passed you a LinkedList, and you need to use get(int) frequently? (LinkedList's get(int) gives very poor performance if the list is large.) Or what if they gave you an ArrayList, and you need to insert or remove many things at the beginning of the list? (Here, ArrayList is very poor, but LinkedList works well.)
So I'd say it's a potentially serious problem if this class is accepting an unknown list and simply using it. Maybe you know for sure what kind of List is being passed in - or think you do. But another programmer may try to do something different with the code tomorrow. Or you may, a few weeks later when you don't remember all the details of this class.
I think a better solution overall is to create a List of your own - for now, assume ArrayList is indeed the best option - and copy the content of any other list into the ArrayList:
This is actually a little slower than the other options, initially, as it spends a little extra time to copy content from one List to another. But this effect is still probably minor - and the advantage is, now you know what kind off List you have inside your class, and it supports all the opional methods you may need (like add()). And if you need to change the type later, you can, because it's defined here inside this class, not outside in client code somewhere.
"I'm not back." - Bill Harding, Twister
I’ve looked at a lot of different solutions, and in my humble opinion Aspose is the way to go. Here’s the link: http://aspose.com