Technology

Overview: 
Explore the Java concept of class packages and using packages with the Imports statement.
Objectives: 

Understand the Java concept of class packages and using packages with the Imports statement.

Content: 

A real project, even robotics projects, can end up having many classes. You will likely need to use classes in libraries provided by FIRST or others. Finding the classes you need, controlling access to them and naming conflicts between your classes and library classes would be a problem. You may also want to organize a group of your classes into a library that can be reused with other projects or other robotics teams. Packages give us a way to group together related classes in a unique naming scheme and reference them from other classes.

Packages are intended to group related classes together and facilitate access control and prevent naming conflicts. Naming conflicts would occur if all the library classes you use and all of your classes were all grouped together, and there are library classes that have the same names as your own classes.

You create packages with the package statement placed at the start of your class files. The package statement has your package name (more on names later) and all classes with the same package name in your project are grouped into that package. All Java programs must have a package and If you don't use a package statement, your classes are grouped into the default "unnamed" package. It is good programming practice to at least put all of the classes in a project into the same directly named package. Here is more about packages.

The Java built-in library of classes is organized into the java package and there are many sub-packages organized by function. A name.name.name format is used to create a hierarchy within packages. Here is a detailed discussion of package naming.

While a specific package name format is not required there is a detailed convention used in package names. For robotics, you might want to use a name format like this:   

org.usfirst.<fll/ftc/frc>.teamnumber.projectname

or a simpler but perfectly valid one:

teamnumber.projectname

The first example locates your project package in relation to the world. Your package would not conflict with any other package if named like this. This is a nice convention but only important if your code can be integrated into other peoples projects and you plan to do so. The second example shows a simpler package structure that works fine for projects not shared with anyone else.

Packages organize classes we want to make use of in our own classes. So how do we access these other classes? The types (another name for classes) in a package are referred to as members. To access the members of a package you can specify the fully qualified package name when using classes, fields or methods or you can use the import statement. Using fully qualified package names can get pretty tedious. The import statement makes the package name known to the compiler so that when the compiler finds a class, field or method name it does not find in your code, it uses the imported packages to look for the name. This is called resolving the reference. Here is a discussion on using the import statement. Please read this discussion as it covers important details not discussed here.

Robot programs will import some number of Java packages and some number of packages from the robotics library provided for your hardware platform. You will see examples of this when you get to the unit covering your hardware platform.

Note that you do not see any imports or package name in the CodingGround examples. CodingGround uses the default package and is doing any needed imports for you behind the scenes.

Finally, many Java compilers and IDEs want to organize your source files (.java) into directories based on the package name(s) you use. Typically a directory hierarchy is created by IDEs that matches the package hierarchy when you create a package in an IDE. So the package name suggested above might have the directory hierarchy:

c:\projectname\src\org\usfirst\frc\team4450\projectname

or

c:\projectname\src\team4450\projectname

Note that project name is repeated because the projectname right after the c:\ is not part of the package, but is part of the project directory hierarchy.

Here is a summary discussion of packages and import. Here is a video on this topic.

One more important aspect of this topic. With import you tell Java what packages or classes within packages you want to use. But where does Java actually find that code to include in your program? When a programmer creates a library of classes, (a package) the deployment step for such a project is to create a .jar file. Jar means Java Archive and is a special zip file containing the byte code for the classes packaged into the jar file. You tell your IDE what jar files are available on your computer and then when you use an import statement, Java can locate the code to import in the jar files it knows about through your IDE. Typically, one part of an SDK is all of the jar files needed to develop your programs. Your robot platform SDK contains the jar files you need and automatically configures your IDE to know about them. At some point you may wish to use a package of classes not included in the robot SDK. You would download the jar file containing the package and tell your IDE about the jar file and then you can import members from the package.

 

Navigation:

Overview: 
Explore the difference between passing primitive parameters and reference parameters.
Objectives: 

Understand the difference in behavior of primitive data type parameters and reference data type parameters in methods.

Content: 

In the lesson on passing parameters we learned that primitive parameters are passed by value, that is, a copy of the calling code's variable value is given to the method for it's internal use. Reference variable (object instance pointer) parameters are passed the same way but there is an important distinction to make in how reference parameters (objects) are used in methods.

For this lesson, we are going to use the String object and a new object called StringBuffer. StringBuffer is part of the standard Java API library. We will use String and StringBuffer to illustrate show Java manages object instances and reference variables.

 String objects are immutable, meaning that once they are created they can't be changed. So if we do this:

