Java for C# Developers

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Alright, in this video I’m going to cover the differences between Java and C#. To be honest, there aren’t many differences, but I’ll cover the differences that we do have. Now, just to be clear, I am not going to cover all the differences, just the big, major differences, but there will definitely be a few other little things you might come across that you’ll need to look up when you start writing Java code. One thing you will notice is a moment is that Java takes a lot more work than C# to get setup, you see, Java is an interpreted language… Well, sort of. When you compile Java code it gets compiled to Java bytecode. And this bytecode is then executed inside something called the JVM. The JVM is the “Java Virtual Machine”, and your Java bytecode is executed within this JVM. This of course makes sense since the whole idea is Java can run on any platform, as long as there’s a version of the JVM for that platform. In many ways, this is similar to C#, C# compiles to a language called “IL”, which is then embedded in the EXE file and, provided the machine has the .NET Framework or mono installed, then compiled to the native machine’s code live as the program runs. So, they’re pretty similar. And, this means that anytime you want to run a program that needs Java, like Minecraft, you need to install Java, you need to have that JVM to be able to run this bytecode. So, in that case you download Java from the official Java website, which they only just modernized. And when you want to run Java programs, what you will end up downloading from the website is something called the “JRE”, the Java Runtime Environment. And this provides the JVM and various other things Java needs to run. It doesn’t come with any developer tools, like a compiler, however. To get those we need something called the JDK. This is the “Java Development Kit”, this has the compiler and other development tools we need to make programs using Java. One thing that is important to note is the JDK comes with everything the JRE has. So, the JDK is essentially just the JRE with some extra stuff thrown in there for development, like a compiler, that’s it. This means that if you don’t have the JRE installed on your machine, you don’t need to install it, the JDK comes with all of the JRE things too, like the JVM, so we won’t have any problems running our program after we’ve compiled it. OK, now, there’s something important be aware of, that’s just recently come up with the JDK. Oracle has introduced a new licensing system which means if you use the JDK for developing commercial programs, you have to buy a license. So, sure, for personal use, it’s fine but if you want to use Java for an application that will get you even the slightest money, you either have to pay for a license, or, use something called the “OpenJDK”. OpenJDK is an open-source Java Development Kit, based on the original JDK, and not only is completely free, so you won’t need a license, but Oracle themselves have made it quite clear that they absolutely support what OpenJDK is. Which of course begs the question of: What’s the point in paying for the official Oracle JDK when you can just use OpenJDK for everything, including commercial use? And, the biggest reasons are that with the official, payed JDK, you get support from Oracle if something gets wrong, you have access to loads more tools than you get in OpenJDK, and, biggest of all, all updates are straight from Oracle, while they’ll be from the open-source community on OpenJDK. So, that’s something to keep in mind, and because of this, we’ll go over how to install both the official Java JDK and OpenJDK, don’t worry, this shouldn’t take too long, then we’ll start looking at how Java differs from C#. We’ll nice and quickly cover this for Windows, Mac OS and Linux, they’re all very similar. Let’s try and get through this quite quickly so we can cover the language. And these apply to both OpenJDK and the Oracle JDK, there will be some differences, but they are mostly the same, I’ll show the Oracle JDK, but they’re both configured the same way. On Windows, you can just get the installer and run it, no problems there. But there is more configuration we have to do once this is done just in case it hasn’t already been done from the installer. On Mac OS, it’s essentially the same, we’ll download the installer and run it, but there’s more to this, and we’ll get to that in a moment. If you’re on Linux, there are a range of choices, and on Debian-based systems and systems that support installation from rpm files, you could most likely just use the packages provided, but I won’t cover that, and from what I tried they didn’t exactly seem to just “work”. So, what would be easier, since we know what’s going on ourselves, and in my opinion the best way, because this just straight-up works across all distributions of Linux is to download the binaries from the Oracle website, in the “tar.gz” file. Then, extract out that archive and you’ll get a folder from the archive. Now, all we need to do move this folder we just extracted over to /usr/lib, we’ll need to do this as root of course. Now, this alone isn’t enough because they aren’t in the PATH, but we need to be able to run “java” to run our programs and “javac” to compile our programs. So, we’ll just very simply create a symlink to those files, which is just the equivalent to a shortcut, in the “/usr/bin” directory, where they are accessible through the PATH. To do that, we’ll use “ln -s” followed by the source and destination. The source, so, where the java and javac executable files are is inside the folder we just moved over, and within the “bin” directory within that, so, you’ll end up with something like this, the version numbers will be probably different though. Let’s do “java” first. Then, we just follow that by where we want to create the shortcut, which is in “/usr/bin” and we’ll just call it “java”. Then, we’ll do exactly the same but instead of “java” we’ll do “javac” so we can compile java code. And, later on you might find yourself using other executables, like “javaws”, so you create the links for those as you need them. And, now, you should be able to write “java -version” and “javac -version” without any errors, which means it works. Alright, but, now across all platforms, there are some other things we need to do, we need to make sure the PATH is correct and another Environment variable called “JAVA_HOME” are configured. On Windows, you can either access this by just searching “environment variables” or searching “This PC” and hitting “Properties” and “Advanced system settings”. Now, we just choose “Environment variables” down here and we’ll see all the “Environment variables”. If we take a look at PATH, it should have something related to the JDK in it. However, if it doesn’t, we need to add that, so, we’ll add to the PATH where Java is, we’ll find Java inside “Program Files”, and just “Java”, then we choose the JDK version we just installed, and the “bin” directory within that is what we’ll set it to. On top of that, if there isn’t a “JAVA_HOME” variable, we also need to set that, and we set it to the folder that the “bin” folder is in, not the bin folder itself, so, it’s slightly different from the PATH, it’s one folder up. Now, in order for this to work you need to restart your computer after doing this, and that is so important. On Mac OS, we don’t need to worry about the PATH since the installer handled all that for us. However, JAVA_HOME, isn’t configured. So, within the “bash_profile” file (in our home directory), we’ll need to set it, and we can do that by writing “export”, followed by “JAVA_HOME” and setting it to the “/usr/libexec/java_home”. This will only apply to this user though. Similarly, on Linux, we need to fill in the “JAVA_HOME”, PATH is already sorted since we created the link in “/usr/bin”, but we still need to set “JAVA_HOME”, if we want to do that for all users on the system, we’ll modify “/etc/profile” to set JAVA_HOME to the directory our JDK was stored in, so, we’ll write “export” followed by “JAVA_HOME”, an equals sign and the folder we copied, that was in “/usr/lib”, since I’m in vim I can check what the folder name was so I can set it correctly. Great! Now everything is properly configured, regardless of your platform. Alright, let’s dig down on the code, I’m going to be using the IDE IntelliJ Idea which is very similar to Visual Studio in many ways and will take essentially no effort to get going provided you set JAVA_HOME and everything else set correctly. However, you absolutely don’t have to use it, you can use “java” in the command line to execute your Java programs and “javac” to compile your programs, there’s lots of documentation and I’m sure you can figure it out. Now, if you are using IntelliJ, we’ll just create an Empty Project. To do that, make sure “Java” is selected in the “New Project” window, choose an SDK version, don’t worry about any of these, make sure they aren’t ticked, and hit “Next”, then tick this and choose “Command line app” otherwise things aren’t going to work, and then we’ll give our project a name. Now, notice how it’s asking us for a “Base package”, so, that’s our first thing: What are packages? Well, packages are essentially namespaces, that’s all they are. So, if I have a package called “A”, within that package we can put classes in there. So, it’s exactly the same as the folder structure you can get in your C# projects. Then, if I want to access that class from outside from that package, we need to import that class. Now, this is different from C#, in C#, you say “using” followed by whole namespaces, and that makes everything inside that namespace accessible. In Java, you use something called “import”, and you have to import individual classes. So, if I wanted to access this “Hello”, I would say “import A.Hello”. However, you can also use wildcards, so you can say “import A.*” which will import everything within the package “A”, you’ll find that IntelliJ lets you just import classes as you need them by putting your mouse over them though so you generally don’t need to worry about this yourself. You’ll also notice that if I make a package, and make a package within there, it will join up into one “A.B” for neatness. Now, one important thing to point out is that these packages are only in the source files. Essentially, all of your project’s code is contained within a “src” folder, and that’s where you have your packages. It’s only the actual code that’s put into packages, everything else, like resources are stored in just normal folders. But, wait, how are these packages different from just folders, then? Well, technically they aren’t, these packages are stored as folders in our file system, they’re just called packages, it’s just a clearer way of representing them. But, really, they’re just a fancy name for folders that behave exactly like C# namespaces that you use to organise your code. So, the base package is the whole package that our entire project is going to be put in. So, now we need to look at naming this base package. The first thing you need to keep in mind when naming packages is that they need to be lowercase, do not put uppercase characters in the package. And, you also can only put letters and underscores in package names, nothing else, so that’s important to keep in mind too. Now, there’s a general naming convention when naming your base package, the package that your whole project will go into. You’re supposed to name it based on your website. So, for me, my website is “abworld.ml”, so you do that in reverse, meaning my base package name would be “ml.abworld”. But what if you don’t have a website? Well, then things get a bit tricky, Java doesn’t really say what you should set it to in that case. But, just make sure to set it to something that’s unlikely to conflict with something else, since that’s the whole point of it. Maybe I would call “com.abworld” or “com.abmedia” or something if I didn’t have a website, up to you. So, once we’ve set that package name, we can just go ahead and create the project! Right, finally, we’re here in the code. Now, we can use “System.out.println”, giving it a string to print out some text to the console. Then, when we execute it, we’ll find our text displayed in the “Run” section down here. Great! Let’s start off by focusing on the types. Now, in C# every single class or data type inherits from one big base object called “object”. This means that every single object has “Equals”, “GetType”, “GetHashCode” and “ToString” on them. And that’s everything, from strings, to integers… To just everything. However, Java has a similar system, where it also has an object type, but not everything inherits from it. Some primitive types, like integers don’t… But, for the most part, more complex data types do, so that’s something to keep in mind. In Java, anything that isn’t a primitive will have a capital letters at the start, for example, a “String” isn’t considered a primitive, therefore it has a capital “S”, and it does inherit from “Object”. Alright, another thing that’s different with the type system is “enumerations”. In C#, enumerations are literally just integers, there’s nothing more to them. They just fancy integers, just syntactical sugar, if you like. If I make an “enum” in C# and put four values in there. Each of these values will automatically be set to 0, 1, 2, 3 and so on. But we can manually set each of these to a different number. These pretty much just get substituted for numbers, there’s nothing too special about them. In Java, however, it’s a whole different story. Enums are essentially classes and arrays joined together. Now, fundamentally, it’s looks almost the same, and you can use it almost the same way too, let’s hop into the code and take a look. Let’s make an enum called “Device”, and within here, we’ll have a phone, a tablet, a laptop and a desktop. Now, yes, in Java you often put the things within enums as all capitals, so keep that in mind. So far, this is the same as C#. And, we can use these the same way. But we need to know what’s going on here to take this to the next level. You see this enum is actually just a class, and each of these are instances of this class. So, this where things get clever, and this can be quite useful too, I can put some fields in this enum. Now, it’s important that this always stays right at the top of the enum, so we’ll put this below. Let’s put a screenWidth, and a screenHeight field in there. Now, watch this, if make a variable of type “Device” and set it to “Device.PHONE”, there’s now a “screenWidth” and a “screenHeight” within this. If I write “Device.TABLET”, it has a “screenWidth” and “screenHeight” on it. What happening is this enum is essentially a class, and these are just constant instances of the class. I could do exactly this with a plain class, I would create the class, give it these two fields, then create each of these as constant static instances of this class. But, of course, that would take more effort, an enum just gives us this in an easier-to-use format. Alright, fine, but let’s take this up to the next level. What we can now do to take this even further is to make a constructor on this enum, that takes in the width and height and sets them properly. Now, we can provide the parameters of this constructor for each of these. So, these are just random numbers that I’m making up, but let’s just say that the phone screen is 600 pixels wide and 1200 pixels high. We’ll do some brackets, because we’re providing the arguments for this constructor, followed by the width and height. And, you’ll notice here that IntelliJ is showing us what parameters we’re providing the values for, this is just something IntelliJ does, it’s quite convenient when I think about it, it would be nice is Visual Studio had this because it tells you exactly which argument is going to which parameter. So, let’s just set some random sizes for every single one of these. Now, each of these have a different width and different height, and we could add even more sub-properties to these, I think you can see how this is quite powerful in comparison to C# enums. We can also put methods in here too and pretty much anything else that you can get in a class. Right then, the next topic to talk about is properties! This is something you’ll definitely notice. In Java, properties don’t exist… At all. Instead, you use something called “accessor and mutator methods” Java. This isn’t really a feature of Java, but it’s a pattern that almost all Java developers use. Let’s create a class, and call it “C”, for class. Then, within this class, we’ll have a string variable in here, but we’ll keep it private. Then, we create a getting method and a setting method. And these will do what you would expect. This is the accessor method here, and this is the mutator method here. If we want to have a variable that we can only get, we just don’t provide the “setter” and this is an extremely common pattern in Java, this is everywhere. Let’s take a look at Exceptions next. Now this is something that is quite different between Java and C#. In Java, you have two different types of things that can go wrong. You have something called an “Error” and something called an “Exception”. Now, an “Error” is a major error that comes from something internal in the language, like the JVM or something like that, changes are you will never need to handle “Error”s or even look at them. However, “Exceptions” are different. Now, “Exception” if look at what’s going on inside “Exception” we have a range of exceptions, but also something called a “RuntimeException”. And there’s a pretty big difference between the two. Anything here, that just inherits from “Exception” is something called a checked exception. And anything that inherits from “RuntimeException” is something called an unchecked exception. But what does this mean? Well, a checked exception is an exception that you must handle. You have to handle that exception at some point down the line. While an unchecked exception is an exception that you don’t have to handle. And unchecked exceptions usually come internally from Java, so, things like dividing by 0 or trying to access an invalid method in a class, or something along those lines. When you make exceptions, you should always make checked exceptions, never unchecked exceptions. In C#, all exceptions are unchecked, you don’t have to handle them, they’ll just crash the application if they occur. So, how does the checked system work in Java? Well, let’s think about a very simple application. We have three methods, like that. And this is the call stack, so we’re in a method called “Method1”, that we called from “Method2”, which was called from “Method3”. Then, inside “Method1”, we throw a checked exception. What happens is we get a compiler error inside Method1, saying that the exception is unhandled. So, it’s telling us that we need to deal with this exception. And we need to handle this Exception inside “Method1”. So, we could deal with the exception inside “Method1”, we could put a “try…catch” in the same method the Exception is thrown. And, now, we don’t get an error anymore, because we’ve handled the exception, that’s how you handle exceptions, you just catch them in a “try…catch”. But what if it needs to be handled somewhere higher up? Of course, sometimes you can’t handle all these errors at the same level you throw them, in a way that kind of defeats the point, sometimes they need to be sorted out at a higher level. For example, if we have a method that makes a connection to a server, and then we have another method that prepares the address. If we failed to prepare the address and threw an exception in here, we don’t want to handle that exception inside here, we want to sort that out in the place we’re trying to make the connection to the server, because that’s the level where we’re able to say to whoever wanted to make the connection that the address was invalid. That’s where we want to handle it. We don’t want to deal with it in the smaller part that processes the address. So, back to our three methods, in order to tell Java that this exception needs to get handled from the person that calls Method1, instead of Method1 itself, we add to the method’s declaration the word “throws”, followed by the exact type of exception this throws. So, this tells Java that this method can throw that exception, unhandled, and now the responsibility is pushed up to “Method2”, now it’s up to “Method2” to handle the exception. We could also do the same to “Method2” if we wanted. We can add to “Method2”’s declaration that it throws a given type of exception, which, once again tells Java that this method, “Method2” can throw that exception unhandled, and now yet again, the responsibility has been moved up to “Method3”, now it’s up to “Method3” to catch the exception. And we can add multiple exceptions to this “throw”s thing here. We can specifically handle some exception but leave other exceptions to be handled higher up. Now, there is a lot of controversy surrounding checked exceptions, some people think they’re good, some people think they’re bad. Because on the one hand they make sure you’re code always handles exceptions at some point, your application is way less likely to crash, but on the other hand, this “throws” bit here can get exponentially bigger as you can see in this image here, the amount of exceptions this method can throw, that need to be handled just gets bigger and bigger. And, on top of that, some people also don’t like it because some developers will just leave empty catch blocks to stop it from having to be handled properly, but that’s really bad, please don’t do that. Now then, what about unchecked exceptions, if we have this great checked system, why are some exceptions unchecked? There’s a class called the “RuntimeException” class, and if you make an exception based on that, it’s unchecked and doesn’t need all that, what’s that for? Well, remember that earlier I said that internal exceptions are unchecked, like for example dividing by 0, that’s an unchecked exception. That’s because Java decided that it would be near madness to try and work out every single little exception that could come from things like that. Imagine if every single time you divided by a number, you had to say that this method can potentially throw a “DivideByZeroException”, things would get very messy, very quickly. And that’s why the absolute fundamental things, like division or accessing members on an object are unchecked exceptions. Essentially, the official way Java looks at it, (although as I’ve said people do have different opinions about this) is never make unchecked exceptions in anything you do, it’s the only the absolute fundamental things that should give off unchecked exceptions. Right, hopefully that makes sense, it’s really difficult to explain that, but try it out in your own code and you’ll get an idea of how it works. Next thing to talk about is inheritance, one of the most important parts of object-oriented programming. The biggest difference is how you make a class inherit from something. If you’re inheriting from an interface, you write “implements” followed by the interface. And if you’re inheriting from another class, you write “extends” followed by the class. In addition to that, in C#, you need an override keyword when you’re replacing a method in a subclass, however, in Java you don’t need to override. If I make class “A” and class “B” and put a method within class “A”. Then, make class “B” inherit from class “A”. I just put in a method with the same name as the one in class “A”, and it will replace the one in class “A”. Most other things are the same, however, one thing you will notice is that virtual isn’t a thing in Java. All Java methods are virtual. You’ll notice that I can provide code for the method in class “A” and class “B” will just replace that code, I don’t have to mark it virtual. I only have to mark it abstract if I provide no code for it, as well as making the class abstract of course. Alright, I’ll just quickly mention some of the other smaller differences you have. You’ll notice that if I can only have one public class per file, and that public class needs to have the same name as the file it’s in. We can make lots of smaller, non-public classes, but it’s one public class per file, which is of course different in C#. Also, the equivalent of the C# term “const” is “final” in Java. And, in C# you can use “using” to make sure an object gets disposed, in Java that’s called “try”. In Java, there are no multi-dimensional arrays (thank god). In Java, you can create arrays like this, with the square brackets after the variable name, and it’s exactly the same as putting the square brackets after the type. In C#, you can add internal to a class to make sure that class can only be accessing from within the current project. In Java, you can add “package” to a class to make it can only be accessed from within this package. In Java, there’s a keyword called “strictfp” that you can add to classes or methods that make sure floating-point numbers are handled the same across all different systems. Alright, well, I hope this video was helpful, I dove into some of the biggest differences between C# and Java, the biggest difference being the installation – if you want to see more videos, mainly related to C# or C++, feel free to subscribe, and feel free to suggest any videos, this video came from a suggestion in fact. Alright, bye!
Info
Channel: ABMedia
Views: 7,832
Rating: undefined out of 5
Keywords: java for c# developers, java for c# programmers, java for .net developers, java for .net programmers, differences between java and c#, java vs c#, c# vs java
Id: heZJ3iGj3KA
Channel Id: undefined
Length: 25min 32sec (1532 seconds)
Published: Sat May 16 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.