I'm learning to do some Java 101 syntax stuff. In an exercise I'm trying to do, I can't get the incremented value to print. Any ideas?
Here is my code:
class StaticTest {
static int i = 47;
}
class incrementable {
static void increment() { StaticTest.i++; }
}
class DataOnly {
int i;
double d;
boolean b;
public static void main (String[] args) {
incrementable t = new incrementable();
DataOnly df = new DataOnly();
df.i = t.increment();
System.out.println(df.i);
}
}
The error I get is:
aTyp0eName.java:18: incompatible types
found: void
required: int
df.i = t.increment();
df.i is an int and so is t.increment. I'm guessing it's because increment() is void?
your method signature is:
static void
Which means nothing is returned from this method.
Hence, attempting to assign increment() to df.i won't work.
increment() doesn't have a return value. You'd need to have it return an int for your code to work:
class incrementable {
static int increment() {
StaticTest.i++;
return StaticTest.i;
}
}
"void" is a keyword reserved for methods which don't return any value. Otherwise, you specify what class or primitive you return (int, double, String, whatever). You can read more about return values here.
Also, for future reference, class names should be capitalized, so you should be using "Incrementable" rather than "incrementable". (In my sample code I kept it the same as you had it so you could just drop the code in for now.)
The error I get is:
aTyp0eName.java:18: incompatible types
found: void
required: int
df.i = t.increment();
df.i is an int and so is t.increment [fault?]. I'm guessing it's because increment() is void?
Eeeexactly, your guess is correct.
This is the error message explained line by line:
aTyp0eName.java:18: incompatible types
You are trying to assign "void" to an int in line 18.
df.i = t.increment();
Here is where the error is.
found: void
You declare what's the return type in the method "signature".
The method signature is :
<access modifiers> <return type> <method name> (<parameters> )
static void increment ()
So the return type is void.
Next line:
required: int
df.i is int as you have previously stated.
So, pretty much you have already your own question answered.
The good point of having a compiler is that it tells you when something is wrong.
The bad thing ( for humans ) you have to learn to read those messages. They vary from programming language to another and even from compiler to compiler.
This would be a corrected version:
class StaticTest {
static int i = 47;
}
class Incrementable {
static int increment() {
return ++StaticTest.i;
}
}
class DataOnly {
int i;
double d;
boolean b;
public static void main (String[] args) {
Incrementable t = new Incrementable();
DataOnly df = new DataOnly();
df.i = t.increment();
System.out.println(df.i);
}
}
There are some other enhancements could be done, such as adding access modifiers to the methods and attributes, but for now I think this would help.
The answer is that the increment() method returns a void. That being said, there are a lot of violations of the Java standard syntax that programmers generally use, Namely:
Class names should start with a capital letter.
fields should not be mutated from different classes, rather a helper method should be within the same class
If you want to call a static method, don't reference an instance variable, rather use ClassName.reference
If a variable is only needed locally, it should not be a field (df.i could just be an int i declared within the main method).
EDIT:
An example of a helper method within the same class:
class StaticTest {
private static int i = 47; //keep i private and mutate and access via methods
public static void increment() { i++; }
public static int getI() { return i; }
}
also, if you instantiate incrementable, you shouldn't define the method increment() as static. or you can, but don't need to.
you could simply incrementable.increment() if it's static.
just a tip. as for the answer to your question, toolkit already said that right.
Also, your incrementable class should really be Incrementable.
Related
I would like to pass a reference to a primitive type to a method, which may change it.
Consider the following sample:
public class Main {
Integer x = new Integer(42);
Integer y = new Integer(42);
public static void main(String[] args) {
Main main = new Main();
System.out.println("x Before increment: " + main.x);
// based on some logic, call increment either on x or y
increment(main.x);
System.out.println("x after increment: " + main.x);
}
private static void increment(Integer int_ref) {
++int_ref;
}
}
The output running the sample is:
x Before increment: 42
x after increment: 42
Which means int_ref was past to the function by value, and not by reference, despite my optimistic name.
Obviously there are ways to work around this particular example, but my real application is way more complex, and in general one would imagine that a "pointer" or reference to integer would be useful in many scenarios.
I've tried to pass Object to the function (then casting to int), and various other methods, with no luck. One workaround that seems to be working would be to define my own version of Integer class:
private static class IntegerWrapper {
private int value;
IntegerWrapper(int value) { this.value = value; }
void plusplus() { ++value; }
int getValue() { return value; }
}
Doing this, and passing a reference to IntegerWrapper does work as expected, but to my taste it seems very lame. Coming from C#, where boxed variable just remain boxed, I hope I just miss something.
EDIT:
I would argue my question isn't a duplicate of Is Java "pass-by-reference" or "pass-by-value"?, as my question isn't theoretical, as I simply seek a solution. Philosophically, all method calls in all languages are pass-by-value: They either pass the actual value, or a reference to the value - by value.
So, I would rephrase my question: What is the common paradigm to workaround the issue that in java I'm unable to pass a reference to an Integer. Is the IntegerWrapper suggested above a known paradigm? Does a similar class (maybe MutableInt) already exist in the library? Maybe an array of length 1 a common practice and has some performance advantage? Am I the only person annoyed by the fact he can store a reference to any kind of object, but the basic types?
Integer is immutable, as you may notice.
Your approach with private static class IntegerWrapper is correct one. Using array with size 1 is also correct, but in practice I have never seen using array for this case. So do use IntegerWrapper.
Exactly the same implementation you can find in Apache org.apache.commons.lang3.mutable.MutableInt.
In your example you also can provide Main instance to the static method:
public class Main {
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
incrementX(main);
}
private static void incrementX(Main main) {
main.x++;
}
}
And finally, from Java8 you could define an inc function and use it to increment value:
public class Main {
private static final IntFunction<Integer> INC = val -> val + 1;
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
main.x = INC.apply(main.x);
}
}
I have an assignment where we make a bunch of different methods based on uml. the uml looks like this +add2Nums(iX1:int,iX2:int):int and my code looks like this:
import java.util.Scanner;
public class proj2
{
public static void main(String[] args)
{
add2Nums(2,3);
} //End main
public static int add2Nums(int iX1, int iX2)
{
}//End add2Nums
}//End proj2
I get an error saying i am missing a return statement, however if i change the type from int to void in the method declaration, it will compile but this goes against what the uml is telling me to do. I feel like im missing something super important, can anyone tell me whats going on?
You should simply return something (int in your case) in your add2Nums method as the compiler tells you:
public static int add2Nums(int iX1, int iX2)
{
int num = iX1 + iX2;
return num; //this is what you are missing
}
Your method signature has int type:
public static int add2Nums(int iX1, int iX2) //note the "[int] add2Nums"
Thus, the compiler expects the method block to have return the same data type/its parent type (int or its parent types) in all possible paths of the code.
you method signature says it is going to return an integer value. But
you do not return anything from within your method, hence the error.
public static int add2Nums(int iX1, int iX2)
{
return iX1 + iX2;
}
I have experience working in Java but have recently started doing work in C++, I'm having a little trouble understanding how things are stored in memory in the latter. In java, the following is valid:
class Class {
int myInt;
public Class(int myInt) {
this.myInt = myInt;
}
}
So I have an integer within the class, I give it a value when the object is created. I want to replicate this in C++:
class Class {
int myInt;
public:
Class (int myInt) {
// What goes here?
}
};
This however doesn't work. If I name the variable being passed into the constructor something other than myInt, I can simply state myInt = differentName. But suppose like in the Java, I want both the variable passed to the constructor and the name of the variable to be the same? How can I achieve this?
Two options:
Using an Initializer list:
class Class {
int myInt;
public:
Class (int myInt) : myInt(myInt)
{
}
};
What you were intentionally looking for:
class Class {
int myInt;
public:
Class (int myInt)
{
Class::myInt = myInt;
}
};
But the first one is preferred.
You just need to use the constructor initialization list:
class Class {
int myInt;
public:
Class (int myInt) : myInt(myInt)
{
// by the time you get here, myInt is already initialized.
// You can assign a value to it or modify it otherwise,
// but you cannot initialize something more than once.
}
};
That the only way to explicitly initialize a data member in a constructor. Once you're in the body of the constructor, all data members have been initialized.
In addition to the initializer syntax, this is also available in C++. You would use it as this->myInt because this is a pointer.
"this" is a pointer in C++. So it'll be
this->myInt = myInt;
The following is the way to achieve the same in c++
this->myInt = myInt;
My question is regarding the declaration and value assignment rules in Java.
When writing the fields we can declare and assign values together but we cannot do the same separately.
E.G.:
class TestClass1 {
private int a = 1;
private int b ;
b= 1;
private int sum;
public int getA() {
return a;
}
public int getB() {
return b;
}
public int getSum() {
sum = a + b;
return sum;
}
}
public class TestClass {
public static void main(String[] args) {
TestClass1 testClass1 = new TestClass1();
System.out.println("total =" + testClass1.getSum());
}
}
Here in line:
private int a = 1;
We are able to declare a as a private int and assign a value 1 to it. But in case of:
private int b ;
b= 1;
Eclipse does not allow this to happen and throws an error. Kindly explain the logic behind this.
Code inside a class, but outside a function, is purely declarations. It does not get "executed". It simply declares what fields a class contains.
The reason you can do the shorthand private int a = 1; is just syntactic sugar that the Java language allows. In reality, what happens is that the a = 1 part is executed as part of the constructor. It's just easier to read and write when it is next to the variable declaration.
It's something nice that the Java langage creators allowed. Not every language allows that, look at C++ as an example that does not always allow it.
you have to put b=1; inside a method or put this inside a constructor.
you are getting this error since you can't do any thing other than declaration(private int a= 1;
) in class level.
It's just a question of syntax in Java. In the example you show, you try to affect a value to b in the member declaration part of your class. This is not allowed by the syntax of Java. You can only do it when you declare your attribute, in the body of a method or in a static block if your attribute is static e.g. :
private static int b;
static {
b = 1;
}
It is only a syntax problem. You can do it like this :
private int b ;
{ // <- Initialization block
b= 1;
}
See What is an initialization block?
You are unable to write logic directly in the class. You should move it to the constructor.
Java only allow declaration within the class and outside any method. Declarations like int b = 1; will be executed when you initialize a new Object.
I have errors when I run program(1). But when I used program(2), writing 0 after a, it run and produced the correct output. Writing 0, is just my guess and somehow it worked. Why is that?
Program (1):
public static void main(String[] args) {
System.out.println(a);
}
private static int a(int len) {
String s = "What";
len = s.length();
return (len);
}
}
Program (2):
public static void main(String[] args) {
System.out.println(a(0));
}
private static int a(int len) {
String s = "What";
len = s.length();
return (len);
}
}
You wrote the function in such a way that it requires a parameter. To call a function that requires a parameter, you have to supply one. That's why the second program worked--you gave the function a a parameter of 0.
To make the first program work, then, you have two options. The first is what you did--supply the required parameter for the function. The second is to modify the function declaration so it does not require a parameter, changing
private static int a(int len) {
to
private static int a() {
public static void main(String[] args) {
System.out.println(a);
}
private static int a(int len) {
String s = "What";
len = s.length();
return (len);
}
The problem here is that a is a function which receives a single integer parameter. This code is therefore a compilation error:
System.out.println(a);
You cannot print a function. What you can do is call a function and print that function's return value. Which is precisely what your second chunk of code does.
However, since your function a ignores its input parameter, you could re-write the code like this:
public static void main(String[] args) {
System.out.println(a());
}
private static int a() {
String s = "What";
int len = s.length();
return len;
}
Note that you still need to call the function using parentheses, a(). But because there is no longer a parameter required, you can leave the parameter list empty.
(Note: this really has nothing to do with the string length part. It's just simple method calling.)
Well look at this code:
public static void main(String[] args) {
System.out.println(a);
}
That's trying to use a as if it's a variable - it's not, it's a method. So you want to invoke that method, and use the return value, which is what you do in your second version.
Admittedly it's pretty odd to pass in an argument and then not use it, and likewise you've got unnecessary parentheses around your return value - return isn't a method call.
So your code can be simplified to:
public static void main(String[] args) {
System.out.println(a());
}
private static int a() {
return "What".length();
}
Or if you really want the local variable:
public static void main(String[] args) {
System.out.println(a());
}
private static int a() {
String s = "What";
return s.length();
}
You seem to be confusing method parameters with normal variable declarations. You've written a as a method that takes a single int parameter, so you need to pass it a value; but you don't actually use that value in the body of the function.
You probably really want to use a local variable, and not pass a parameter at all, e.g.:
public static void main(String[] args) {
System.out.println(a());
}
private static int a() {
String s = "What";
int len = s.length();
return (len);
Note that you still need to write a() in the call, not just a, to make clear that it is a method call.
The first code can't compile as you are trying to output a variable a that has not been declared (this syntax is not a method call). In the second one you are actually calling the static method a that exists, so it runs.
a is a function not a variable. You cannot call a function without the paranthesis...
you would have to type in a() to call the function.
Now, what happens in the first case is, since there are missing paranthesis it tries to resolve it as a variable and errors out.
The second case is where you call the function in the correct fashion
You need to read up on how to make method calls. This is one of the most basic things you will be doing in java.
When you want to call method a, you need to pass the correct number of arguments(in this case a single int) or the method call will not be recognized and be an error. What IDE are you using to develop your java code? If you are using something like Eclipse you shouldnt even be able to run the code with this error present.
Your function a is defined as a function that takes a single argument, which is named len. When you call it as a(0), you provide that argument and everything works just fine. When you call it as a, you do not provide that argument and compilation fails. The code never runs.
The question is: why have you defined a to take an argument? It isn't used: its value is immediately overwritten with the result of s.length().
It seems like you are attempting to declare a local variable for use by mentioning it in the function signature. That does is not necessary, and does not work, in Java.