The first statement created a String object instance with the value "abc". Java allocates computer memory and places a String object containing the characters abc into that memory and places a reference (pointer) to that memory location in the variable myString. The second statement creates a new String object instance with the value "xyz" and places a reference to that new object in the same variable, myString. At this point the reference (pointer) to the original object containing "abc" is now no longer available to us. "abc" still exists in memory but we overlayed the reference to "abc" with a reference to "xyz". The String object "abc" is now orphaned, meaning it no longer is connected to a variable in our program and will be discarded by Java. This is called garbage collection.

Note that the String object has no methods that change it's contents. Strings are modified by making a new String object from the old one. Here is another example:

Here again, we did not modify the string "abc" with the second statement. A new string is created containing the characters myString references, "abc" in this case, and concatenates the string "xyz" to create a new string containing "abcxyz" and a reference to this new string is stored in myString. The original string containing "abc" is no longer referenced by this code and will be garbage collected.

Now the StringBuffer class does provide methods to change it's contents without creating a new object. So if we do this:

The first statement creates a new StringBuffer object instance and places "abc" into it. The second statement calls a method on the StringBuffer object that adds "xyz" to the "abc" already inside the StringBuffer object instance without creating a new instance. When done, mySB is still a reference to the same StringBuffer object which now contains "abcxyz".

So with all of that out of the way we can discuss the nuances of using reference parameters in a method.

Consider this example:

The intent of the method is to append "xyz" to whatever is in the String str. After the call to myMethod(), what is in the String myStr? The answer is "abc". Why? The parameter myStr is passed as a copy and placed into the method variable str. In the method, we change the contents of str. Str now points to a new String object instance containing "abcxyz". However, this new String object instance reference is not passed back to the calling code. myStr still points to "abc". Now consider this example:

After the call to myMethod1(), what does mySB contain? The answer is "abcxyz". Why? Because we called a method on the mySB object instance using the copy of mySB passed into the method's sb variable. This means that sb also references or points to the same object instance as mySB. With the StringBuffer object's append method, we change the internal state of the object instance jointly pointed to by sb and mySB.

After the call to myMethod2(), what does mySB contain? The answer is still "abcxyz". Why? Because we created a new StringBuffer object instance containing "xyz" and stored the reference to it in sb. For the rest of the method sb contains a reference to "xyz". Since we changed the object instance that sb points to, the method lost its pointer to mySB and can't reference it after that point. Note that at the end of the method sb, which contains "123456", will be released since variables created in a method only exist while that method is executing.

As a final point, in our first example the method wanted to append "xyz" to whatever string was passed into it, but it does not change the string that was passed in. Here is how you could fix that method:

Here the method concatenates the two strings using the + operator and creates a new string with it's reference deposited into str. The method then returns this new string reference and the calling code replaces the original string reference with the returned string reference and so myStr ends up pointing to the string instance "abcxyz".

A final note about garbage collection. In the last example, str will go out of scope when the method ends. You might think the new string pointed to by str would be orphaned and then garbage collected. However, since a reference to the actual string object instance in memory was passed back to the calling program and placed into myStr, the string object is not orphaned and will continue to exist. When a reference to an object instance is stored in a variable, the JVM keeps track of that by incrementing the object instance's reference count. When a variable that references an object goes out of scope or the variable has something new stored in it, the JVM decrements the object instance reference count. This is how the JVM knows when an object instance is orphaned, when its reference count goes to zero (no variable is pointing to it). When no variable is pointing to an object instance in memory, that object instance is no longer accessible and the memory can be released.

Here is a video about the difference between primitive and reference variables and how they are passed to methods.

Here are the examples on CodingGround.

 

Navigation:

Overview: 
Explore general topics related to using objects in Java programs.
Objectives: 

Understand additional basic concepts related to using objects in Java programs.

Content: 

Now we are going to look at some aspects of using objects in your code.

The first topic is access-modifiers. An access-modifier is one of the modifier keywords that can be specified before the word class when defining a class, before the Data Type when defining a variable and before the return Data Type when defining a method. We have been using public for access modifiers thus far. An access-modifier determines what access other classes have to the components of your class. There are several different access-modifier keywords but for robotics projects, public and private are sufficient. For classes, always use public. This means other classes can access your class.

When defining class level fields (recall that fields are the internal variables or ‘properties’ that an object may have), you can use public or private. For fields, public means other classes can access the field directly. Private means the field may only be accessed by code in your class. For robotics, fields can be public or private, but good programming practice says fields should be private, that is, only accessible outside your class through methods.

