Im still learning and have noticed many inconsistencies when it comes to coding.
I take it Java is pretty much like Photoshop in the way that a single task can be done many different ways and still have the job done.
One of my main questions is when it comes to Scanner and Random.
In one source they have Scanner in the scope of the whole class
public class test {
private static Scanner input = new Scanner(System.in);
}
In another source they have it like this
public class test {
private static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
}
}
What is the difference with this? Is there a right way and a wrong way?
The two ways you've initialized the Scanner are similar, but not quite the same.
The first always works because you're initializing the static variable when it's being created.
The second only works when test is the startup class, because public static void main(String[] args) is always called in an application's startup class.
The problem arises if you try to use a method of the test class from another class, like this:
public class test {
private static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
}
public static void myMethod() {
input.hasNext();
}
}
and in a separate file
public class AnotherTest {
public static void main(String[] args) {
test.myMethod();
}
}
As soon as you run java AnotherTest, it will bomb with a NullPointerException on the input.hasNext() because test's main is never run and thus input is never initialized.
Edit: Side note, class names in Java are almost always capitalized.
There is a difference here!
If you want to access your scanner without invoking any method, then place it in field or static block.
Your example
private static Scanner input = new Scanner(System.in);
is only equal to this
private static Scanner input;
static {
input = new Scanner(System.in);
}
Initialization time is different. Method main is special method in which this is not visible, because this method start your program ;)
You are right, there are for sure many ways to do things and all of them might solve the problem equally good for some use cases.
In your example code, the only difference is basically at what time in the class lifecycle the static variable gets a value declared to it, the scanner-object.
Think of statics to be a part of the class, the template, rather than the object that is constructed with the class as a template of how it should look and function.
I would believe that there are two good reasons for when you need to think of where and when you are initiating your variables.
One is when it comes to thread safety. " is it ok for several threads to be able to access the very same class-member, the scanner? ". A variable declared inside of a method is not accessible outside the method and it isn't accessible by any other threads either.
The other reason is design and structure. We all want to have code that like good and is easy to read and understand. Which is more clear for someone reading your code?
Of course, the thread safety-matter has to be considered before thinking of the design and structure. Just because it would be easier to read some code when all variables are declared at a class level, it doesn't necessarily have to be written like that if it makes the application to fail.
Ultimately, the code you're writing is not what the computer executes when you run the program. If it was an interpreted language like Python or Lua that would be the case, but with a compiled language (not getting involved in the ways Java is special) the language is actually completely converted by the compiler program into an entirely different program in machine code.
As a result, in many cases you can write things several different ways that the compiler will end up writing out as machine code the same way.
There is a distinction here with static variables, as they are initialized immediately, but otherwise the difference here is mostly one of style and appearance, don't worry about it too much. The compiler will understand both and produce largely the same code.
Un-initialized variables are set to defaults (null for objects) which are then set in the constructor, and it may be slightly more efficient to set them during the initialization.
Final values should be initialized, and static, but otherwise its mostly a matter of your preference.
Related
In Java, often main methods are written above (or at least I do so) and in these methods, objects are created even if their respective classes are declared way below. Why does it not result in a compilation error? I know java is not procedural but I never found an answer for this.
public static void main (String[] args)
{
baby1 obj1 = new baby1();
baby2 obj2 = new baby2();
}
class baby1
{
//some code
}
class baby2
{
//some code
}
Java uses Multiple Passes for Name Resolution. The first pass is "Definition Pass" where it scans the source program and stores classes, fields and methods in a table. In the next pass ("Resolution Pass"), if it encountered a class, it looks up for the class in the table created in the previous pass. If the class is there, it continues otherwise it throws an error.
But this doesn't happen for Local Variable Declaration. You can't use a local variable before it has been declared.
public class Test{
static Test test = new Test();
static {
System.out.println("Test class ...");
}
public static void main(String[] args){
}
}
See code above , class Test will get loaded when main is called and a static instance called test will be constructed , has Test class been loaded already when static Test test = new Test(); is called ? If not , is it safe to do like this ? If loaded, is it safe to construct a new object when class has been loaded but not initialized ?
Edit
Code above seems to be causing much concern about the main method while it is not what I am asking .
public class App{
public static void main(String[] args) {
new Test();
}
}
class Test{
static Test app = new Test();
static{
System.out.println("Test ");
}
{
System.out.println("constructing a Test object ...");
}
}
Code here , am I constructing Test object before Test class initialized ? Is it safe to do so ? Is #Thirler's answer telling that it is not safe but can do so ?
This is allowed, and most of the time this will go fine. However this will allow you to create some constructs which seem fine at a quick glance, but fail. For instance the circular reference below.
public class InitTest {
static InitTest test = new InitTest();
private int count = 0;
public static void main(String[] args) {
}
public InitTest() {
test.count++;
}
}
Here the constructor of the static object calls itself. Since the constructor has not yet finished, the object has not yet been assigned (only finished objects are assigned). And this will cause a NullPointerException on test.count++;
Note that the Java Language Specification is quiet readable, chapter 12 talks about loading classes and specifies the order of initialization (which is the formal name of the phase we are talking about, which gets all static variables initialized). Sections 12.4.1 talks about this some more (though rather vaguely). The bold part (my emphasis) refers to the example above and your question.
The intent is that a class or interface type has a set of initializers
that put it in a consistent state, and that this state is the first
state that is observed by other classes. The static initializers and
class variable initializers are executed in textual order, and may not
refer to class variables declared in the class whose declarations
appear textually after the use, even though these class variables are
in scope (§8.3.3). This restriction is designed to detect, at compile
time, most circular or otherwise malformed initializations.
The fact that initialization code is unrestricted allows examples to
be constructed where the value of a class variable can be observed
when it still has its initial default value, before its initializing
expression is evaluated, but such examples are rare in practice. (Such
examples can be also constructed for instance variable initialization
(§12.5).) The full power of the Java programming language is available
in these initializers; programmers must exercise some care. This power
places an extra burden on code generators, but this burden would arise
in any case because the Java programming language is concurrent
(§12.4.2).
Basically they say: because we want initialization to be strong and not place many restrictions, it is possible, but rare to create situations that wont work.
This question already has answers here:
Using JUnit to test a main method that requires simulation of keyboard input with an input stream?
(2 answers)
JUnit test for System.out.println()
(14 answers)
Closed 6 years ago.
I wrote a class which takes input from console and arguments in main method. The main method calls different methods for different console inputs and it calls different function for different arguments. So i want to test this main method with Junit by mimicking these inputs from a file. how can i do it? Is there any special provision in junit to test the main method of the class?
To provide the input from a file, make a FileInputStream and set that as the System.in stream. You'll probably want to set the original back after the main method has finished to make sure anything using it later still works (other tests, JUnit itself...)
Here's an example:
#Test
public void testMain() throws IOException {
System.out.println("main");
String[] args = null;
final InputStream original = System.in;
final FileInputStream fips = new FileInputStream(new File("[path_to_file]"));
System.setIn(fips);
Main.main(args);
System.setIn(original);
}
In your actual code you'll want to handle any IOExceptions and use something better than a full path to the file (get it via the classloader), but this gives you the general idea.
EDIT:
A couple years and some more wisdom later, I'd have to agree with Michael Lloyd Lee mlk's answer as the better approach and what should be preferred if possible. In the class containing your main method (or even a separate class) there ought to be a method that accepts an arbitrary InputStream and the arguments array. It could be a static method. The main method then simply calls it with the System.in stream as argument.
public class Main {
public static void main(String[] args) {
start(System.in, args);
}
public static void start(InputStream input, String[] args) {
// use input and args
}
}
Or alternatively you could have a class with a constructor accepting the arguments array to create a properly configured instance and then call an instance method on it that accepts an InputStream, like so:
public class Main {
public static void main(String[] args) {
Bootstrapper bootstrapper = new Bootstrapper(args);
bootstrapper.start(System.in);
}
}
public class Bootstrapper { // just some name, could be anything else
// could have some instance fields here...
public Bootstrapper(String[] args) {
// use the args to configure this instance, set fields, get resources...
}
public void start(InputStream input) {
// use input
}
}
Whatever fits the requirements and program design best. In both cases you end up with something that can be unit-tested with an InputStream obtained from a file. A test doing a simple static method call to Main.start, or a test creating a Bootstrapper instance and then calling its start method. Now your testing is no longer dependent on the System.in stream. The main method does minimal work and is simple enough for you to just trust its correctness without a separate test. At some point a piece of code becomes so trivial that testing it is equivalent to distrusting the compiler. And an issue in these main methods would become apparent very soon as it's the one method you know will always be called. A main method that does too much or is complex usually points to a lack of modularization in the code.
I leave the original answer in because it does offer a solution in case you really can't get past the use of System.in and testing the main method. That's why I wrote it in the first place, because I couldn't be certain about the asker's constraints. Sometimes someone just wants a straight answer to their exact question because the better approach is not available; you're not allowed to change the code, or refactoring it is too much effort and there's no budget, or some library is used that is hardcoded to use the system streams etc. Note that the original answer is less robust anyway. If the tests are run in parallel instead of sequentially, swapping out a system stream could cause unexpected and inconsistent failures.
IMO the best way to test the main method is by having the main method do absolutely nothing but set up the world and kick it off. This way one simple integration test gives the answer "has the world been set up".
Then all the other questions become much easier to answer.
The main method calls different methods for different console inputs and it calls different function for different arguments.
It should not, it should call someService.somemethod(args). This service gets tested like any other.
So i want to test this main method with Junit by mimicking these inputs from a file. how can i do it?
Either some form of fakes injected in or the use of the TemporaryFolder JUnit rule.
You can call main method from junit test like this:
YourClass.main(new String[] {"arg1", "arg2", "arg3"});
But since main method is void and does not return anything, you should test object that changed after main invocation;
Here is Link How do I test a method that doesn't return anything?
What makes public static void main(String args[]) {} be the convention to test code instead of simply static {}?
class Test {
public static void main(String args[]) {
System.out.println("testing");
}
}
It seemingly has the same capabilities, you can instantiate owner class, use its methods, another classes, even send output as well:
class Test {
static {
System.out.println("testing");
}
}
Is there a standard reason to not use the small static {} to run your average test? Can I take it just as my choice/preference safely?
In other words, I'd like to find a case where you put a code in one that you couldn't (or shouldn't) put in another, that it wouldn't run or give unexpected result, etc.
I'd say the most prominent reason not to use static {} for such things is that you have little control over when it runs. static {} blocks run "when the class is initialized", which means at least four (watch out for the Spanish inquisition) detrimental things for this purpose:
It does not necessarily happen just because the class is loaded.
It does, on the other hand, happen just because you want an instance of the class or reference a static field from some other class, which is the main reason why you don't really want to put code with wide-ranging side-effects in static {} blocks.
It is also not guaranteed to not happen for such simple reasons as the Jar file being on your classpath. JVMs are free to run static {} blocks whenever they feel like it, as long as it is before any static references from the class from other code is made. "Before" could mean "at VM startup".
No VM implementation has any invocation arguments to run such code for you on request.
The purpose of static {} blocks is to initialize static class data (in possibly quite complex ways, of course), and from the preceding points you may be able to see why it's not particularly useful for anything else.
In java every application requires a main method which will be the entry point of the application. The main method required has the signature as follows:
public static void main(String[] args)
The difference between this method and the other one you suggested (besides the fact that your application needs a main method with this signature as an entry point) is that this is a method and takes the "String[] args" parameter. This parameter is where your arguments would go when running a program from the console.
Every java application can be run from the console and therefore it makes sense for every application to have a standard entry point method which will be able to take any special arguments.
Your static {} block is not necessarily a method or a function that can be called and therefore it can not be used as a entry point into your application. It takes no parameters and you have no control over when its code block will be run.
I'm rather confused by the concept of making a class with methods, and having a main method with methods underneath.
What exactly are the differences here? How it one way better than the other way? What situations call for a method under the main rather than a class?
It would help me to understand a project - a basic Craps game which will contain a Shooter class, Die class, and a Craps class (which apparently contains the main).
You do not have "main" methods. All methods are a class method, the only difference is that 'static' methods (v.g., main) do not need that you instantiate a new object (via the 'new' statement) to use them.
In other words:
public class MyClass {
public static void myStaticMethod() {
}
public void myInstanceMethod() {
}
}
You can do
MyClass.myStaticMethod()
but in order to use myInstanceMethod you must create an object
(new MyClass).myInstanceMethod;
Usually you do the last thing as
MyClass myObject = new MyClass();
myObject.myInstanceMethod();
Note that you can also do
myObject.myStaticMethod();
but it is exactly the same than doing
myClass.myStaticMethod();
and the first way is considered poor style and usually causes a compiler warning.
#Miranda because with only static methods you lose all of the Object Oriented part, and you just end using Java as you would use plain C.
In the object, you have both the state and the methods. In the class you store both the object state and the methods. For instance, typically you can create a "Card" class, create a card "new Card('K', "Leaf")" and have methods to manipulate it ("uncoverCard()").
Once you have the reference to the object that you want, you use its methods and you know that you are only affecting this object, and that you are using the right version of the method (because you are using the method defined for this very class).
Switching to OO programming from procedural programming may seem difficult at the beginning. Keep trying, looking at tutorial code and asking for advice when needed and you'll soon get to understand it.
Basically it's a matter of separation. You create classes for reusability. If everything was in the main class then your code would not be maintainable. The main class is used as a starting point for your application. If you did everything in the main class you wouldn't be able to take advantage of all that object oriented programming affords you. You'll learn more about it as you get into the course. But basically each of the classes you will create will have single responsibility. Even the main class, whose responsibility is to run the program.
Good luck with your class by the way. Maybe it will give you an advantage in the casinos.
The entrance-point for a Java-Application is it's main-method:
public static void main(String[] args){
// Do stuff here
}
This method differs from others in the way that it's:
The entrance-point of your application, so it will be the first
called method and basic initialization things should be done here.
It's a static-method which makes it accessible without creating an
instance of the class holding it.
This static-thing is best illustrated as follows:
public class Test{
public int addOne(int number){
return number++;
}
public static int drawOne(int number){
return number--;
}
}
// Create our Int:
int value = 12;
// This will work because the method
// is a static one:
System.out.println( Test.drawOne(value) ); // Outputs 11
// This won't work because it's a non-
// static method:
System.out.println( Test.addOne(value) ); // Error
// But this will work:
Test ourTest = new Test();
System.out.println( ourTest.addOne(value) ); // Outputs 13
An Application written in Java will normally only have one main-Method, which declares the point where the Application first starts off.
If you want to do stuff with variables, objects, etc you'll want to create your own methods/classes but they won't be main-Methods.
First of all, method can't have another method inside it. Every method has to be part of a Class. The difference between a main method (actually the main method which you are talking about) and any other method is that execution of the program starts at the main method.
A method represents a functionality or a set of instructions that have been grouped together. And a class is a set of methods and variables that define an entity (like Shooter, Die).
So you'll have a Die class which will contain methods that will only contain die specific methods, a Shooter class with methods specific to Shooter and a Craps class, from where the game will begin, that utilizes the methods of the Die and Shooter classes to complete the game.
I'm sure some of the other guys here will be able to explain this much better than I can, but I'll give it a shot.
So, as you know, your main method is the sort of entry point to your program. It is the first thing executed. You can add other methods in the same class, but these methods are static methods as you can't instantiate a class that has your main in it (at least I don't think you can; I've never actually tried).
The purpose of making a class and defining methods is so that you can create objects out of that class. For instance, in your case, you create a Die class. You can then create Die objects from that class. Think of a class as a sort of model or mold that you create objects out of. Once you create these objects they each have their own data members (variables defined in the class). Lets say in your Die class you defined two variables, die1 and die2, each Die object you create will have a die1 and die2 variable, but each Die object can hold different values for these variables.
Now, lets say you create a method in the die class that modifies these variables (a setter method) and lets call it public void setDie1(int value) then you can modify the value of the die1 variable by calling that method on the Die object with something like myDieObject.setDie1(3).
To put this altogether, if you just put methods in the same class as your main method then you wouldn't be able to have multiple objects created from the same class.
This can be a tricky concept to figure out at first, but it will all clear up quickly as you learn more. I hope this helps!
The main method
This is the only method REQUIRED to run a Java application. The method MUST have a very specific signature public static void main(String[] args). The reason why it needs this specific signature is because the Java Virtual Machine (JVM) needs to find it in order to execute your program. The JVM is that Java runtime "thingy" you install on your computer to run programs. More correctly, the Java Runtime Environment (JRE) contains the JVM. The String[] args is 0 or more arguments the method accepts from the command prompt when executing a program. Simple programs often don't require any arguments being passed from the command prompt.
What might confuse beginner Java programmers, is that it seems that many projects out there have main methods in every .java file. This is not required. This is done so that each class could be run in isolation from its dependencies. In a project (application) only one class is required to have a main method.
Other methods
Methods other than the main method are optional. If you want, you could place 100% of your program logic inside of main. But, you can understand the problem with that. If you do that, your code will only be able to do a very specific sequence of steps. Back in the days prior to modular programming, this was the way it was done. So, if you needed to write a program that did something slightly different, you needed to write a new program. It is not very efficient, but it still works. Fast forward a few years after "modular programming" became a thing and now you have to write programs that have to react to events. For example, a user hovers the mouse over a button. The problem with events is that events are unpredictable. Not only you don't know WHEN events will occur, but also you cannot predict the ORDER in which they will occur. Therefore, having all the logic inside a single function (i.e. main) won't work and compiling a "different" sequence of steps inside main might not work also because you cannot predict the WHEN and HOW.
Methods allow you to encapsulate very small units of execution in a prescribed order. The assumptions is that, whenever a situation calls for it, the same sequence of steps must be executed. So, you modularize your code and extract those small sequences you know will always execute in that order and put it in some "method" so that you could call that sequence of steps when I needed.
Example
Simple program with no command-line arguments
public class MyProgram {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
When you execute the compiled unit from the command prompt, you will type java MyProgram and in the console you will see "Hello World!"
public class MyProgram {
public static void main(String[] args) {
System.out.println("Hello " + args[0]);
}
}
However, in the above program, if you don't provide an argument, it will throw an exception when executing. But, if you pass at least one argument, it will display the very first argument and ignore the rest. For example, java MyProgram Hector Fontanez will display "Hello Hector"
On both examples, the JVM called the main method for execution.
public class MyProgram {
public static void main(String[] args) {
showGreeting("Hello " + args[0]);
}
public static void showGreeting(String greeting) {
System.out.println(greeting);
}
}
In this last example, I created a function called showGreeting. Contrary to the main method, I as a programmer decided when and where to call this function, not the JVM. In the function, I extracted functionality I thought the method needs to execute in order to "show a greeting". I know my example has only one line. But you get the idea. As my program grows, I can call showGreeting from other parts of the program as many times I think, as a programmer, is necessary for my application to do the job it is required. Not only that, from the main method, the argument being passed will not necessarily the same as the argument that could be passed from another part of the program.
Lastly, you need to understand what are static and non-static methods, and also understand what public, protected, private, and default (no keyword) access modifiers do.