views:

169

answers:

4

In Php I really often use this one:

$conn_sets = array();
$conn_sets['login'] = "aaa";
$conn_sets['pass'] = "bbb";

How to do the same in JAVA 1.6. I tried to do this:

private method1() {    
    String[] mystring = new String[] {"login" => "aaa", "pass" => "bbb"};
}

But it give's me an error. I want to make this work, because I have an error lists declarations, and it is better to identify:

throw new MyException(myerrors['failed_login_error']);

than a:

throw new MyException(myerrors[116]);

I know I can do a new class, and throw an object:

throw new MyException(ERROR_CONSTANTS.FAILED_LOGIN_ERROR);

But I prefer the first one (the same as I use in Php).

So, any ideas?

+13  A: 

In Java, you probably want to use the Map interface, such as a HashMap.

Although, I would say that using an Enum is actually what you should be doing in your second (list of errors) example. Forget about PHP when you're in Java. Enums are much better in this case because you want a well-defined list of keys.

philfreo
+1. When in Rome do as the Romans do. Enums give you static type checking. If you misspell the name of an enum you'll know at compile time. With the associative-array/Map approach this sort of error bites you at runtime.
Laurence Gonsalves
+4  A: 

You could use the double brace pattern:

Map<String, String> map = new HashMap<String, String>() {{
    put( "login", "aaa" );
    put( "pass", "bbb" );
}};

... and your other example:

throw new MyException( myErrors.get( "failed_login_error" ) );
tangens
And you say this works??
Carl Smotricz
Which version of Java are you using to get the 'double brace pattern'?
vkraemer
Theres nothing like a "double brace pattern". You just create an annonymous subclass of HashMap and calls "put" two times in the static initialiser of this subclass.
Arne
It's been valid since 1.1 or so, I believe. All it's doing is defining an anonymous class (which is the outer braces) with an instance initializer (the inner braces). "Double brace" is a little misleading.
Michael Myers
So yes, what Arne said (except that it's an instance initializer and not a static one).
Michael Myers
Arne: that's why it's called a "pattern". It isn't an explicit language feature, it's just a pattern. Though really, I personally think it's an anti-pattern, because the mechanism by which it operates is so baffling to many people.
Laurence Gonsalves
Uh, yes, you are right (@mmyers) ... of course an instance initialiser, not a static one ;).
Arne
@Laurence: I would avoid to name this "double brace pattern" because it confuses more than it helps understanding.
Arne
I it also a bad idea IMO since you wind up creating a subclass of HashMap instead of an instance of it. You violate the rule of "Don't be tricky" when you do this too... tricky == bad in most cases.
TofuBeer
Well, thank you all for teaching an old dog a new trick, anyway. I'll save it for when I want to dazzle people with BS.
Carl Smotricz
It's only tricky if you don't know it. I use this "pattern" often, because it makes my code shorter and reduces the number of temporary variables that have no special meaning.
tangens
+5  A: 

You really should be using Properties (or better yet a ResourceBundle to abstract the properties file) for this particular case.

Here is a tutorial on the usage.

This is a much better way as you can internationalize (I18N) the messages (if you want) and you can specify them in text files rather than inside the code (messages are much better in text than in code so you can update them without having to rebuild).

TofuBeer
OP: accept this answer. It is the only right one of all for this particular purpose.
BalusC
+3  A: 

You don't want to use a HashMap or a Properties object to store wildly named parameters. You really want to think object-oriented and use a class to encapsulate the data of an account and to express what an object really represents in the real world:

String username = "aaa";
String password = "bbb";
Account acc = new Account(username,password);
if (!tryLogin(acc)) {
 throw new LoginFailedException(account);
}

That way, clients who catch the LoginFailedException can make use of the information and use statically typed methods with good names to, for example, retrieve the username by calling loginFailedException.getUsername().

mhaller
The message in the LoginFailedException should probably be from a properties file...
TofuBeer
@TofuBeer: no, because if you're in a two-tier or three-tier architecture, you want to transmit the exception to the client first and then translate using the client's locale. Higher-up code may also rethrow using a service exception and thus need to translate it again etc. Better th only use data in low-level methods and not try to perform UI-stuff down there.
mhaller
bah to client server :-P
TofuBeer