When defining methods, you can use public or private. For methods, public means other classes can call the method and private means the method can only be called by other methods in the same class. For robotics, methods can be either public or private as you think best. Private methods are those that support your class and don't really make sense to call from other classes. Here is more information about access control.

The next topic is object instance lifetime. When you create an object instance with the new keyword, a block of memory for the class variables is allocated in computer memory and a pointer to that memory location is placed in your object variable. The fact that there is a pointer to the instance in memory is recorded (called reference count). Any additional pointers to the same instance increment the reference count. As long as the reference count for an object instance is not zero, the instance will  be maintained in memory. When the reference count goes to zero, no one is using the instance and the JVM marks the memory as garbage and it will eventually be reclaimed by the system. The reference count is decremented whenever a variable pointing to an object instance is deleted (goes out of scope) or the value of the variable is changed to point to some other object instance or no instance all (null).

The next topic is variable scoping. Scoping describes the lifetime of variables you create in your program. When you define variables in a class at the class level, those variables will be allocated memory when a class instance is created with the new keyword. As long as the class instance is in use (reference count not zero), those fields will exist in memory. When a class instance is not being used anymore (marked for garbage collection), all of it's variables will have their memory released as part of that process.

Variables defined in methods (local) only have memory assigned to them when the method is executing. When a method starts, the local variables are allocated memory and retain it while the method runs. When the method ends, the memory is released. When a variable's memory is released because it's containing method or class ends it is called going out of scope.

Our next topic is the this keyword. The this keyword refers to the current instance of the containing object. The this keyword helps resolve ambiguity in naming within a class. In a constructor or method, if you use a variable or parameter name that is the same as a class field, the method local name hides the class field of the same name. The this keyword allows you to access the hidden name. Additionally, when calling a method which has a parameter which is a reference to the instance of the calling class, this allows you to pass the calling instance. Here is an an example of that:

This may seem a strange example but in reality there are many cases where a method in another class needs our own class instance as a parameter. Here is more information about the this keyword.

 

Navigation:

Overview: 
Explore object constructor methods.
Objectives: 

Understand what an object constructor is and how it is used.

Content: 

Objects have special kind of method called a constructor. A constructor is an optional method that is called when a new instance of an object is created with the new keyword. Constructors are used to initialize the fields of the new object instance. A constructor looks like a method except that it has no return data type (including void) and has the same name as the class. A constructor can have a parameter list and a class can have more than one constructor by varying the parameter list. Lets look at our Dog class from the previous lesson:

We see that the fields breed and name are not initialized. This would lead to a run time error (called an exception) if we called the bark() method without first putting something in the breed and name fields. We can fix this with direct initialization of the fields or with a constructor method, and we will add a second constructor that allows us to set the breed and name fields when we create a new Dog object:

 So in another place in your code you would write:

We have added three constructors, the first with no parameters which would create a Dog object with the breed field set to an empty string. We directly set the name field to an empty string. When we create an instance of this class, the bark() method won't fail because the constructor is called and initializes the breed field and the name field is initialized when the object is created by Java. If we use the second constructor when we create the Dog object instance, the breed field is set with our desired value. If we use the third constructor when we create the Dog object the breed and name fields are set to our desired values on one statement.

If you omit a constructor, the Java compiler creates one for you internally. That default constructor has no parameters and no code so it really does nothing.

Note that the second constructor shows the use of the this keyword again and also how you can do it without using this.

Here is a video about constructors.

Here is the example on CodingGround. Modify the example to add an age variable (field) and a constructor that allows you to initialize the age (along with breed and name) when creating a new Dog object instance.

 

 

Navigation:

Overview: 
Introduction to access control modifier keywords.
Objectives: 

Gain a basic understanding of access control modifiers.

Content: 

You have seen the access control modifier public used extensively in our Java examples. The access control modifier is applied to classes and class members (variables and methods) and determines what access code in other classes have to the class members.

Classes can have no access modifier before the class name and will default to package-private. This means the class is only visible to top level classes in the same package. You can also use public, which means the class is visible inside and outside of its package.

At the member level, things get a bit more complicated. You can use access modifiers of public, private, protected or the default, package-private (when no modifier is specified).

  • public - The member is accessible to the world.
  • private - The member is accessible only in the same class it is defined.
  • protected - The member is accessible only in classes defined in the same package or any subclasses thereof.
  • package-private - The member is accessible only to other classes in the same package but not in subclasses. Again, this is the default when no access modifier is specified.

In robotics, using public for everything will work fine. Access modifiers are typically important when creating libraries that will be shared with other projects. In those cases, there may be internal members that should not be exposed to users of the library.

