Understanding Interfaces, classes and constructors in java - java

Right now I'm trying to implement this interface with an int which represents a binary number.
I know I shouldn't implementto string(); , but Let's assume that I need to.
This is what I wrote so far:
public class IPAddressInt implements IPAddress {
private int ipAdress;
public IPAddressInt(int num1,int num2, int num3, int num4){
String n1=Integer.toBinaryString(num1);
String n2=Integer.toBinaryString(num2);
String n3=Integer.toBinaryString(num3);
String n4=Integer.toBinaryString(num4);
String finalString=n1+n2+n3+n4;
this.ipAdress=Integer.parseInt(finalString);
}
public String toString() {
return this.toString();
}
when I'm tring to return this.ipAdress.toString(); or even ipAdress.toString()
the compiler says that it Cannot invoke toString() on the primitive type int,
and when I write only this.toString(); it works. why? I know that an int can be converted to a string, and how come the this works and the whole statement is not? shouldn't it be the same? will I get what I want anyway?
Thank you.

Calling this.toString() is just going to blow up - it's calling the same method recursively, with no exit.
The reason you can't call toString directly on ipAddress is that int is a primitive type, and you can't call methods on primitive types.
To convert anything to a string, use String.valueOf(ipAddress). For int in particular, you could use Integer.toString(ipAddress).
It's not really clear why you're doing the conversion to a binary string in the first place though... that doesn't look like a good idea to me. Any reason why you're not using
ipAddress = (num1 << 24) | (num2 << 16) | (num3 << 8) | num4;
(assuming each value is really in the range 0-255).
I highly doubt that the binary representation is really want you want, particularly given the lack of padding, and that you're then trying to parse it as a decimal number.

When you say "it works" I suspect you mean "it compiles". If you actually call that toString method you'll get a stack overflow, or maybe just an infinite loop if your compiler/JVM is very clever.
To convert an int to a string, call Integer.toString(this.ipAdress). (But preferably spell address correctly :-).)
[EDITED to add: after writing this I see that in another answer Jon Skeet prefers String.valueOf rather than Integer.toString for this purpose. He's a very smart chap and probably has a good reason. It'll mean less has to change if you change the type of ipAddress -- er, I mean ipAdress, for instance.]

What you want is probably to implement the toString method like this:
public String toString()
{
return Integer.toString(ipAdress);
}
What the compiler says is true because you cannot invoke ANY methods on primitive types. You have to wrap the primitive int into an Integer which has the method toString implemented. The code snippet above is just a more effective way of calling:
return Integer.valueOf(ipAdress).toString();

Your toString method is recursively calling itself and will end up in a stack overflow exception.
Try converting ipAdress to a String like this:
public String toString() {
return Integer.toString(ipAdress);
}
FYI, your variable ipAdress has a typo, should be ipAddress.

Related

Java's toString() static or non-static (based on my example)

I am new to the concepts of oop and therefore what I write have may have bad assumptions. Please correct me where appropriate.
In some code I saw a function takes in an argument in the form of int number. Then, in the function the following line is written outputString = Integer.toString( number );
I interpreted this as go the the class Integer, find a method called toString() and feed this the int called number and set the output of that to outputString. Since the syntax is class.method(arg) I assumed that toString() is a static function.
I wanted to test if it was static. I rewrote the code with the argument as Integer number and then did outputString = number.toString(); and it worked. This has the form obj.method(arg) which I had assumed would only work for non static methods.
I am unsure what conclusion to draw from this or if I have made a wrong assumption. Thanks.
If you're talking about the class Integer, it has two methods toString, one static and the other one is not static.
Integer a = 5;
a.toString() // Is valid
Integer.toString(5); // Also is valid
There are 3 methods in java.lang.Integer class.
public static String toString(int i);
public static String toString(int i, int radix);
public String toString();
In your first case, you have used the 1st one ( a static method).
In your second case, you have used the 3rd one ( a non-static method).
I think you should know more information about inheritance in java. All classes extend Object class, that is why all classes have non-static toString() method and can override it. Class Integer have also static toString(int number) that returns String representation of int.
The Integer class has 2 methods as below;
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(buf, true);
}
AND
public String toString() {
return toString(value);
}
Both the methods are self explanatory. To Note second method calls the first one.
Integer.toString(1); // Calls method 1
Integer one = 1;
one.toString(); // Calls method 2
You may also want to lookup the Object's toString() method, which by the way gets inherited in every objects in java. This method is not static. The Integer's toString(int) method is only specific to the Integer class. This method is static (does not work on objects, but only on the Integer class). You will also want to check out the concepts of "method overriding", "method overloading" and "polymorphism". Here's a page containing almost exactly your question: https://www.geeksforgeeks.org/can-we-overload-or-override-static-methods-in-java/

