Want this course?
Course: JVM Fundamentals for Clojure
When we need to refer to Java classes, we need to import them in the
ns declaration. There are a few things you should know about doing that. This lesson covers the basics, a couple of gotchas, and some nice properties of the import form.
So, when we're interacting with Java classes, we're often going to need to import something. So, we have an import directive that goes in the NS, looks just like that.
Now, there's two versions of it, and they're totally incompatible and, so, you really need to be careful with them because the system can't detect if you're using it wrong. So, the first way, the easy way, is if I wanted to include java.io.File. Just type it in there. Now, I compiled it, it found it, everything's good. If you notice, if I did java.io.File, but I spell it wrong, it's going to have an error and the error will be something like Class Not Found Exception. Okay, so we know when we get it right there.
I can also do java.io and then put File here. Now let's remove this. And that compiles. You can also see I can also do some gobbledygook in there that obviously is not going to be a class and, see, I can put two; so this let's me import two different classes from the same package. This is the package name and this is the class name. So, I can have one package with a bunch of classes that I import, and this is saying that this one is not found, which is good. But, I've made this mistake before. If you put a dot in there, it thinks that this is part of the package name because you're inside a square brackets.
So, you have to be very careful with this because it's hard to see, you know, you're going to have a lot of these in there, and you're not going to be paying attention to spaces versus dots. So, this is going to compile, and it thinks, "Oh, you have this package name with zero imports, zero class names," but really you want one class. So, I just remove it and now it's working. Okay, another thing that can happen is that you're going to want a, to get an inner class. Java has this concept of inside of a class, you can name, you can make a new class that is still public, but it's part of the interface of that class.
So, something like, "Oh, it's not supposed to be used in general, outside of the use of this class," but you might need to construct a thing. Like, you can imagine a file system where each file, let's say a directory has some inodes, and so those inodes are the blocks for a file, like those things aren't really made to be used on their own, but you will need to use them, and they'll be internal to that class. They're public, meaning you can construct them and everything, but they're, they're inside, and they need a name, so on the JVM, the way that name is constructed, is by putting a dollar sign, so you have that kind of enclosing class and then a thing inside, so you put a dollar sign between their names.
So, there's a thing called Thread. It's in java.lang; it's an object, it's a class. You can instantiate it, but it actually has its own exceptions that are defined as inner classes. It's, you know, it's kind of one of those things, those features of a language that is used sometimes good, sometimes not so good, and, you know, you just have to figure out how this library writer did it. I'm not going to try to justify this as a feature or whether it was done correctly, but there is actually an inner class; that's an Exception Handler, okay, and this is something that's supposed to be used only with a thread.
Now, if you want to import that, it's actually going to be imported because it's java.lang and everything in java.lang is automatically imported, but let's say you did want to write it in your import statement. You would do java.lang space and then this is just the name. It has a dollar sign, but it, it's almost like not even a special meaning. It's just some character that you will probably not put into your class name. So, that, that will work. So, if you need to import something, with that to inner class, like you're researching in the java, the library you're looking at, and it says it's an inner class, don't forget, it's just a dollar sign. In Java, you wouldn't, you wouldn't notice. So, this would be import java.lang.Thread.UncaughtExceptionHandler. So, that's where it gets confusing because you'll read some java code and it says, "Oh, put a dot," but in enclosure, we use the JVM's name, which uses the dollar sign there. Here, I'll put this up here. Import java.io.file and let's put this inside there just for clarity.
Awesome. Now, we seen before, in another lesson, that there are enums. So, if you have java.nio.charset.StandardCharsets, the enums, wait see, let me back up here. If I do this, it's not going to work. I'm trying to execute it and it doesn't know it. I don't want to use that whole long name, so I need to put in import. Java.nio.charsets, this is one of those ones that you probably won't remember the name of, you have to look it up each time, you know, it's how it works, and then StandardCharsets. Uh oh. Did I misspell it? There we go. Alright, so now, I can say StandardCharsets and get, get the class itself. Okay, now there are. I kind of went over this already in a different lesson, but there are, it's an enum, and you can access it like this. Okay, so, in Java, the problem is it's going to look like a dot. So, I just want to, I just want to reemphasize that; that Java uses the dot for a lot of different stuff, whereas internally, this is a class and this is a static field on a class.
Same here, it uses the dot here, to separate the inner and the outer class, but internally it uses a dollar sign, and that's what enclosure it uses. It's just a, it's just a class like any other. It just happens to be, have this funny name. And I'll put an import here, and I'll put the java equivalent, java.nio.charset, I think it's clear though, StandardCharsets. So, that's, that's the big thing is be careful with the dot here, dot or no dot. If it's got a dot, it's part of the package. If it's got a space, it's a class name.
The dollar sign means an inner class. You won't be making inner classes from enclosure, but you'll often have to use them. And then, you've got, you can use, if you import it, you can just name it with the short name, you know, with the name of the class, and not the whole package, doesn't have to be qualified. And you've got your static methods, your static accessors, your fields, on enums. Because in the Java language, it gets compiled down to classes and fields.