Here is a video about access control. We will discuss access control in more detail in a later lesson.

 

Navigation:

Overview: 
Explore the basics of objects and classes.
Objectives: 

Understand what objects and classes are and a basic idea of how to use them.

Content: 

Java is an object-oriented language so it stands to reason that objects are the workhorse construct of the language. We have talked about objects and classes in previous lessons but now its time start our detailed exploration of objects.

An object is a software container that includes state information (variables) and behaviors (methods). Objects are used to model real-world things like cars, people, bank accounts, etc. Joysticks, controllers, Motors, servos, and sensors are all typically going to be objects in robot code.

A class is a prototype or blueprint for an object from which actual object instances are created. Object and class can be used interchangeably and that is fine but there is a difference. We write a class as source code in a .java file and then use that class definition in another .java file to create an instance of the object defined by the class with the new keyword. The basic form of a class definition is:

We will discuss modifiers later, for now we use the word public. This means other classes can access this class. The keyword class is required and the name of the class followed by the class body as a statement block. Here is a simple class definition for a real world object, your dog:

We see the Dog class has state information in the variables breed, name and age. These are also called fields. We have made the fields public so we can access them directly from other code. At this point, we have not created any particular instance of a ‘dog’ object, we have just said “All Dogs will have a breed, name, and age.” The only constraint we have is that the breed and name both have to be strings, and the age has to be an integer.

We also see a method that implements a behavior of dogs. With this class you have created your own custom Data Type called Dog. So in another place in your code you might write:

The new keyword creates a new object instance of the Dog Data Type (class) and puts a reference to that instance into the variable myDog. myDog now points to a Dog object instance, which you can manipulate.

We access the components of the Dog object with the . (dot) notation. We use the myDog variable name followed by a dot and then the name of a Dog class component (field or method) we want to access. So, if we want to use the function bark(), we must state myDog.bark(), as opposed to just bark(). The method bark() is owned by the class Dog, and when writing code that is outside of the class Dog, we must access the method bark() by having a Dog object instance to call it with. With a robot motor, for instance, we would create an instance of the Motor class connecting it to an actual motor, store it in variable motorA and then write motorA.setPower(0.5) to set our motorA object instance to half power.

An most significant feature of objects is the ability to use multiple objects all created from the single class definition:

In a robot example, if we have four motors on our robot, we would create four instances of the motor class.
 
Here is more about objects, classes and using objects. Here are two videos (video1, video2) discussing objects and classes.

Note that, while not required, it is considered good programming practice to make all class fields private. This means that fields cannot be directly accessed with the dot notation. In this case, you must provide methods to set and get the values of fields. The reason is to make sure the values of fields are always under the control of the class methods and so the methods can then depend on the values being correct since no outside code can modify them directly. To follow this convention we would rewrite our Dog class like this:

Here we provide methods to give code using our class access to set and get the name and breed fields. Note that in the setName() method, we used a parameter called name. If we did nothing about this the compiler would not be able to tell the class field called name from the method parameter called name. The this. keyword allows us to tell the compiler when we want the class level field. You can think of the this. keyword as meaning "class level".

Following that idea, if we have a variable in a method with the same name as a class level field, the variable in the method "hides" the class level field. This means any use of the variable name refers to the method local variable. If we wish to do this and still need to access the class level field, we again use the this. keyword to tell the compiler we mean the class level field.

We also include a constructor method (more later) that allows us to set the dog name when we create an instance with the new keyword. We would use this new Dog class as follows:

Here are the examples on CodingGround (new). Read below before looking at the examples. Add a Cat class with field name and breed and a method called meow() and call it from the main method.

It is a Java convention to have each class is in a separate .java file with the same name as the class. However it is possible to define a class within another class, thus having more than one class in a single file. This is called an inner class. We are only introducing this idea because the new version of CodingGround does not support more than one source file in an example. So in order to have multiple classes in an example, we have to use inner classes. This is a strange limitation as practically all programming languages support breaking projects into multiple source files. The old version of CodingGround allowed multiple files but has quit working.

 

Navigation:

Overview: 
Explore Methods, what they are, how they are used and how to write them.
Overview: 
Wrap up the method unit with references to other sources of information on Java methods.
Objectives: 

View some different explorations of Java methods.

Content: 

We are going to wrap-up the unit on methods with several resources for you to view:

Here is a video about methods. This video is a good introduction to methods. However the definition of the static keyword in this video is incorrect. Please ignore the discussion of static for now as we will explore static later in this curriculum.

Here is a detailed discussion of methods. Here is another discussion (stop at "Constructors").

Navigation:

Pages