In java is there a way to call a void method from a constructor.I try something like this but get an error message that the compiler can not find symbol method printThis(java.lang.String):
public class Date{
public Date(String inString){
String s = inString;
String b;
b.printThis(s);
}
public void printThis(getString)
{
System.out.printf(System.out.printf( new SimpleDateFormat("MM/dd").format(new SimpleDateFormat("MM/dd").parse(getString) ) );
}
You want printThis(s) - the complier is looking for a printThis method on the String instance, which does not exist.
There are LOTS of errors in the code as presented. These are the ones I spotted.
public class Date{
Problem: you are missing package declaration means this will be in the default package. That's a bad idea.
Problem: you are using a class name that is the same as commonly used classes in the standard class library. That's a bad idea.
public Date(String inString){
String s = inString;
String b;
b.printThis(s);
Error: The code attempts to invoke a method in the String API called printThis(...). No such method exists. You should probably get rid of b and just call printThis(s)
Error: The code attempts to use an uninitialized local (b) and this will give a compilation error (if you "fixed" the previous error by changing the type of b to something that did have a printThis method).
Problem: It is bad practice for a constructor to invoke a method on the object being constructed if there is any possibility that it might be overridden in a subclass. The problem is that the overriding method (from the subclass) might be called on the object before the superclass initialization has completed. It is safe to call static or private methods.
}
public void printThis(getString) {
Error: There is a syntax error in the declaration. Change getString to String getString.
Problem: The choice of parameter name is (IMO) nonsensical. What is a "get string"???
System.out.printf(System.out.printf(
new SimpleDateFormat("MM/dd").format(
new SimpleDateFormat("MM/dd").parse(getString) ) );
Error: Compilation error: the parentheses don't balance.
Error: Compilation error: the first argument to printf must be a String or a Locale. In your code, the first argument in the outer call is a PrintStream instance.
Error: System.out.printf(System.out.printf( is nonsensical. You almost certainly should use just System.out.println or System.out.print. If you do use a printf method you have to supply a format string in the syntax specified in the PrintStream javadocs. (This is NOT the same as the syntax used for date formats!!!)
}
Error: missing '}' to complete class.
Problem: Your code style needs a lot of work. If you can swear on a bible that nobody else is ever going to have to read your code (!), then I suppose its OK. Otherwise, this kind of stuff is unacceptable. If this was homework, I'd dock you 50% of your marks straight off for making no attempt to get the style correct.
You have used printThis() as a method of String. If you want to print the date you might want
printThis(s);
It's not generally a good idea to use the same class name (Date) as the JDK library class
The following lines are not going to work:
String b;
b.printThis(s);
What the above code is doing is attempting to call the printThis method on the String object called b.
Since a String.printThis method does not exist, the compiler returns the error message saying that it could not find the method.
What is probably intended is the following:
printThis(s);
The above will call the printThis method of the current instance.
You're getting that error because you're trying to call printThis() on object b, which is a String. You want:
public Date(String inString) {
printThis(inString);
}
Just FYI, it's generally inadvisable to name classes the same as JDK classes (like Date). Also the assignment you're doing of inString doesn't really achieve anything. Perhaps your code is a simplification of what you're doing but I thought I'd mention it anyway.
Related
I'm studying the new Stream API for the OCP exam and I found something that I don't really understand. Here's my code:
void methodOne() {
this.compare(1, 2); // This works fine.
Stream.of(1,2,3)
.sorted(this::compare); // Compilation error.
}
static Integer compare(Integer s1, Integer s2) {
return 0;
}
Here I have a static method called compare and a non-static one called compare. If I call the compare method from the non-static method I get a compiler warning:
The method compare(Integer, Integer) from the type TestStream should be accessed in a static way
If I instead use a method reference to that same method in my stream, that compiler warning becomes a compiler error with the same message.
I know why I get the warning but I don't get why this warning becomes a compilation error if I use a method reference. I didn't find anything online either. Can someone explain it to me?
Accessing a static method via a reference was seen as a design error to this day AFAIK. You can even do:
YourClass c = null;
c.compare (...)
And that would work just fine (with a warning though).
When java-8 features where designed this was corrected, so the only way to access a static method (for a method reference) is via the class itself:
YourClass::compare
I know why I get the warning but I don't get why this warning becomes
a compilation error if I a method reference. I didn't find anything
online either. Can someone explain it to me?
It should have been a compilation error in both cases, but the earlier versions of Java tolerated it because the designers of the language didn't know better, and now for continued compatibility it is too late to change it.
However, method references are a newly constructed language syntax. When you're using the construction <object instance>::<method name>, then by definition the method you're trying to reference cannot be a static method since you're accessing it by specifying what object instance you want it applied to, which a static method is incapable to do.
Doing it right this time and rejecting invalid constructs that try to access static stuff through an instance, doesn't break any existing syntax of the language that may have been used somewhere by someone, albeit unwisely. So they did it right this time. Don't do invalid things, the compiler ought to reject them, and in that case it will.
It would also complicate parameters inference in case of overloaded methods, some static and some non-static. But it wouldn't be the first inference hell they would have to make do with.
I want to know why the below code doesn't work :
System.out.print(null);
response.getWriter().print(null);
But the below ones work :
String s = null;
System.out.print(s);
response.getWriter().print(s);
Whats the difference between passing a null as compared to passing a reference as null ?
EDITED : Doesn't work fore mentioned indicates to compilation error .
This is because you can pass an Object or a String. Since null can fit in both, the compiler doesn't know which method to use, leading to compile error.
Methods definitions:
System.out.print(Object)
System.out.print(String)
Instead, if you provide an Object or a String variable (even if it has null value), the compiler would know which method to use.
EDIT: This is better explained in this answer. As to the internal link pointing to the Java specification, you can read it here, and this case would suit here:
The informal intuition is that one method is more specific than another **if any invocation handled by the first method could be passed on to the other one without a compile-time type error.
It is possible that no method is the most specific, because there are two or more methods that are maximally specific.
It's because System.out.println() expects something with a type. null doesn't have a type, and therefore it can't be output on it's own. This is shown by:
Doesn't work:
System.out.println(null);
Works:
System.out.println((String)null);
System.out.println((char[])null);
System.out.println((Object)null);
It's the compiler type-checking the parameters of the method call.
Thank you all for your answers . From your inputs , I compiled the answer myself . It seems the call System.out.print(null) is ambiguous to compiler because print(null) here will find the two best specific matches i.e. print(String) and print(char[]) . So compiler is unable to determine which method to call here .
Small example will be :
private void methodCall(String str) {
}
private void methodCall(char[] ch){
}
Now this code becomes ambigious : methodCall(null) .
I have a method that returns a list of a generic type, method shown below.
protected <T extends SQLDataBean> List<T> getJavaListFromOracleArray(Array array) throws SQLException
I then have an object called a ReplacementBean that extends SQLDataBean.
In another class I have a List<ReplacementBean> with a set method taking in a List<ReplacementBean>
What I have found and I'm not sure why is I can not call the above listed method inside the set. Meaning this gives a compile time error:
setReplacements(this.getJavaListFromOracleArray(in.readArray()));
However the following compiles and works fine.
List<ReplacementsBean> temp = this.getJavaListFromOracleArray(in.readArray());
setReplacements(temp);
I have also tried to cast inside the set method as follows, but it also has a compile time error.
setReplacements((List<ReplacementsBean>)this.getJavaListFromOracleArray(in.readArray()));
Is there any way to not have to do the two line process of setting a temporary local variable before calling my set method? While it does work, it would be nice to not have to do it.
calling the following:
setReplacements(this.getJavaListFromOracleArray(in.readArray()));
results in a error of setReplacements(List<ReplacementsBean>) is not applicable for the arguments List<SQLDataBean>
The setReplacements code is as follows:
public void setReplacements(List<ReplacementsBean> replacements)
{
this.replacements = replacements;
}
Also if I try this:
setReplacements((List<ReplacementsBean>)this.getJavaListFromOracleArray(in.readArray()));
I get the error Cannot cast from List<SQLDataBean> to List<ReplacementsBean>.
This is one of those cases where the compiler type inference isn't quite as good as you might like it to be. The following should work, where you specify the generic method type parameter explicitly:
setReplacements(this.<ReplacementsBean>getJavaListFromOracleArray(in.readArray()));
In the temporary variable case
List<ReplacementsBean> temp = this.getJavaListFromOracleArray(in.readArray());
setReplacements(temp);
the compiler is forced to instantiate <T> as <ReplacementsBean> to make the assignment work.
The problem is that inside the compiler the following is done:
List<X> temp = getJavaListFromOracleArray(in.readArray());
setReplacements(temp);
where X must be ReplacementsBean or a child thereof. And that is open-ended. In many more formally typed languages the X is resolved, in java not. Hence the need for:
setReplacements(<ReplacementsBean>getJavaListFromOracleArray(in.readArray()));
However this "defect" is also a clear symptom: probably getJavaListFromOracleArray does unsafe generics.
Mind also that the function setReplacements might be overriden in a child class with as parameter a List<ReplacementsBeanChild>.
Create a new exception class IllegalDimensionException that extends Exception class. It will have two constructors, one default- value and one explicit value that uses the message "Illegal dimension for the figure you specified.
Does this seem to be correct way of doing this??
public class IllegalDimensionException extends Exception {
String message; //the message that will be used
String Eplicitm = "Illegal dimension for the figure you specified";
//constructor one
public IllegalDimensionException (String m){
m = message;
}
//constructor two
public IllegalDimensionException(String E){
E = Eplicitm;
}
public static void main(String[] args){
return E;
}
}
Im having trouble creating two constructors without one being void? Any suggestions in how I can get this to correctly work??
Any two constructors (or any methods for that matter) must have a different method fingerprint (aka signature). The fingerprint consists of;
The method name
The method return type
The method parameters (by type)
You are trying to create two constructors that have the same fingerprint, which is not allowed. After all, how does the compiler know which method you are trying to call?
As a side note; your code makes little sense:
public IllegalDimensionException (String m){
m = message;
}
Has literally no effect, you are overwriting the value of your local variable m with your instance variable message...I can only assume you were meaning to do this the other way around?
Constructor should not have return type, so your second "Constructor" is not actually constructor, instead it is a method with constructor like name. I am wondering why it is not giving you any error since you do not return anything from here.
And if you just remove void from the second one, it will not work because both of the constructors then will have same type of arguements, so will not be overlaoded consturctor, instead would be duplicates. In which case you will get error again.
Please look at this link for the real answer of your question, How to define custom exception class in Java, the easiest way?
Maybe something like that answer your question:
public IllegalDimensionException (String m) {
super(m); // you may use the exception message member instead of defining yours
message = m;
}
public IllegalDimensionException(){
this(Eplicitm);
}
Thus you really have two constructors: one with default value and one with custom message.
If this is what you expect, the Eplicitm should be a constant (static final).
It will have two constructors, one default- value and one explicit value that uses the message "Illegal dimension for the figure you specified.
It sounds like what you really need for your two constructors are a default (parameter-less) one as well as one which accepts a String parameter. e.g.,
public IllegalDimensionException() {
super(Eplicitm);
}
public IllegalDimensionException(String m) {
message = m;
}
The super() call in the default constructor will call Exception's constructor, which accepts a String, and pass up your Eplicitm to it.
However you are making several fundamental flaws in the logic of your code snippet above which I'd like to point out to you:
You can not specify an extra return type for a constructor (as you do in your "constructor two" with public void IllegalDimensionException). This is because IllegalDimensionException essentially is the return type, as you are creating a new instance of the object with it. Your above signature will instead create a new method called IllegalDimensionException which returns void and must be called by an instance of this exception... so you've essentially created a setter method with an overly complex (and poorly formatted) name.
It does not make sense for an Exception to have a main(String[]) method. A main() is essentially the kick start for an entire program, while an Exception is something that is created when something goes wrong within a program. As you create more complex projects, you will want to keep the function of each class fundamentally separate, distinct, and logical.
A constant such as a default value should be declared as private static final. As your code stands, any code that can obtain an instance of your IllegalDimensionException can change the default message by simply calling theException.Eplicitm = "Yo yo yo, wassup.". Not a very helpful error message. This is because the default privacy of variables is public. Fortunately, you have not declared it static yet, so such a change would only affect one instance of the exception... but it is much better practice for there to be only one immutable version of this across all possible exceptions that are created.
Variable names should be in camel case (variableName) while class names should begin with all capitals (MyClass). Constants should be in all upper-case with separations as underscores (MY_CONSTANT_VALUE).
Some of the above might sound nit picky, but it's really not. All of the above either close loopholes in your code (some of which are pretty dangerous) or make your code substantially more readable (which you'll find is a great boon - because even you will forget why in the heck you wrote some section of code when you go back to look at it three months later). For example, I'm sure I'm not the only professional programmer who took a while to figure out what you meant by Eplicitm (apart from the spelling), because it looks like the name of a complex, custom-defined object... not a String!
This might be what you are looking for. The question you are answering is unclear, so I'm not sure:
public final class IllegalDimensionException extends Exception {
private static final String DEFAULT =
"Illegal dimension for the figure you specified";
//constructor one
public IllegalDimensionException(){
super(DEFAULT);
}
//constructor two
public IllegalDimensionException(String message){
super(message);
}
}
Note the usage of super() to pass the exception message correctly to the super class.
I have a class
class Configuration {
// various stuff
#Override
public String toString() {
// assemble outString
return outString;
}
}
I also have another class
class Log {
public static void d(String format, Object... d) {
// print the format using d
}
}
The Log class works perfectly fine, I use it all the time. Now when I do this:
Configuration config = getConfiguration();
Log.d(config);
I get the compiler error The method d(String, Object...) in the type Log is not applicable for the arguments (Configuration). I can solve this:
Log.d("" + config); // solution 1
Log.d(config.toString()); // solution 2
My problem: How is this different? In the first solution, the compiler notices that it has to concatenate two Strings, but the second one is a Configuration. So Configuration#toString() is called and everything is fine. In the compiler error case the compiler sees that a String is needed, but a Configuration is given. Basically the same problem.
Needed: String
Given: Configuration
How are these cases different and why is toString not called?
While designing the language, someone decided that when a programmer appends an arbitrary object to a string using the + operator, they definitely want a String, so implicitly calling toString() makes sense.
But if you call an arbitrary method that takes a String with something else, that is simply a type error, exactly what all that static typing is supposed to prevent.
The line
"" + config
gets translated to something like
StringBuilder sb = new StringBuilder("");
sb.append(config);
where the second line calls
StringBuilder.append(Object obj);
This method calls obj.toString() to get the String representation of the object.
On the other hand, the first parameter of Log.d must be a String, and Java doesn't automatically call toString() to cast everything to a String in that case.
One of the common use of toString(), is print() and println() methods of PrintStream, as in:
System.out.print(object);
System.out.println(object);
Basically, these two methods will call toString() on the passed object. This is one of the Polymorphism's benefits.
Nice Question...
But,
Compiler does not call a method to match formal parameters. it simply tries to cast the objects if possible.
But when you use the "+" operator the compiler executes the toString() method of its arguments (in case they are objects) by default.
In one case you are passing an object argument to an operator which expects objects.
In the earlier case you are passing an object argument to a function which expects string.
Basically function/operator signature is different.
It is almost incidental [in the context of this question] that .tostring called when + is applied. It takes an object and does something.
For all you know, you might be passing in object when string is required by mistake. So it can't blindly do .tostring()
You are passing Configuration class object argument in case 1 but in the case 2 , you are passing string argument . so no error occures.