I tried below code in my developer Org and observed something strange. I was expecting it to throw a compile time error or
at least a Runtime error. But it behaved something else.
public class TestBug { public TestBug () { // Below commented line behaves as expected // Map<String,Account> mapAccount = new Map<String,Account> ([SELECT Id, Name FROM Account LIMIT 100]); // This line should give Compile/Runtime time error. Map<String,Account> mapAccount = new Map<String,Account> ([SELECT Id, Name FROM Account].Name); } }
Expected Behavior:
Compile time error or Runtime error
Output:
Can anyone explain why this is happening?. Is this a normal behavior or a bug in Apex Compiler?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
It looks like you’ve caused a gack.
What you are looking at is what we call a GACK. A gack is our blue screen of death, our frowny Mac icon, our “the number you have reached is no longer in service”, our “Jedediah has died of dysentery”. A gack is what happens when an error got thrown within our application and we didn’t catch it and handle it.
What this means is that it’s not your fault. It’s ours. That’s why we apologize in that message. Sorry!
This friendly message is the above-water portion of a huge iceberg of functionality. The numbers you see are part of an elaborate system for efficiently bringing these events to the attention of R&D. This post will help you understand that system, and how you can help us in getting you running safely. (Hint: steer away from icebergs.)
Despite what the above says, you can very well cause a gack- this is a great example. They’re harder to debug than the average error, and can be caused by just about anything that forces an operation that should never happen.
Method 2
This is a bug in your code. Class structure is irrelevant. The constructor can essentially be rewritten:
String value = [SELECT Id, Name FROM Account].Name; Map<String,Account> mapAccount = new Map<String,Account> (value);
Or basically it’s the same as:
Map<String,Account> mapAccount = new Map<String,Account> ('Some Account Name');
Of course this code will not compile. Even if it did, the code you wrote would almost certainly fail at run time (unless your instance has exactly one Account
record in it). Perhaps the compiler should be able to decipher the problem, but in this case the code is just causing a glitch somewhere.
Method 3
After a bit of testing, it seems that almost any non-list
type passed to the Map<ID, sObject>
will throw a GACK, while List
types are correctly type-checked and issue a compiler error if the type does not match the sObject value type. This includes set
, but not map
, probably because they will use the copy constructor instead. This only applies if the key of the map
is either an ID or String, and the value is an sObject
type – any other combination of key
and value
will issue a compiler warning if an incompatible type is passed, probably because they default to the copy constructor instead of the list
constructor.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0