Why does this print exception?

String bob2 = "3";
System.out.println((int)bob2);
I'm unsure of why this causes an exception. Can anyone explain? Pretty sure because of the int on String type, but want to make sure.
Yes you are right its because of typecasting. If u need to convert String to int use below code
Integer.parseInt("3");
You are correct.
You can't just cast a string to an int.
You should convert it using Integer.parseInt()
Use this
Integer.valueOf("3");
or
Integer.parseInt("3");
In Java whenever you are trying to change type of an entity to another, both the types should have some relation. Like if you are trying to caste a sub class object to super class, it will work smoothly. But if you try to compare a Person object with a Lion object, that comparison is meaning less, the same is the logic in casting. We cannot cast a Person object to Lion object.
In your code bob is String type and you are trying to cast it to int and in Java both String and Integer is not having any relation. That's why Java is throwing Exception, Class Cast Exception I guess, this is raised when different types of objects are compared.
But the parseInt(String arg) method in Integer class gives an option to convert numeric String to Integer, given that the argument is a qualified Integer as per Java standards.
Example :-
String numericString = "1234";
int numberConverted = Integer.parseInt(numericString);
System.out.println(numberConverted);
You can also try these which will tell you the precautions before using this method
int numberConverted = Integer.parseInt("1234r");
int numberConverted = Integer.parseInt("1234.56");
int numberConverted = Integer.parseInt("11111111111111111111111111111");
You can't cast String to Integer. Change:
System.out.println((int)bob2);
to:
System.out.println(Integer.parseInt(bob2));
It will create an Integer value from the String provided with bob2 variable. You can also create a reference to int variable like this if you want to store primitive int instead of Integer:
int intBob2 = Integer.parseInt(bob2);

why it always giving call integer parameter method not short parameter method

