How can I create a static final java.net.URL?
Solution 1
An "alternative" which I'd prefer to @HosamAly method:
private static final java.net.URL STATIC_URL = makeUrl("http://www.example.com");
public static java.net.URL makeUrl(String urlString) {
try {
return new java.net.URL(urlString);
} catch (java.net.MalformedURLException e) {
return null; //Or rethrow an unchecked exception
}
}
Solution 2
Use a static initializer:
public class Main {
private static final java.net.URL STATIC_URL;
static {
java.net.URL temp;
try {
temp = new java.net.URL("http://www.example.com");
} catch (java.net.MalformedURLException e) {
temp = null;
}
STATIC_URL = temp;
}
}
Note: The usage of a temporary variable is required to avoid a compilation error about assigning to the final static field twice. If the field is not final
, the assignment could be done directly.
Solution 3
If you're sure you want to hardwire a URL. Are you sure? java.net.URL
is one of the most comprehensively broken classes in the JDK. In regards to use as a "constant", there is DNS lookup involved and it uses a mutable static (albeit one guarded by a security check, if you have a SecurityManager
installed).
If it's just one, a static initialiser should be fine.
private static final java.net.URL STATIC_URL;
static {
try {
STATIC_URL = new java.net.URL("http://example.com/");
} catch (java.net.MalformedException exc) {
throw new Error(exc);
}
}
(Note, you can't qualify the static field name with the class name.)
Note: You really do not want a null
- throw an error of some sort and stop the class loading. I've made the constant private
as it really isn't the sort of thing you want dependencies on.
If you have lots, then a method for the common code and assignment at the site of the definition is appropriate.
private static final java.net.URL STATIC_URL = constantURL("http://example.com/");
private static URL constantURL(String str) {
try {
return new java.net.URL("http://example.com/");
} catch (java.net.MalformedException exc) {
throw new Error(exc);
}
}
Again, no nulls!
Ky -
Any pronouns. Really, as long as you're respectful, use any singular third-person pronouns to refer to me. More about me on my site! https://KyLeggiero.me Starting on 2016-11-21 and going forward in perpetuity, all content I post on a website in the StackExchange network is written specially for that post, and is licensed under BH-0-PD unless otherwise stated.
Updated on June 29, 2022Comments
-
Ky - almost 2 years
My question is simple. I'm trying to make a set of
java.net.URL
s that arepublic static final
, so that any class can access them from any context, as these URLs won't change during runtime. However, when I try to create them, I get a compiler error telling me that I must catch or declare thrown ajava.net.MalformedURLException
, but that is impossible outside a method. Is there any way to circumvent such a constructor that throws a non-java.lang
Throwable?Some dummy code below to visualize my problem:
public class Main { public static final java.net.URL STATIC_URL = new java.net.URL("http://example.com/"); public static void main(String[] args) { GUI gui = new GUI(); gui.setVisible(true); } }
public class GUI extends java.awt.Window { public GUI() { add(new java.awt.Label(Main.STATIC_URL.toString())); } }
If you try to compile this, it will tell you that you can't because of line 3. Hence my question.
-
Buhake Sindi over 12 yearsCompiler will complain as
STATIC_URL
hasn't been initialized (since you usefinal
). -
Buhake Sindi over 12 yearsCompiler error:
variable STATIC_URL might not have been initialized
. -
Thomas over 12 yearsThat is not only preferable but also circumvents the compiler error due to the final variable possibly being assigned twice.
-
Hosam Aly over 12 yearsThe
final
keyword could still be used. Please see my updated answer. -
Hosam Aly over 12 yearsMax: I agree with you, that is the preferred way of doing it. @Thomas: I've fixed the error; sorry I didn't have an IDE at hand.
-
Buhake Sindi over 12 years@Hosam Aly, no it won't. This solution (posted above) is the only solution that compiles. Yours doesn't. I've compiled it using IDE, as well as on command line, and yours failed.
-
Ky - over 12 yearsbut is it as efficient, in terms of memory and processing time?
-
Buhake Sindi over 12 years@Supuhstar, I'm not "high-and-mighty". I just posted a code that I tested instead of rushing to post answers just for point. Besides, SO was designed to give solutions/answers that works, and not for greed. :-)
-
Ky - over 12 yearssorry, I just assumed that you were being pretentious when you said something to the effect of "my solution is the only one that works, so yours can't be right"
-
Hosam Aly over 12 years@TheEliteGentleman Mine compiles with javac 1.6.0_26. Which compiler version are you using?
-
Buhake Sindi over 12 years@Hosam Aly, I have the same, 64 bit version. You've edited your code, and it's effectively, exactly as mine (except, I don't use
temp
variable). :-) -
bezmax over 12 years@Supuhstar Static fields are filled in only once. Also I have a feeling that this method would be inlined by compiler (not sure because of that nasty "final"). Anyway, yes, it is efficient in both memory and processing time.
-
Thomas over 12 years@Supuhstar I'd not worry about efficiency here. Normally there are many other much more inefficient parts of ones code and often you don't actually care because what is more important in most cases is developer productivity.
-
Ky - over 12 years@Thomas I am insulted. I take pride in constantly going over my code to ensure it is as efficient as possible. also, this has to be efficient because there may be hundreds of this object created at once.
-
Thomas over 12 years@Supuhstar I didn't intend to insult you :). What I basically meant is that in favor of developer productivity you don't try to optimize every tiny bit of your code. Often there will be other performance bottlenecks which often only become obvious after thorough profiling. However, many of those are not worth the trouble because you have to invest way too much in order to squeeze out a little more performance. If productivity wouldn't matter, we'd still code our software in C or even Assembler :)
-
Ky - over 12 years@Thomas I understand where you're coming from, but I am still worried about poor performance. I want my programs to be as quick-starting and responsive as Chrome.
-
bezmax over 12 years@Supuhstar Well, the problem is, if you try optimizing each place in your code as much as this URL initialization stuff, you'll use up... lets say 8 extra hours. During that time you could have had coded several extra features in your app at a cost of 50msec start-up time because of skipped micro-optimizations. Is it really worth it?
-
Ky - over 12 years@Thomas it is very much worth it. A program is made for the end user, and it is the end user for whom I work. If there is any part of my program that the end user might not like, I must abolish it, and that includes a somewhat slow startup time. If Valve pushed out their games on time instead of held them back to polish them, they might be infamous for their bugs. Because of this, they hold their games back until they feel they have a product of which they are proud. I will not release a product of which I cannot be proud.
-
Cameron Skinner over 12 years+1 for the no nulls. It really doesn't make sense to continue if one of your constants has blown up.
-
Thomas over 12 years@Supuhstar The question is: would the user recognize the extrac 50ms you squeezed out and if so would they appreciate it?
-
Thomas over 12 yearsAs for the Valve example: games developers have to meet strict deadlines and they often work hard to get rid of as many bugs as possible. Often their initial pre-alpha releases have quite poor performance since they want to get something testable as quickly as possible. Then they optimize for their target platforms until they reach their performance goals (say 30fps/34 ms per frame). Once they reach that goal they won't invest much more effort in order to be a few ms faster, since they reached their goals. They don't optimize areas where optimizations most likely have no benefit.
-
Ky - over 12 yearsI believe they will, especially since individual class loading times add up fast. As for your counter to the Valve example, they indeed do optimize the performance. Try playing Portal 2 on an older computer, which just meets the system requirements, and then try playing Portal. Portal 2 will almost always run better because Valve invested more time and effort into improving the source engine. Their games are "late" because they care about the end product. My programs have no release time, and I believe no one's should. Any well-made program should be released only after the creator is proud.
-
bezmax over 12 years@Supuhstar So what you are saying is that Portal 1 was not optimized to the edge and that it had to be released with performance issues, right? And you are using that to prove that Valve only release perfect products? Am I missing something in your statements?
-
Ky - over 12 yearsYou're missing the pride. My philosophy is one of pride. If I can't be proud of a product, I can't release it. Now, please tell me this is the key to that oh-so-private information you've been withholding. Which method of static initialization is faster?
-
bezmax over 12 yearsTechnically, the "fastest" way for static initialization would be what @HosamAly proposed. However, to make it faster than my solution - you would need to bundle as many as possible URL initializations inside of one try-catch block. The reason for that is that try-catch operation is somewhat resource-heavy. So if you use try-catch for each variable, it will be somewhat slower than if you bundle them all into one try-catch block. However, personally I prefer a clear and understandable code. You will see what I mean after you actually try initializing several URLs in one try-catch block.
-
Flame almost 12 yearsI'd like to see a suggestion to use java.net.URI instead also. If using a library that requires a URL, use the toURL() method at that point.
-
Ky - over 7 yearsIn the 5 years since posting this question and accepting an answer, I've decided to make this the accepted answer since it's a lot easier to understand, and much more functional.
-
bezmax over 7 years@Supuhstar What about the pride? ;)
-
Ky - over 7 years@bezmax haha it's still there! Just also now balancing pride of speed with pride of exemplary code. Working with teams changed me :P