I am very confused by this task. There seems to be a lot in the provided code that I do not understand.
1.
public static void main(String... args) throws IOException {
The argument to the main function is "String... args". IntelliJ does not report this as an error.
I thought it was suppused to be "String[] args"
2.
The main function has 2 instructions as arguments. I am not familiar with try taking instructions.
try (
FileOutputStream outputStream = new FileOutputStream(args[0]);
InputStream is = Solution.class.getClassLoader().getResourceAsStream(args[1]);
) {
and what arguments, args[0] and args[1] are we meant to provide?
3.
When I try to run the provided code I get the error:
Exception in thread "main" java.lang.NullPointerException
at com.codegym.task.task19.task1928.Solution.main(Solution.java:23)
Line 23 is:
byte[] b = new byte[is.available()];
I suppose this is linked to the args provided when running the main Solution class?
4.
Solution.class.getClassLoader().getResourceAsStream(args[1]);
what does this do?
I don't get the feeling that my progress at CodeGym has made me familiar with the code in this example.
I feel really lost in this task
Resolved
Comments (8)
- Popular
- New
- Old
You must be signed in to leave a comment
Gellert Varga
2 November 2021, 15:05
I think your questions are valid, and I think it's very good that you're breaking it down into smaller and smaller parts of what's causing the confusion.
I think you have to clarify every little bit, not skip over anything that is still in question.
If you start to search about each part, your feeling of "I feel really lost in this task" will decrease and finally terminate.
I struggled through this task not too long ago.
I sometimes spend days studying the TOTALLY UNKNOWN classes and methods in CG tasks in the oracle API, just to have at least some vague idea of what they are and how they work. This requires a lot of testing and experimentation to see which method does what. I don't claim I understood everything... but at least a little bit surely.
For example:
Class class: https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html
ClassLoader class: https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html
getResourceAsStream method: https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html#getResourceAsStream-java.lang.String-
URL class: https://docs.oracle.com/javase/8/docs/api/index.html?java/net/URL.html
0
Gellert Varga
2 November 2021, 15:08
4.)
If I understand correctly, that's the point:
"Instances of the class Class represent classes and interfaces in a running Java application."
Every Class object contains a reference to the ClassLoader that defined it.
One of its methods:
getClassLoader() // Returns the class loader for the class.
"A classloader is an object that is responsible for loading classes."
"When you load classes into memory, the JVM uses a subsystem called the classloader.
It loads the class into memory, parses it, checks its correctness, and creates a Class object. It contains all possible information about the loaded class, its methods, constructors, fields, etc."
It is possible to get the Class object using a class literal:
Solution.class
From this you can get its classLoader object:
Solution.class.getClassLoader()
And this classLoader object has such a method:
getResourceAsStream(String name) - Returns an input stream for reading the specified resource. (("String name" is for example a file name.))
So we finally got an InputStream for the given fileName.
Why this complicated solution is good, and why we didn't create a FileInputStream for the given fileName in the usual way, I don't know at all. But maybe someday someone who knows will read this and answer it:)
But this task is really about what Lupe said: "these things are there to distract you."
3.)
To test this program, write this at the beginning of main:
or this:
(And don't forget to delete these lines before you want to validate the program!)
After that it will no longer throw nullpointerException, and you will be able to test to see what is going on in the program. 0
Gellert Varga
2 November 2021, 15:09
2.)
This is called "try with resources". As far as I know, it only has the effect of automatically closing the opened streams at the very end of the block, so no need to use the close() method. It's good to make sure you don't forget some open streams, which consumes a lot of resources.
Line 22: The ; sign does nothing by itself, it is just an empty line with no commands in it. It's also just there to confuse you...
1.)
I seem to remember there was mention of "var args".
In this case, the method can take any number of String arguments.
public static void main(String[] args) - in this case the method takes a String array.
You can handle args as a String array in both cases.
https://www.geeksforgeeks.org/variable-arguments-varargs-in-java/
0.) Hint: Make a test case where line 30 says: String s = "c"; 0
Lisa
2 November 2021, 16:19
This is all pretty much bogus code. Just look at:
cause s = "a" all the other cases are redundant..
it'll be best to remove all that crap code and just leave the content of the a case.
Same for the getResourceAsStream() part. This is just to confuse you as Lupe already has written (thumbs up for your comment). If it would be 'real' code writing either Class.getResourceAsStream() or ClassLoader.getResourceAsStream() would be sufficient (there are slight differences between them, though). They all use the systems class loader and not a special one just for the Solution class). Afaik it's used to load resources packed into jar files like properties (that's really cool as you just supply the jar and this comes with the props inside and when running the program you access the settings inside the jar). So you give the getResourceAsStream method the package path + the path inside the pkg. As long as you do not provide a valid 'inner' path to the resource it will throw a null pointer exception (as no resource is referenced).
But I haven't tested this so far. That's just what I've read I worked on that task. To test it you'd need a pkg with some resource inside (as mentioned eg. properties) and that you need to link to.
Ahh... no, why am I always doing this 😜🤪... cause I'm the mad girl, hrrhrrr +1
Jon Hjerting
4 November 2021, 22:01
Thanks for your help. I guess I still don't understand the point of the classloader. But it looks like it more or less is like a FileInputStrem except it requires an absolute path or points to some folder that I don't know where is.
Otherwise it seems that the line
C p = (C) result;
will only work with Class C objects as one cannot cast a parrent Class Object to a child class (?)
Changing the conditional to only allow Class C objects to run that code seemed to make the Solution pass.
+1
Guadalupe Gagnon
5 November 2021, 02:25
"one cannot cast a parrent Class Object to a child class"
Correct. You can declared a variable of a parent class and assign it an object of a child class:
A objectA = new C();
However you can not declare a variable of a child class and set it to a parent object:
C objectC = new A();
This is because an object of C is also and object of A, however an object of A is not an object of C. The reason to extend a class is to add functionaltiy. The way that I remember it is the variable type will determine the methods and fields available. If you are declaring a variable type and assigning it an object, the object MUST have all the methods/fields associated with the variable type or it is illegal. Quick example:
An object of A will have method1() available. An object of B will have both method1() (inherited from A) and method2() available. So if you create a variable of A then any object that you initialize to it MUST have method1(). So both:
are valid. You can use both variables and call method1() from them. If you tried calling method2() it wont work, even for test2 that is a B object. Now if the variables were B instead:
You wouldn't be able to assign it an object A because A does not have a method2() which an object initialized to a B object MUST have.
Extending this logic to the task then the lines that test for an object A and then cast to an object C are logically not sound because if it is an instance of A then casting to C is going to expose methods/fields not guaranteed to be available. 0
Gellert Varga
5 November 2021, 10:56
Jon:
"I guess I still don't understand the point of the classloader."
- Me neither quite exactly.
But that's okay, we already know something about it, so the next time we meet it again, it will be easier to understand more about it.
0
Guadalupe Gagnon
1 November 2021, 03:26
You don't need to know any of that at this point, it is there to distract you. There is only one problem with the code that needs to be fixed. Look at what you do know to find the 1 single line that has a problem in it.
+1