This is my code:
public class Test
{
public static void main(String arg[]) {
new Test().method1(5);
}
public void method1(int b) { // integer method
System.out.println("integer ");
}
public void method1(short a) { // short method
System.out.println("short");
}
}
I am running this class, and it gives me result of integer. Why it is not giving short?
Because the literal 5 is by default understood as an int. If you want to call the method1(short a) method, you need to explicitly do a cast:
new Test().method1((short) 5);
The literal 5 has type int, that's why the method that expects an int is called.
new Test().method1((short)5) would call the method that expects a short.
Default type of Java integer literals is int thats why integer method is getting invoked.
you have to apply type conversion because you are willing to call a function which receives short.
try calling with:(short)5
It's because, as noted in the other answers, a 5 on its own denotes an int. You can denote a long by appending an L, so 5L would be treated as a long. If you want a byte or a short then you have to cast explicitly.
It may be that you have a good reason for wanting a method that takes a short, but please bear in mind that this is quite rare. Certainly you would not want to be doing this for performance reasons. Java uses a 32-bit int by default because pretty much every processor out there can work natively with 32-bit integers. You will probably find that a short will operate more slowly than an int.
(Of course, if you're doing specifically 16-bit arithmetic, then you might still need to use a short.)

Return two Strings from method

I'm a beginner in Java programming, and I'm trying to make a voting machine program, where you can vote for Republicans or Democrats. My question is, how can I edit my method so I would be able to return two strings with two distinct values?
For example, look at my code all the way in the bottom. It's wrong, but I wanted the tester to be able to print out Democrats: (some number) and Republicans: (some number) in one method. How can I do that?
import java.lang.String;
public class VotingMachine1 {
private double Democrats;
private double Republicans;
public VotingMachine1() {
Democrats = 0;
Republicans = 0;
}
public void voteRepublican() {
Republicans = Republicans + 1;
}
public void voteDemocrat() {
Democrats = Democrats + 1;
}
public void clearMachineState() {
Republicans = 0;
Democrats = 0;
}
//this is where I'm having difficulties. I know its wrong
public double getTallies() {
System.out.println("Democrats: ", return Democrats);
System.out.println("Republicans: ", return Republicans);
}
}
No return is necessary there, since you aren't leaving a function. To do what you seem to want to do, just replace that last method with the following:
public void getTallies()
{
System.out.println("Democrats: " + Double.toString(Democrats));
System.out.println("Republicans: " + Double.toString(Republicans));
}
Also, since your votecounts should only ever be integers, there's no reason to declare them as doubles instead of ints.
What you are looking for here is a format string. A format string is used when you know what your output should look like, and only have a few "holes" where unknown data should be filled in. To output your data using format strings, you would use the System.out.format(String, Object...) method:
System.out.format("Democrats: %f\n", Democrats);
System.out.format("Republicans: %f\n", Republicans);
In this case, the %f indicates that a floating-point number (since your variables are declared as double) will be printed instead of the %f. However, you may wish to consider declaring them as int (or long) instead, in which case you would use %d instead of %f in the format strings.
Finally, you ought to change your getTallies() method to return void instead of double, as you are printing the values, not returning them.
Your code and your description are so contradictory, it is not clear that you even know what you are trying to do. I believe that this is the real root of your problems.
Here goes:
public double getTallies()
{
System.out.println("Democrats: ", return Democrats);
System.out.println("Republicans: ", return Republicans);
}
First, your question says that you want to "return two strings with two values" ... but you have declared the method as returning one double.
Next, your code is printing values ... not returning them.
You've also made some major mistakes at the syntactic level, largely (I believe) because you are trying to do contradictory things:
return Republicans is not a valid Java expression, so you can't use it as a argument to the println method.
The println method can't be called with two arguments, as your code is trying to do. There is a zero argument version and a number of one argument overloads ... but no overloads with two or more arguments.
Basically, you need to start by making up your mind about what this method is supposed to do. Is it supposed to:
return the tallies (as two doubles)?
return a string representing the two tallies?
return nothing ... and output the two tallies to standard output?
do something else?
Once you've made up your mind:
code the method to do what you've decided it should do, and
chose a method name that correctly reflects what it is supposed to do. Hint: a method that starts with get is conventionally a "getter" that returns the attribute or attributes themselves ... not a String rendering.
double is a bad choice of type for a vote count too:
You cannot have a fractional vote.
You want to represent vote counts precisely and floating point types (like double) are not precise. (Or at least, not in the sense that you require.)
When you attempt to format or output a double, the resulting character string is likely to include a pesky decimal point ... or worse.
You should use int or long instead of double.
Finally, this is a serious Java style violation, and should get you a significant penalty if your marker is paying attention.
private double Democrats;
private double Republicans;
Variable names in Java should start with a LOWER CASE letter.
A few more random comments:
import java.lang.String; is superfluous as all classes in package java.lang are automatically imported in every Java source file.
Votes can not be fractional. People can't vote 0.75 candidate A, and 0.25 candidate B. If you use integer datatypes (int or long), you will be reflecting this fact better. Also, you will be saving yourself a lot of headache when you start obtaining results like 379857.999999. This is because floating point types have a better range, but worse precision (especially noticeable when working with pure integers).
According to Java usual naming conventions, variable names should start with a lowecase letter.
A better name for function getTallies is printTallies.
For output purposes, it's much better to use string formatting than concatenation. Some advantages are: multiple formats supported, ease of use, and internationalization.
Putting all together:
private int democratVotes;
private int republicanVotes;
public void printTallies() {
System.out.format("Democrats: %,d%n",democratVotes);
System.out.format("Republicans: %,d%n",republicanVotes);
}
In this particular case, votes will be printed with thousand separation (ex: 3,345,623 instead of 3345623). Check Java's Formatting Numeric Print Output tutorial.
Thinking better about it, there are some alternatives where getTallies would effectively be returning some form of value:
1) Make it to return a String with both tallies. It would be hard and inefficient to separate the tallies later, though.
public String getTallies() {
return "Democrats: %,d votes. Republicans: %,d votes.%n".format(democratVotes,republicanVotes);
}
2) Make it to return an array.
public int[] getTallies() {
return new int[2]{ democratVotes, republicanVotes };
}
public int[] getTallies1() { // Same as getTallies, but written step by step.
int[] result= new int[2] ;
result[0]= democratVotes ;
result[1]= republicanVotes ;
return result ;
}
3) Make it to return a class.
public VotingMachineResults getTallies() {
return VotingMachineResults(democratVotes,republicanVotes) ;
}
public static class VotingMachineResults {
private int democratVotes;
private int republicanVotes;
public VotingMachineResults(democratVotes,republicanVotes) {
this.democratVotes= democratVotes ; // `this` required to disambiguate field democratVotes from parameter democratVotes.
this.republicanVotes= republicanVotes ;
}
public int getDemocratVotes() {
return democratVotes ;
}
public int getRepublicanVotes() {
return republicanVotes ;
}
}
As you can see, this class is very similar to VotingMachine1, but it does not accept internal state changes. It is a "value" class.
In Java, you concatenate Strings with the + operator. Proper syntax for what you were trying to do looks like this:
System.out.println("Democrats: " + Democrats);
System.out.println("Republicans: " + Republicans);
A return statement is only used when you want to return some object or value to a method that called your current method. It is not appropriate in this place since you're only passing a value to another method (println()).
ALSO, you need to fix your getTallies() method. Make it return void instead of double since you aren't returning anything.
Here's something completely different: why not override toString()?
Presumably, any instance of VotingMachine1 will apply for all votes that you care about for that instance. That is to say, you don't create a new instance of a VotingMachine1 every time someone casts a vote.
So, what you can do is override the toString() method. We'll also use String.format() to handle the numerical values.
#Override
public String toString() {
// assumes that Democrats and Republicans are declared as int
// since it's pointless to indicate percentages of a vote
return String.format("Democrats: %d\nRepublicans: %d", Democrats, Republicans);
}
Now, whenever you vote, you can use the toString() method to get the information (which is called whenever one does System.out.println(object).
VotingMachine1 voter = new VotingMachine1();
voter.voteDemocrat();
voter.voteRepublican();
System.out.println(voter);
/* This prints:
Democrats: 1
Republicans: 1
*/
A less specific answer to your question would be to return an Object called (say) Votes
public class Vote {
int democratVotes
int republicanVotes
}
and then make your VotingMachine class simply return an instance of this object (suitably changed to make it immutable).
On my project we have created a generic version of this called a Tuple that returns a pair of values in a single object - it has an overloaded toString method for easy printing.
you can return an array with [0] and [1] as key and devide it on the basis of your need..
like
returnArray[0]="first string";
returnArray[1]="second string";
and use it ur way...

How does System.out.print() work?

I have worked with Java for a quite a long time, and I was wondering how the function System.out.print() works.
Here is my doubt:
Being a function, it has a declaration somewhere in the io package. But how did Java developers do that, since this function can take in any number of arguments and any argument types no matter how they are arranged? e.g:
System.out.print("Hello World");
System.out.print("My name is" + foo);
System.out.print("Sum of " + a + "and " + b + "is " + c);
System.out.print("Total USD is " + usd);
No matter what is the datatype of variables a, b, c, usd, foo or how they are passed, System.out.print() never throws an error.
For me, I have never worked on any project where the requirement was like this. Provided, if I get a requirement like this, I really don't know how to solve it.
Can anyone explain to me how it's done?
System.out is just an instance of PrintStream. You can check its JavaDoc. Its variability is based on method overloading (multiple methods with the same name, but with different parameters).
This print stream is sending its output to so called standard output.
In your question you mention a technique called variadic functions (or varargs). Unfortunately that is not supported by PrintStream#print, so you must be mistaking this with something else. However it is very easy to implement these in Java. Just check the documentation.
And if you are curious how Java knows how to concatenate non-string variables "foo" + 1 + true + myObj, it is mainly responsibility of a Java compiler.
When there is no variable involved in the concatenation, the compiler simply concatenates the string. When there is a variable involved, the concatenation is translated into StringBuilder#append chain. There is no concatenation instruction in the resulting byte code; i.e. the + operator (when talking about string concatenation) is resolved during the compilation.
All types in Java can be converted to string (int via methods in Integer class, boolean via methods in Boolean class, objects via their own #toString, ...). You can check StringBuilder's source code if you are interested.
UPDATE: I was curious myself and checked (using javap) what my example System.out.println("foo" + 1 + true + myObj) compiles into. The result:
System.out.println(new StringBuilder("foo1true").append(myObj).toString());
Even though it look as if System.put.print...() take a variable number of arguments it doesn't. If you look closely, the string is simply concatenated and you can do the same with any string. The only thing that happens is, that the objects you are passing in, are implicitily converted to a string by java calling the toString() method.
If you try to do this it will fail:
int i = 0;
String s = i;
System.out.println(s);
Reason is, because here the implicit conversion is not done.
However if you change it to
int i = 0;
String s = "" + i;
System.out.println(s);
It works and this is what happens when using System.put.print...() as well.
If you want to implement a variable number of arguments in java to mimimc something like C printf you can declare it like this:
public void t(String s, String ... args)
{
String val = args[1];
}
What happens here is that an array of Strings is passed in, with the length of the provided arguments. Here Java can do the type checking for you.
If you want truly a printf then you have to do it like this:
public void t(String s, Object ... args)
{
String val = args[1].toString();
}
Then would you have to cast or interpret the arguments accordingly.
It is a very sensitive point to understand how System.out.print works.
If the first element is String then plus(+) operator works as String concate operator. If the first element is integer plus(+) operator works as mathematical operator.
public static void main(String args[]) {
System.out.println("String" + 8 + 8); //String88
System.out.println(8 + 8+ "String"); //16String
}
Evidently, the compiler was made in a confusing way although the compiler developers thought they added some smartness. The true smartness they should really add is to look entire argument and interpret + operator consistently. For example, System.out.println(1+2+"hello"+3+4); should output 3hello7 instead of 3hello34
I think you are confused with the printf(String format, Object... args) method. The first argument is the format string, which is mandatory, rest you can pass an arbitrary number of Objects.
There is no such overload for both the print() and println() methods.
Its all about Method Overloading.
There are individual methods for each data type in println() method
If you pass object :
Prints an Object and then terminate the line. This method calls at first String.valueOf(x) to get the printed object's string value, then behaves as though it invokes print(String) and then println().
If you pass Primitive type:
corresponding primitive type method calls
if you pass String :
corresponding println(String x) method calls
You can convert anything to a String as long as you choose what to print. The requirement was quite simple since Objet.toString() can return a default dumb string: package.classname + # + object number.
If your print method should return an XML or JSON serialization, the basic result of toString() wouldn't be acceptable. Even though the method succeed.
Here is a simple example to show that Java can be dumb
public class MockTest{
String field1;
String field2;
public MockTest(String field1,String field2){
this.field1=field1;
this.field2=field2;
}
}
System.out.println(new MockTest("a","b");
will print something package.Mocktest#3254487 ! Even though you only have two String members and this could be implemented to print
Mocktest#3254487{"field1":"a","field2":"b"}
(or pretty much how it appears in the debbuger)
#ikis, firstly as #Devolus said these are not multiple aruements passed to print(). Indeed all these arguments passed get
concatenated to form a single String. So print() does not teakes multiple arguements (a. k. a. var-args). Now the concept that remains to discuss is how print() prints any type of the arguement passed
to it.
To explain this - toString() is the secret:
System is a class, with a static field out, of type PrintStream. So you're calling the println(Object x) method of a
PrintStream.
It is implemented like this:
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
As wee see, it's calling the String.valueOf(Object) method. This is implemented as follows:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
And here you see, that toString() is called.
So whatever is returned from the toString() method of that class, same gets printed.
And as we know the toString() is in Object class and thus inherits a default iplementation from Object.
ex: Remember when we have a class whose toString() we override and then we pass that ref variable to print, what do you see printed? - It's what we return from the toString().
The scenarios that you have mentioned are not of overloading, you are just concatenating different variables with a String.
System.out.print("Hello World");
System.out.print("My name is" + foo);
System.out.print("Sum of " + a + "and " + b + "is " + c);
System.out.print("Total USD is " + usd);
in all of these cases, you are only calling print(String s) because when something is concatenated with a string it gets converted to a String by calling the toString() of that object, and primitives are directly concatenated.
However if you want to know of different signatures then yes print() is overloaded for various arguments.

Categories