If you have a constructor that receives a list, there is no way to call it without having a list (unless you pass null
, of course, but I don’t think that’s the point).
So the answer to "It is possible to pass an array (or list) by parameter without instantiating it?" is nay. In fact, if you need to pass whichever object as parameter (assuming it will not pass null
), you will need, at some point, to instantiate it. There is no escape from this.
The answer you accepted uses Arrays.asList
, and that method also instance a list. Just because you didn’t instantiate the list directly doesn’t mean it’s not being instantiated elsewhere.
In fact the most you got with Arrays.asList
was to save one or two lines of code (as you didn’t need to create the list before). But you’re still instantiating a list.
But all right, maybe what you meant is that you just wanted to save those lines even (without having to create the list directly), and expressed yourself badly by saying "without instantiating it", but it’s good to make it clear that yes, the list is being instantiated (and I’m sorry to be so repetitive, but I thought it was important to emphasize this...)
There’s another detail: Arrays.asList
returns an immutable "more or less" list. So if you try to add elements in the list, it will give error. For example, if the class User
have a method to add another Role
:
public class User {
public User(String email, String password, List<Role> roles) {
this.password = password;
this.email = email;
this.roles = roles;
}
public void addRole(Role role) {
this.roles.add(role);
}
}
...
User user = new User(email, password, Arrays.asList(role1));
user.addRole(role2); // erro!
This code launches a UnsupportedOperationException
, for the list returned by Arrays.asList
does not allow new elements to be added (the same error occurs if trying to remove elements from the list). But as I said, the list returned by Arrays.asList
is "more or less" immutable, since it allows you to change an existing element. For example:
public class User {
...
public void mudaRole(Role role, int posicao) {
this.roles.set(posicao, role);
}
}
...
User user = new User(email, password, Arrays.asList(role1));
user.mudaRole(role2, 0); // muda a Role da posição 0 da lista
In this case the code works, because the list returned by Arrays.asList
allows you to change the widget at an existing position.
Depending on how you will manipulate the list of roles, That may or may not make a difference. That’s why it’s important to know the implication of every method you use, and not simply use it to "save a line of code". A smaller code is not necessarily "better".
Alternative: varargs
An alternative to "save lines" is to use varargs:
public User(String email, String password, Role... roles) {
this.password = password;
this.email = email;
this.roles = Arrays.asList(roles);
}
...
// pode passar uma Role
User user = new User(email, password, role1);
// ou pode passar várias de uma vez
User user = new User(email, password, role1, role2, role3);
The syntax Role... roles
indicates that you can pass one or more roles (or none, in which case the list will be empty).
Internally, the JVM "converts" these parameters to an array of Role
, so it is still necessary to convert it to a list. I used Arrays.asList
, but you could create it another way if you wanted to. For example:
this.roles = new ArrayList<>(Arrays.asList(roles));
This case is a little different: I create a list of all the roles (using Arrays.asList
), and create a ArrayList
containing the elements of this list. The difference here is that this list is not "immutable means" as it occurs if I just call Arrays.asList
(with the ArrayList
I can add and remove elements).
In addition, with varargs you hides the internal implementation of the class: whether or not the roles are in a list, an array or any other internal structure, this is class implementation detail User
; who create the user only needs to pass the roles he has, without knowing if within the class he will create a list or not (and if one day this internal implementation changes, the other classes need not know, because the constructor will continue to receive the roles in the same way).
But of course, if the roles get on a list, then you’ll still be instantiating a list (who creates the User
no need, just pass the roles to the builder, but within the class User
has an instance being created). I think I’ve said that can not escape this, right?
It seems that you are asking if you can make a steak without killing the ox. It may not be this, but it is not very clear what you want. It’s possible you didn’t kill the ox, you can buy it at the supermarket, but someone did. You might not need the steak, you might just want a protein and it could be soy, but how do we know?
– Maniero
When you go to write a shopping list and will jot down the items on a paper you first need to have the paper. And if it is a list of a single item why create a list?
– Vinicius Fernandes
@Viniciusfernandes, my object may have a list, permissions, but for this scenario, initially will have a single permission
– Fabio Souza