Background info
I have a query regarding a questions from Sierra & Bates, SCJP v6 book. Namely Chapter 2 question 2. The answer given is that the "compilation fails". However when I tried this in neBeans, the code compiled and ran without error. It also returned a output of "D" which was not one of the alternatives. There are some other discussions on this same question in various forums, regarding the need to insert super() etc. However none seem to have recognised it can compile.
Question
1. I expected the constructor "Bottom2(String s)...to have called the super constructor "Top(String s)...". In which case the output would have been "BD" (which happens to be an option for the question. Why does the "Top(String s)..." not get called.
2. As there is a Top constructor then would the default compiler constructor still be implicitly created. ie in effect a "Top() {}" constructor which can be called by "Bottom2(String s)". This not how I understood this to happen - ie the compiler only creates this default if no other constructor is created.
3. Is there and error in this question, or is this a carry over question from the Java 5 version and somehow in Java 6 the compiler can now handle this.
4. Could netBeans have a means to "solve" the compiler problem. This is quite important as I am studying for the SCJP and I find not all the questions can be duplicated in netBeans. In which case I may learn to believe some code works when (for exam purposes) it does not.
Code included for ease of reference.
class Top {
public Top(String s) { System.out.print("B"); }
}
public class Bottom2 extends Top {
public Bottom2(String s) { System.out.print("D"); }
public static void main(String [] args) {
new Bottom2("C");
System.out.println(" ");
}
}
Top doesn't have a default constructor (a default constructor is a public constructor with empty argument list. Therefore, the constructor of Bottom2 must explicitly invoke the super constructor (and pass its argument), but doesn't, and hence compilation fails.
Indeed, eclipse helios says:
Implicit super constructor Top() is undefined. Must explicitly invoke another constructor
and javac says:
cannot find symbol
symbol : constructor Top()
location: class tools.Top
public Bottom2(String s) { System.out.print("D"); }
^
Are you really sure you have tried the same code in Netbeans?
Related
I want to test some code that uses 3rd party code that calls kotlin.system.exitProcess(), defined as follows in the standard lib:
#kotlin.internal.InlineOnly
public inline fun exitProcess(status: Int): Nothing {
System.exit(status)
throw RuntimeException("System.exit returned normally, while it was supposed to halt JVM.")
}
When exitProcess() is called, the JVM stops and further testing is impossible. I didn't manage to mock calls to exitProcess() with mockk. Is it possible?
Some further information:
The 3rd party lib is Clikt (https://ajalt.github.io/clikt/), a nice library for building a command line interface. A Clikt application parses the command line, and exits if this fails. This may be one of the rare reasons, where calling System.exit is OK. Surely there are more testable solutions, but anyway, when working with 3rd party libs, arguing what could be better done in the lib is obsolete.
What I actually want to test is, that my application writes the expected usage message when called with --help or wrong arguments.
I also tried to mock the call to System.exit() this way:
mockkStatic("java.lang.System")
every { System.exit(any()) }.throws(RuntimeException("blubb"))
which leads to another problem, als all calls to System are mocked then:
io.mockk.MockKException: every/verify {} block were run several times. Recorded calls count differ between runs
Round 1: class java.lang.System.getProperty(kotlin.ignore.old.metadata), class java.lang.System.exit(-630127373)
Round 2: class java.lang.System.exit(158522875)
Funnily enough, I managed to test this in Java with jmockit, like this:
public class MainTestJ {
private ByteArrayOutputStream consoleOut;
#BeforeEach
public void mockConsole() {
consoleOut = new ByteArrayOutputStream();
System.setOut(new PrintStream(consoleOut));
}
#Test
public void can_mock_exit() {
new MockUp<System>() {
#Mock
public void exit(int exitCode) {
System.out.println("exit called");
}
};
assertThatThrownBy(() -> {
new Main().main(new String[] { "--help" });
}).isInstanceOf(RuntimeException.class);
assertThat(consoleOut.toString()).startsWith("Usage: bla bla ...");
}
}
I played with this for a while attempting to get it to work but unfortunately it is not possible. There are several difficulties with mocking this function; that it is a Top Level function and that it returns Nothing. Each of these can be overcome, but what makes it impossible is that the function is inlined. Inlined kotlin functions do not produce methods in the bytecode, it is as it says on the tin, inlined. The trouble is that Mockk and other mocking libraries use bytecode instructions when mocking. Refer to this issue for more information.
Your best alternative is not to attempt to mock this function at all, but instead mock the call into the third party library you are using. After all, you should not be testing this third party code, only your own code. Better yet, maybe you should seek an alternative library. As has already been stated in the comments, a third party library should not be exiting the process, this should be left up to the client code.
So Groovy based macros in Intellij IDEA are my excuse for learning Groovy.
Groovy Version: 2.4.9 JVM: 1.8.0_144 Vendor: Oracle Corporation OS: Windows 10
See groovyScript("groovy code") here in the IntelliJ docs:
https://www.jetbrains.com/help/idea/live-template-variables.html
I have a script that IntelliJ calls and it binds the parameters as _1, _2..._n and also there is an _editor... parameter? IDK if it's a parameter or not. There has to be some means for getting the transformed input back out though.
Here is my test script:
public class IvyPaister {
public static void main(String[] args) {
println _1
println _editor
}
}
Here are the errors:
startup failed:
C:\path\to\script.groovy: 4: Apparent variable
'_1' was found in a static scope but doesn't refer to a local variable, static field or class.
Possible causes:
You attempted to reference a variable in the binding or an instance variable from a static
context.
You misspelled a classname or statically imported field. Please check the spelling.
You attempted to use a method '_1' but left out brackets in a place not allowed by the grammar.
# line 4, column 41.
yPaister app = new IvyPaister(_1, _edito
^
C:\path\to\script\pasteIvyDependenciesAsMaven.groovy: 4: Apparent variable
'_editor' was found in a static scope but doesn't refer to a local variable, static field or
class. Possible causes:
You attempted to reference a variable in the binding or an instance variable from a static
context.
You misspelled a classname or statically imported field. Please check the spelling.
You attempted to use a method '_editor' but left out brackets in a place not allowed by the
grammar.
# line 4, column 45.
ster app = new IvyPaister(_1, _editor);
^
This makes sense but I don't know what to do about it in this language. Have tried some variations but no dice. Clues? Ideas? A bone?
Change your script to:
println _1
println _editor
First of all: the title of this post does not match the actual question I have.
But I am also supplying the answer to the original problem (NullRefExcp on bool), so other users will find it's solution here by the chosen title.
I have a class, similar to the following:
ref class CTest
{
bool m_bInit;
void func()
{
if (!m_bInit)
return;
...
}
...
}
Today I had the problem that func crashed with a NullReferenceException at some point although it had been executed successfully many times before.
The exception occured in the line if (!m_bInit)!
I know, you all are saying now, that this is impossible. But it actually was this line. The reason was following:
I have two different variables, both named oTest, but at different places. One of them was initialized: oTest = gcnew CTest. Calling func on this oTest worked well. The first call of func on the other oTest failed with the exception from above. The curious thing is, that the crash seems to happen at the query on m_bInit, also the stacktrace of the exception tells so. But this was just the first place where a member of the not initialized object (it was still nullptr) was called.
Therefore, the advice for other users with the same problem: Check the stack backwards to find a function call on an object that is nullptr/null.
My question now is:
Why does the execution not fail on the first call of a function of oTest which is nullptr?
Why is the function entered and executed until the first access to a member?
Actually, in my case 3 functions were entered and a couple of variables were created on the stack and on the heap...
This code:
void func()
{
if (!m_bInit)
return;
...
}
could actually be written as:
void func()
{
if (!this->m_bInit)
return;
...
}
Hopefully now you can see where the problem comes from.
A member function call is just a regular function call that includes the this parameter implicitly (it's passed along with the other parameters).
The C++/CLI compiler won't perform a nullptr check when calling non-virtual functions - it emits a call MSIL opcode.
This is not actually the case in C#, since the C# compiler will emit the callvirt MSIL opcode even for non-virtual functions. This opcode forces the JIT to perform a null check on the target instance. The only ways you could get this error in C# is by calling the function via reflection or by generating your own IL that uses the call opcode.
Dart Editor version 1.2.0.release (STABLE). Dart SDK version 1.2.0.
This source code produces runtime exception.
void main() {
test(new Base());
}
void test(Child child) {
}
class Base {
}
class Child extends Base {
}
I assumed that the analyzer generates something like this.
The argument type 'Base' cannot be assigned to the parameter type 'Child'
But I can only detect this error at runtime when occurred this exception (post factum).
Unhandled exception:
type 'Base' is not a subtype of type 'Child' of 'child'.
The analyzer is following the language specification here.
It only warns if a the static type of the argument expression is not assignable to the type of function the parameter.
In Dart, expressions of one type is assignable to variables of another type if either type is a subtype of the other.
That is not a safe type check. It does not find all possible errors. On the other hand, it also does not disallow some correct uses like:
Base foo = new Child();
void action(Child c) { ... }
action(foo); // Perfectly correct code at runtime.
Other languages have safe assignment checks, but they also prevent some correct programs. You then have to add (unsafe/runtime checked) cast operators to tell the compiler that you know the program is safe. It's a trade-off where Dart has chosen to be permissive and avoid most casts.
Let's try to be polite and answer the question without any prejudice.
I think I understand what you expected and here my angle on what the error means:
You are invoking the method with the argument of type Base
The method is expecting an argument of type Child
The Child is not equal to the Base, neither is a subtype of it (as a fact it is the Child that is a subtype of the Base)
It is working as expected as it makes only sense to provide object of the expected type (or it's subtypes - specialisations).
Update:
After reading again your question I realised that you are pointing out that editor is not finding the type problem. I assume this is due to the point that Dart programs are dynamic and hence certain checks are not done before the runtime.
Hope it helps ;-)
There is a "NameAndType" structure in the constants pool in .class file.
It is used for dynamic binding.
All methods that class can "export" described as "signature + return type".
Like
"getVector()Ljava/util/Vector;"
That breakes my code when return type of the method in some .jar is changed, even if new type is narrower.
i.e:
I have the following code:
List l = some.getList();
External .jar contains:
public List getList()
Than external jar changes method signature to
public ArrayList getList().
And my code dies in run-time with NoSuchMethodException, because it can't find
getList()Ljava/util/List;
So, I have to recompile my code.
I do not have to change it. Just recompile absolutely the same code!
That also gives ability to have two methods with one signature, but different return types! Compiler would not accept it, but it is possible to do it via direct opcoding.
My questions is why?
Why they did it?
I have only one idea: to prevent sophisticated type checking in the runtime.
You need to look up to the hierarchy and check if there is a parent with List interface.
It takes time, and only compiler has it. JVM does not.
Am I right?
thanks.
One reason may be because method overloading (as opposed to overriding) is determined at compile time. Consider the following methods:
public void doSomething(List util) {}
public void doSomething(ArrayList util) {}
And consider code:
doSomething(getList());
If Java allowed the return type to change and did not throw an exception, the method called would still be doSomething(List) until you recompiled - then it would be doSomething(ArrayList). Which would mean that working code would change behavior just for having recompiled it.