Java.lang.nullpointer exception in a sourcecode - java

Okay, here is the sourcecode -
The program should be able to run a) if no arguments are given, ask for a file name with args
b) if there are args, get these args as parameters for method 'parametr'
The problem is, program works fine with the file input, but if the args are given from CMD or Eclipse. From my point of view, the code is totally fine, but IDK...
//block of a code, thats creates a output file + that should hand
//over a Integer to method 'parametr' from the args array
else if (args.length > 0) {
try {
PrintStream ps = new PrintStream("vystup.txt");
for (int i = 0; i < args.length; i++) {
parametr(Integer.parseInt(args[i]));
}
ps.close();
}
catch (Exception g) {
g.printStackTrace();
System.exit(1);
}
}
}
this points at a Method 'parametr' >>
// this method should just create an array named 'pseudoposloupnost'via method //'Posloupnost' and then copy this array into a new array named 'serazenaPosloupnost'
// rest of the code is not important
public static void parametr (int n) {
Posloupnost(n); //Another method to count array 'pseudo...'
serazenaPosloupnost = new int [pseudoposloupnost.length];
for (int k = 0; k < pseudoposloupnost.length; k++) {
serazenaPosloupnost[k] = pseudoposloupnost[k];
}
serazeniPosloupnosti(serazenaPosloupnost);
ps.println(pseudoposloupnost.length + " " + Arrays.toString(pseudoposloupnost));
ps.println(serazenaPosloupnost.length + " " + Arrays.toString(serazenaPosloupnost));
ps.println();
drawPosloupnost();
}
Java points at these two blocks as a nullpointer exception when I try to run the code from CMD with arguments given.

