Using var As A Data Type in Programs
Overview
In this lesson, students will begin to develop an understanding of when it is appropriate to use var
and when it is not appropriate.
Learning Objectives
- 1.4.A.3 Use
var
to create variables of inferred types.
Skills
- S1.C Explain the impact design has on data storage.
- S2.A Write program code and implement algorithms.
Student Outcomes
Students will be able to:
- determine when
var
can be used instead of a data type.
Duration: 1 class period
Resources
Background
The local variable type (var
) can be used to declare variables as long as the variable is being assigned to a value, making the type unambiguous.
What is var
used for?
- We can declare a variable of type
var
when the actual type of the variable can be inferred based on what it is assigned to:
- Local variables with initializers &
- Indexes in enhanced for-loops and traditional for-loops
- While you can use
var
when we are assigning the result of a method call. You may not want to where the type of the return is ambiguous. While the compiler will understand that type, this practice will make the code less readable.
When can we NOT use var
?
We cannot use var
if the type of values being stored in the variable cannot be inferred:
- Method returns or parameters
- Constructor returns or parameters
- Variable declarations
Why use var at all?
The introduction of var
is meant to reduce the syntax when the type of a variable can be inferred.
Many other languages have something equivalent, such as: C++, C#, Scala, and Go
Java is a strongly typed language, doesn’t using var
diminish this strength? Absolutely not, since var
can only be used when the type of the variable can be inferred.
Local Variable var
Examples
The following are some examples of use var
for declaring and initializing local variables.
var price = 7.99; //this is the same as double price = 7.99;
var initial = 'L'; //this is the same as char initial = 'L';
var score = 100; //this is the same as int score = 100;
var isRaining = true; //this is the same as boolean isRaining = 100;
Consider the following class:
class Airplane {
public Airplane () {
println("zoom zoom!");
}
}
We can use var
to when declaring a variable for an Airplane
object.
var ourFlight = new Airplane(); //this is the same as Airplane ourFlight = new Airplane();
Another example using ArrayList
is as follows:
var nameList = new ArrayList<String>(); //this is the same as ArrayList<String> nameList = new ArrayList<String>();
You can also use var
with for
loops. In the following example var
is being used to declare name. Since we know that nameList
is an ArrayList
of String
objects, we can infer that name
is of type String
.
var nameList = new ArrayList<String>();
for (var name : nameList) {
println(name);
}
Another example using a for
loop is a follows:
for(var round = 1; round <= 10; round++) {
// call methods to simulate a round of a game.
}
Not Recommended Uses of var
It is not recommended to use var
in some cases. While the compiler can infer the type, the someone reading the code cannot infer the type making the code less readable. For example, it isn't recommended to use var
to store the value returned from a method. For example:
var brady = new Dog();
var sound = brady.bark();
In this case, it is unclear what is being returned by the method bark
. It could be:
- A
String
containing the word bark
- A
File
containing the sound of a dog barking
- A
boolean
value that represents that the dog is barking
While the compiler knows the return type, the code is less readable without knowing the return value of bark()
.
Improper Uses of var
If a variable is being declared and not assigned to a value, var
cannot be used, such as:
var grade;
For variables that reference an object, you have to assign the variable to a newly created object. You cannot assign the variable to null
, such as:
var plane = null;
We cannot use var
for the return type of a method or the parameters, such as:
public var methodName(var param1) {
//do soemthing
}
We cannot use var
for constructor parameters either, such as:
public class Airplane{
public Airplane (var param1) {
//do something
}
}
We cannot use var
for the instance variables either, such as:
public class Airplane{
private var planeName;
public Airplane (String name) {
planeName = name;
}
}
Using var Reminders
- The use of var is not required.
- Using var can only be done when the type can be inferred. It cannot be used every where. It can be used in the following places:
- local variables with initializers
- for loops: enhanced-for and traditional
Using var
on AP CSA Free Response Questions
How does this look on the exam?
Now that we have taken a chance to understand var
outside of the AP CSA exam. Let's look at an example of how students might use this on the AP Computer Science A (AP CSA) exam.
The following are examples of how students could use var on the AP CSA Free Response Exam. You can find all of the questions here
Free Response Question 1 - Bird Feeder
This question involved a simulation of a bird feeder and requires students to do the following:
- generate random values
- use if statement
- use loops
Part A - Example Canonical Solution
public void simulateOneDay (int numBirds) {
boolean bearPresent = false;
double bear = Math.random() * 100;
if (bear <= 5) {
bearPresent = !bearPresent;
}
int birdConsumed = ((int) (Math.random() * 41) + 10) * numBirds;
if (bearPresent)
{
currentFood = 0;
}
else{
if (birdConsumed >= currentFood) {
currentFood = 0;
else {
currentFood = currentFood - birdConsumed;
}
}
There are three variable declarations in the sample solution above:
bearPresent
– is assigned to the Boolean false
. The type is unambiguous with the assignment.
bear
– is assigned to a double
from Math.random()
. You could use var
, but it can be ambiguous to use with a method return.
birdConsumed
– even though there is a method call, the typecast to an int
makes the type clear that the value being assigned is an int
.
A sample solution using var
is as follows:
public void simulateOneDay (int numBirds) {
var bearPresent = false;
double bear = Math.random() * 100;
if (bear <= 5) {
bearPresent = !bearPresent;
}
var birdConsumed = ((int) (Math.random() * 41) + 10) * numBirds;
if (bearPresent)
{
currentFood = 0;
}
else{
if (birdConsumed >= currentFood) {
currentFood = 0;
else {
currentFood = currentFood - birdConsumed;
}
}
Part B - Example Canonical Solution
public int simulateManyDays(int numBirds, int numDays) {
int count = 1;
for(int days = 1; days <= numDays; days++) {
if(currentFood == 0) {
return days;
}
simulateOneDay(numBirds);
}
return numDays;
}
There are two variables declared in the sample solution above:
count
- Since the variable is being assigned to 1
, it is unambiguous and is a good place to use var
.
days
- The for loop counter days
can be declared using var
.
This sample solution using var is as follows:
public int simulateManyDays(int numBirds, int numDays) {
var count = 1;
for(var days = 1; days <= numDays; days++) {
if(currentFood == 0) {
return days;
}
simulateOneDay(numBirds);
}
return numDays;
}
Free Response Question 2 - Scoreboard
In this free response question, students are asked to write a class for a scoreboard with two teams. Students will need to:
- declare instance variables
- write constructors
- write methods
- use if statements
The following is a sample solution:
public class Scoreboard {
private String team1;
private String team2;
private String activeTeam;
private int team1Score;
private int team2Score;
public Scoreboard(String t1, String t2) {
team1 = t1;
team2 = t2;
activeTeam = team1;
team1Score = 0;
team2Score = 0;
}
public void recordPlay(int points) {
if (points == 0) {
activeTeam = (team1.equals(activeTeam)) ? team2 : team1;
} else {
if (team1.equals(activeTeam)) {
team1Score += points;
} else {
team2Score += points;
}
}
}
public String getScore() {
String retVal = team1Score + " – " + team2Score + " – " ;
retVal += (team1.equals(activeTeam)) ? team1 : team2;
return retVal;
}
}
In this solution, we have many data types where students might be tempted to use var
. However, you cannot use var
for the following:
- instance variables
- constructor or method parameters
- method return types
If a student were to use var
in these places, they will likely lose points.
There is only one place in the solution above where a student could use var
if they wanted to do so. In the getScore
method the String
variable, retVal
, is declared and assigned the concatenation of team scores and a string hyphen. Since the concatenation of strings with int
values creates a String
, it is unambiguous what type we are using and var
can be used appropriately.
A sample solution using var is as follows:
public class Scoreboard {
private String team1;
private String team2;
private String activeTeam;
private int team1Score;
private int team2Score;
public Scoreboard(String t1, String t2) {
team1 = t1;
team2 = t2;
activeTeam = team1;
team1Score = 0;
team2Score = 0;
}
public void recordPlay(int points) {
if (points == 0) {
activeTeam = (team1.equals(activeTeam)) ? team2 : team1;
} else {
if (team1.equals(activeTeam)) {
team1Score += points;
} else {
team2Score += points;
}
}
}
public String getScore() {
var retVal = team1Score + " – " + team2Score + " – " ;
retVal += (team1.equals(activeTeam)) ? team1 : team2;
return retVal;
}
}
NOTE: In this solution we have used the ternary conditional operator. This operator is not a part of the AP Java Subset. You do not need to teach this operator.
Learn more on the Ternary Conditional Operator.
Free Response Question 3 - WordList
In this free response students will need to:
- loop over a list
- access adjacent elements of a list
- use string methods
- add values to a list
- create a new list
Part A - Sample Canonical Solution
In part A of this free response question, students are asked to determine if the previous word is a substring of the next word.
public boolean isWordChain() {
for (int index = 0; index < wordlist.size() – 1; index++) {
String nextWord = wordlist.get(index + 1);
String currentWord = wordlist.get(index);
if(nextWord.indexOf(previous) == -1) {
return false;
}
}
return true;
}
In this solution, there are three variables being declared:
index
- the for loop counter index
can be declared with var
nextWord
and currentWord
- students could use var
to declare these variables, but this would be considered less readable, since the value these are being assigned comes from a method call. In this case, we are using common method calls and will likely know that wordlist
stores String
values, but it is still considered less than desirable to use it in these two cases.
A sample solution using var
is as follows:
public boolean isWordChain() {
for (var index = 0; index < wordlist.size() – 1; index++) {
String nextWord = wordlist.get(index + 1);
String currentWord = wordlist.get(index);
if(nextWord.indexOf(previous) == -1) {
return false;
}
}
return true;
}
Part B - Sample Canonical Solution
In part B, students need to make a list of all word that have the target word at the beginning, but with the beginning of the word is removed.
public ArrayList<String> createList(String target) {
ArrayList<String> retList = new ArrayList<String> ();
for (String word : wordList) {
if (word.indexOf(target) == 0) {
retList.add(word.substring(target.length()));
}
}
return retList;
}
In this solution, var
could be used in two places:
retList
- a new ArrayList
that is able to store string values
word
- used in the enhanced-for loop to store the values in wordList
, which are strings
A sample solution using var
is as follows:
public ArrayList<String> createList(String target) {
var retList = new ArrayList<String> ();
for (var word : wordList) {
if (word.indexOf(target) == 0) {
retList.add(word.substring(target.length()));
}
}
return retList;
}
Free Response Question 4 - GridPath
In this free response students will need to:
- access elements in a 2D array
- use a provided class
- use conditionals and loops
Part A - Sample Canonical Solution
In this part, students need to return the smaller of two values, either below or to the right if they exist.
public Location getNextLoc(int row, int col) {
int numRows = grid.length;
int numCols = grid[0].length;
if (row + 1 == numRows)
return new Location(row, col + 1);
if (col + 1 == numCols)
return new Location(row + 1, col);
int below = grid[row + 1][col];
int right = grid[row][col + 1];
return (below < right) ? new Location(row + 1, col) : new Location(row, col + 1);
}
In this solution, we have declared four variables:
numRows
and numCols
- The value assigned to numRows
and numCols
is from the constant length. Since this is really common, it is most likely readable to use var
in these cases. However, if there is any doubt about the readability, you will want to use the type and be clear.
below
and right
- The values assigned to below
and right
are what is being stored in grid
and is not ambiguous.
A sample solution with var
is as follows:
public Location getNextLoc(int row, int col) {
var numRows = grid.length;
var numCols = grid[0].length;
if (row + 1 == numRows)
return new Location(row, col + 1);
if (col + 1 == numCols)
return new Location(row + 1, col);
var below = grid[row + 1][col];
var right = grid[row][col + 1];
return (below < right) ? new Location(row + 1, col) : new Location(row, col + 1);
}
NOTE: In this solution we have used the ternary conditional operator. This operator is not a part of the AP Java Subset. You do not need to teach this operator.
Learn more on the Ternary Conditional Operator
Part B - Sample Canonical Solution
In this solution, students are summing the values along a path using the return value from getNextLocation
.
public int sumPath(int row, int col) {
int total = 0;
while (row < grid.length – 1 || col < grid[0].length – 1) {
total += grid[row][col];
Location next = getNextLocation(row, col);
row = next.getRow();
col = next.getCol();
}
return total;
}
In this solution, we have two variables that are being declared and assigned values:
total
- which is unambiguous being assigned to 0
.
next
- assigned a returned type from a method call. This method is a local method and would be easy to find, however, it is still considered less readable to use var
in this case.
A sample solution with var
is as follows:
public int sumPath(int row, int col) {
var total = 0;
while (row < grid.length – 1 || col < grid[0].length – 1) {
total += grid[row][col];
Location next = getNextLocation(row, col);
row = next.getRow();
col = next.getCol();
}
return total;
}
Final Thoughts on Using var with AP CSA
Use of var and the AP CSA Free Response Questions
- Using
var
is OUTSIDE the AP CSA Java Subset
- Students can write correct solutions using
var
- Using
var
can be used in any FRQ. Students need to be careful using it with FRQ 2, since they cannot use it with instance variables, parameters, and return types.
Scoring and Teaching
- Student solutions that use correct Java syntax can earn full credit for their solution
- Questions are written with an in AP Java subset solution in mind
- Students should be encouraged to write solutions within the AP Java Subset
- Students could lose points if they use
var
and do not assign the variable to a value that is not unambiguous.
Activities
Activity 1: Updating a Lab
Incorporate var
into a prior program.
- Have students revisit a prior program and include
var
in all places that are unambiguous.
- Identify places in the program where the use of
var
cannot be used.
- Identify places in the program where the use of
var
can be used, but shouldn't be used.