I think you have two variables called ps. One of them is local to your try block, and the other is (probably) a static class variable. "Probably" because you don't show us its declaration.
Simplified down:
public class myClass {
private static PrintStream ps; // we'll refer to this as "ps1"
public static void parametr(int n) {
...
ps.println("foo");
}
public static void myMethod() {
try {
PrintStream ps =
new PrintStream("x.txt"); // we'll refer to this as "ps2"
parametr(1);
ps.close();
} catch (...) {
}
}
}
This is a matter of scope.
ps1 and ps2 are two different variables.
ps1 is defined but never initialised, so it has a value of null throughout the program.
ps2 is local to the try block surrounding it. It is not passed to parametr(), therefore parametr() doesn't see it.
When parametr() executes ps.println(), it looks at ps1, which is null, hence the NullPointerException.
One way you could fix this is to not create ps1, and pass ps2 into parametr():
public class myClass {
public static void parametr(int n, PrintStream printStream) {
...
printStream.println("foo");
}
public static void myMethod() {
try {
PrintStream ps =
new PrintStream("x.txt"); // we'll refer to this as "ps2"
parametr(1, ps);
ps.close();
} catch (...) {
}
}
}
It's generally good to do this kind of thing, because you can see exactly what variables your methods need and can touch.
Another way you could fix it is by removing the PrintStream from the ps = ... statement in the try block, so you assign to the class variable. This is often not such a good idea, because you're hiding the management of that PrintStream from the reader of the code.
One other tip: you call a method posloupnost(n) (I changed its first letter to lowercase, because Java programmers prefer that). I can guess that either:
this method is a waste of time (because its only parameter is an integer, so the method can't change it)
this method has side effects on a class variable or a global variable.
It's almost always better to pass in the objects that will be affected by the method, so that it's clear what effects it will have. Even if you're going to be printing to the screen, it's better to do:
System.out.println(posloupnost(n));
... or ...
posloupnost(n, System.out);

Related

How could we locate lambda position at the source file by there `getClass().getName()`?

We have some log online, they looks like com.xxx.yyy.SomeClass$$Lambda$12345/7654321#qwert.
Those logs point to some lambda functions (functional interface) like Runnable runnable = () -> {}, however the SomeClass have lots of lambda functions, so need to find the specific line of them at the source file in order to locate the wrong.
By the way, what we've figured out is that all the log of those lambda functions looks $package.$ClassName$$Lambda$index/$number#hashCode, and the same lambda have the same $index/$number before the class recompiled.
This is impossible. The class is generated at runtime and does not reflect the code location that triggered the class generation. The observed index number reflects the order of the class generation, not the appearance of the lambda expression in the code.
As long as the program’s behavior does not change, it may look as if there was a stable mapping between this number and the code location, but we can easily disprove this by creating a program that deliberately changes its behavior:
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.nio.file.Paths;
public class LambdaClassGeneration {
public static void main(String[] args) {
if(args.length == 0) {
runMyself();
return;
}
boolean even = args[0].equals("even");
for(int i = 0; i < 2; i++, even = !even) {
Runnable r;
StackTraceElement e;
if(even) {
r = () -> System.out.println("even");
e = new Exception().getStackTrace()[0];
}
else {
r = () -> System.out.println("odd");
e = new Exception().getStackTrace()[0];
}
r.run();
System.out.println("created at "+e);
System.out.println(r.getClass());
}
}
private static void runMyself() {
String[] cmd = {
Paths.get(System.getProperty("java.home"), "bin", "java").toString(),
"-cp", System.getProperty("java.class.path"),
MethodHandles.lookup().lookupClass().getName(),
"arg"
};
ProcessBuilder p = new ProcessBuilder().inheritIO();
for(int i = 0; i < 2; i++) try {
System.out.println("Run " + i);
cmd[cmd.length-1] = i%2 == 0? "even": "odd";
p.command(cmd).start().waitFor();
System.out.println();
}
catch(IOException | InterruptedException ex) {
ex.printStackTrace();
return;
}
}
}
This program runs itself twice with different parameters, "even" and "odd", to exhibit different behavior, affecting the order in which the lambda expressions are evaluated to objects of a Runnable implementation at runtime.
It prints something like:
Run 0
even
created at LambdaClassGeneration.main(LambdaClassGeneration.java:20)
class LambdaClassGeneration$$Lambda$1/0x0000000800b90840
odd
created at LambdaClassGeneration.main(LambdaClassGeneration.java:24)
class LambdaClassGeneration$$Lambda$2/0x0000000800b91440
Run 1
odd
created at LambdaClassGeneration.main(LambdaClassGeneration.java:24)
class LambdaClassGeneration$$Lambda$1/0x0000000800b90840
even
created at LambdaClassGeneration.main(LambdaClassGeneration.java:20)
class LambdaClassGeneration$$Lambda$2/0x0000000800b91440
Clearly showing that the first generated class gets index one and the second generated class gets index two and there’s nothing in the class name hinting at whether we are looking at the “even” or “odd” runnable.

getConstructor() return a constructor that is not implemented

I'm learning some of the reflection features in Java and I got a strange problem testing the getConstructor() function with this Class.
public class IntegerSequence {
private Integer[] elements;
private int size;
private int MAX_SIZE = 100;
public IntegerSequence() {
elements = new Integer[MAX_SIZE];
size = 0;
System.out.println("Hello Guys");
}
}
The function returns a valid constructor but the "Hello Guys" message is never printed.
Furthermore, If I delete the constructor of IntegerSequence, it also return a valid constructor and doesn't throw any exception, even if there is no one anymore in IntegerSequence class.
I read that getConstructor() only returns a constructor coded in the class and not one made automatically by Java so I'm a bit lost.
Here is the code that use the function and it's output:
public void invokeDefaultConstructor(Class c){
Constructor build = null;
try {
build = c.getConstructor();
} catch (NoSuchMethodException e) {
System.out.println(e);
e.printStackTrace();
}
System.out.println(build.toString());
System.out.println(build.getName());
}
console Output:
public generics.IntegerSequence()
generics.IntegerSequence
Do you know what could cause that kind of behaviour ?
The function return a valid constructor but the "Hello Guys" message is never printed.
That's expected, since you never call the constructor anywhere. You only get the constructor from the class.
I read that getConstructor() only return a constructor coded in the class and not one made automatically by Java
I don't know where you read that. The javadoc certainly doesn't say that.

Method.Invoke without knowing the paramaters

I am using Method.Invoke in java to dynamically call methods in another class. The only issue is that if the methods have paramaters i need to start that in the class.getDeclaredMethod("method", something.class) or else it wont see those methods. The issue with this that i don't know when calling the methods what the parameters will be. How do I get around this?
Also I have done this in C# and its easy and does not require me to state the parameters but this is in Java.
Here is the code that does the Invoke:
public void DoCommand(String msg){
System.out.println(msg);
String[] temp = msg.split(" ");
String command = temp[0];
Class c = commander.getClass();
try {
Object obj = c.newInstance();
try {
System.out.println("'" + command + "'");
Method method = c.getDeclaredMethod(command);
Object[] pars = new Object[temp.length];
for(int i = 0; i < pars.length; i++){
pars[i] = temp[i + 1];
}
if((String)pars[pars.length - 1] == null){
pars[pars.length - 1] = socket;
}
Parameter[] paramaters = method.getParameters();
Object[] endParameters = AltimitConverter.ConvertParameters(pars, paramaters);
try {
method.invoke(obj, endParameters);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {}
}catch (NoSuchMethodException e){
System.out.println(e.toString());
}
}catch (Exception e){
System.out.println(e.toString());
}
}
So how do I call different methods with different parameters without stating the parameters when getting the method.
This is the C# version that does work:
private static void DoCommand(string msg, Socket soc){
string[] temp = msg.Split (' ');
string command = temp [0];
Type type = commandObject.GetType ();
MethodBase commandFunction = type.GetMethod (command);
if (commandFunction != null) {
object[] pars = new object[temp.Length - 1];
for (int i = 0; i < pars.Length; i++) {
pars [i] = temp [i + 1];
}
if ((string)pars [pars.Length - 1] == "") {
pars [pars.Length - 1] = soc;
}
ParameterInfo[] paramaters = commandFunction.GetParameters ();
object[] endParamaters = AltimitConverter.ConvertParams (pars, paramaters);
if (commandFunction != null) {
try {
commandFunction.Invoke (commandObject, endParamaters);
} catch (Exception e) {
Debug.Log (e);
}
} else {
Debug.Log ("commandFunction is null");
}
}
}
Instances of java.lang.reflect.Method reflect specific methods. Each one is associated with a specific class, has a specific parameter list, and has a specific return type. When method overloading is in play, each of the overloaded methods will be reflected by a distinct Method object; these are not interchangeable.
If you need to account for selecting among overloaded methods, then you can do so only with reference to the number and types of the intended arguments. If you have to rely on the arguments themselves to determine matching parameter types, then you're looking at duplicating Java's method-resolution logic, which is complex.
In the event that you need only worry about looking up a non-overloaded method declared by the subject class itself (i.e. not inherited) then you can invoke getDeclaredMethods() on the Class object and scan the resulting array of Method objects for one with the correct name.
You can go a little way into overloaded methods while preserving your sanity if different overloads are distinguished by different numbers of parameters, or maybe if there are specific limits on the parameter type patterns you need to account for, but at that point you really should be asking yourself whether there's a better way. This kind of design absolutely begs for trouble.
I figured out a solution. I created a function to take the intended parameters which are strings and convert them to a data type depending on if it looks like a float, Integer, or string. then i send that into another method that gets all methods in a class and get the ones with the method name i am trying to call and then gets the one with the data types i had in the object[] returned from the first method. and then i use the method i got and the converted data types to call the method.

Methods and declaration java

I am trying to make an program to determine averages for school. I am going to have all the files saved to the computer so its easy to access them for multiple uses. I stated to create multiple methods and discovered a problem. I have the user input for a subject in the startup method but in the main method, sub (the subject string) is used and its says "sub cannot be resolved to a variable" I understand why it say this but I am unsure how to fix.
Here is my code:
public class Calculator {
static int x;
static int b;
public static void startup() {
System.out.println("**Receiving User**");
String user = System.getProperty("user.home");
System.out.println("**Checking Directories**");
boolean dir = new File(user + "/Library/Application Support/Average_Calculator/Settings/").mkdirs();
if (dir) {
System.out.println("**Directory Created at:" + user + "/Library/Application Support/Average_Calculator/**");
} else {
System.out.println("**Directory Has Already Been Created at:" + user
+ "/Library/Application Support/Average_Calculator/**");
}
System.out.println("Welcome to the Average Calculator");
System.out.println("Please input the subject average you want to calculate(no caps)");
Scanner scan = new Scanner(System.in);
String sub = scan.nextLine();
// System.out.println(sub);
try {
// System.out.println("It Does!");
FileOutputStream saveFile = new FileOutputStream(
user + "/Library/Application Support/Average_Calculator/" + sub + ".sav");
ObjectOutputStream save = new ObjectOutputStream(saveFile);
FileOutputStream SetsaveFile = new FileOutputStream(
user + "/Library/Application Support/Average_Calculator/Settings/" + "Setting" + sub + ".sav");
ObjectOutputStream setsave = new ObjectOutputStream(SetsaveFile);
// Create an ObjectOutputStream to put objects into save file.
// Close the file.
save.close();
setsave.close();// This also closes saveFile.
} catch (Exception exc) {
exc.printStackTrace(); // If there was an error, print the info.
}
}
public static void main(String[] args) {
startup();
System.out.println(sub);
try {
// Open file to read from, named SavedObj.sav.
FileInputStream saveFile = new FileInputStream(sub + ".sav");
// Create an ObjectInputStream to get objects from save file.
ObjectInputStream save = new ObjectInputStream(saveFile);
x = (Integer) save.readObject();
b = (Integer) save.readObject();
// Close the file.
save.close(); // This also closes saveFile.
} catch (Exception exc) {
// exc.printStackTrace(); // If there was an error, print the info.
}
// Print the values, to see that they've been recovered.
System.out.println(x);
System.out.println(b);
// All done.
}
}
Thanks for the help!
PS I am new to methods and classes, an explanation would be greatly appreciated!
sub is currently a local variable of startup(), so main() does not have access to it.
One solution is to have startup() return the value of sub, and to have main() use that returned value.
A second solution would be to declare sub (and any other shared variables) as a static variable of the Calculator class, which would place it within the scope of both static methods. In this case, you must no longer declare sub locally within startup(), since that would cause the method to ignore the static variable with the same name.
You are declaring sub in your startup method but trying to access it in your main method. The scope of variables declared in methods is limited to that method; that means that once you leave the method, the variable is no longer accessible. If you want to access a variable both methods one option is to make it a property of the class like you did for x and b. Another option is to return the value of sub at the end of your startup method then simply print your call to the method in main.
Here is a good explanation about classes.
Here is a good explanation about methods (you can ignore the part about functions; the explanation for methods is still good).
Your startup function is returning a void. Change this line:
public static void startup() {
to this:
public static String startup() {
and this line:
startup();
to this:
String sub = startup();

Java String function can not be called because it's not static

Let me explain further. I have a String function (called stringReversal) that returns a reversed string, it has no errors in the function. But, when I try to print using System.out.println() from the main function, it gives me the error "Can not make a static reference to the non static method stringReversal (string s) from the type StringReverse".
I tried giving my stringReversal a static modifier, but after doing so, it gave me run time errors.
Here's what my code looks like:
public class StringReverse {
public String stringReversal(String s){
if(s == null){
return null;
}
else if(s.length()% 2 == 0){
int size = s.length();
for(int i =0; i<s.length(); i++){
s.replace(s.charAt(i), s.charAt(size));
size--;
if(i == (s.length()/2) || size==0)
break;
}
}
else{
for(int i =0; i<s.length(); i++){
int size = s.length();
s.replace(s.charAt(i), s.charAt(size));
size--;
if(i == ((s.length()/2) +1) || size==0 )
break;
}
}
return s;
}
public static void main(String[] args) {
String str = "Hello";
String rev = stringReversal(str);
System.out.println();
}
}
You have to instantiate your class to call object members, or you need to make your function static, indicating it's not part of object oriented paradigm
In your case you can do
StringReverse sr = new StringReverse();
String rev = sr.stringReversal("hello");
or declare your method differently
public static String stringReversal(String s)
In fact the class name StringReverse itself does not sound like some kind of object, so the second way is preferred impo
The deeper problem you have is the confusion on how Java handle OO and entrance function in general. Java is primarily an OO language so most of the time everything shall be an object or a member of a object. But when you telling the VM to run some java code, there got to be a place to start, which is the main method. There has to be one main method and it must be under some class, but it really has nothing to do with the class that contains it. Within the main method, you either start your OO life by instantiating objects and invoking their members (method 1) or stay in the spaghetti world for a bit longer, by calling other static members as procedures (method 2).
You have two options:
Keep the method non static and then create an instance of your class to call the method:
public static void main(String[] args) {
String str = "Hello";
StringReverse sr = new StringReverse(); // instance of class
String rev = sr.stringReversal(str);
System.out.println(); // just prints a blank line lol...
}
Make the method static (you should do this):
public static String stringReversal(String s) {
// ...
}
public static void main(String[] args) {
String str = "Hello";
String rev = stringReversal(str);
System.out.println(); // just prints a blank line lol...
}
Either way, you have to fix your "run time errors". You can't get around that. If your method doesn't work, keeping it not static won't make it work either.
By the way, I think you meant to do System.out.println(rev); instead of System.out.println();
For the record, here is how to easily reverse a string (both methods work):
public static String stringReversal(String s) {
StringBuffer reverseString = new StringBuffer();
// reverse the string
for (int i = s.length() - 1; i > -1; i--) {
reverseString.append(s.charAt(i));
}
return reverseString.toString();
}
/* using the reverse() method in the StringBuffer class
instead of reversing the string through iterations */
public static String stringReversal2(String s) {
return new StringBuffer(s).reverse().toString();
}
This is happening because your Main method is static, but the class that it's in is not. In order to call a non-static method, you need to create an instance of the class. Alternatively, the method can be made static, but in order to refer to it you need to include the class name in your call (as if to use the class itself like an object containing the method - see below).
There are three solutions to this problem:
Make an instance of the class and call the method from your object (recommended).
make the method static and use StringReverse.stringReversal().
Make the class AND the method static.

Categories

Resources