This question already has answers here:
How to write a Unit Test?
(5 answers)
Closed 4 years ago.
How would I test this public static method using Junit?
I want to test the ResetFactory static method using Junit 4 but I am not sure how to. Any tips? Any help would be appreciated. I have tested the Ticketing constructor and it works perfectly. I had to write the question in a little strange way since it wanted more words for the question.
/**
* Resets the factory.
*/
public static void resetFactory() {
time = 0;
randomNumber = new Random(10);
}
public class Ticketing {
/** Absolute time for passengers created for the simulation. The time starts at zero
* and increases by up to MAX_PASSENGER_GENERATION_DELAY for each passenger created. */
private static int time = 0;
/** Random object with seed that allows for testing of simulation */
private static Random randomNumber = new Random(10);
/** Maximum delay between creation of passengers */
private static final double MAX_GENERATION_DELAY = 15;
/** Percentage of time a Fast Track passenger should be created */
private static double pctExpedite = .50; // initialize with default value
/** Percentage of time a trusted traveler/TSA PreCheck passenger should be created */
private static double pctTrust = .05; // initialize with default value
/**
* Set the proportions of fast track, trusted traveler, and (by inference) ordinary passengers
* that should be generated. Proportion of ordinary passengers is 1 - (pctFast + pctTrusted).
* #param pctTrusted - proportion of passengers that are TrustedTravelers
* #param pctFast - proportion of passengers that are FastTrackPassengers
*/
public static void setDistribution(int pctTrusted, int pctFast) {
pctExpedite = pctFast * .01;
pctTrust = pctTrusted * .01;
}
/**
* Generate a new passenger as described in the class comments.
* #param log - where the passenger will log his/her data
* #return the passenger created
*/
public static Passenger generatePassenger(Reporter log) {
// Update the overall time with up to the floor of MAX_PASSENGER_GENERATION_DELAY seconds.
// The value is cast to an int, which is the floor of the original double.
time += (int)(1 + randomNumber.nextDouble() * MAX_GENERATION_DELAY);
// Random number x determines which type of passenger will be created. The generated number
// is between 0 and 1.0. By splitting across the range of numbers generated, you can simulate
// creation of different passengers of appropriate types.
double x = randomNumber.nextDouble();
if (x < pctExpedite) { // Create a Fast Track passenger
int ftMin = FastTrackPassenger.MIN_PROCESS_TIME;
int ftMax = FastTrackPassenger.MAX_EXPECTED_PROCESS_TIME;
// If the generated number is less than pctExpedite, create a passenger with expedited security
// with a process time between FastTrack.MIN_PROCESS_TIME and FastTrack.MAX_PROCESS_TIME.
return new FastTrackPassenger(time, // FastTrackPassenger.MIN_PROCESS_TIME +
(int) (randomNumber.nextDouble() * (ftMax - ftMin)) + ftMin,
log);
}
else if (x < pctExpedite + pctTrust) { // Create a Trusted Traveler
int tsaMax = TrustedTraveler.MAX_EXPECTED_PROCESS_TIME;
int tsaMin = TrustedTraveler.MIN_PROCESS_TIME;
// Else if the generated number is less than pctExpedite + pcTrust, create a trusted
// traveler with a process time between TrustedTraveler.MIN_PROCESS TIME and TrustedTraveler.MAX_PROCESS_TIME.
return new TrustedTraveler(time, // TrustedTraveler.MIN_PROCESS_TIME +
(int) (randomNumber.nextDouble() * (tsaMax - tsaMin)) + tsaMin,
log);
}
else { // Create an ordinary passenger
int ordMax = OrdinaryPassenger.MAX_EXPECTED_PROCESS_TIME;
int ordMin = OrdinaryPassenger.MIN_PROCESS_TIME;
// Otherwise, create an ordinary passenger with a process time between OrdinaryPassenger.MIN_PROCESS TIME
// and OrdinaryPassenger.MAX_PROCESS_TIME
return new OrdinaryPassenger(time, // OrdinaryPassenger.MIN_PROCESS_TIME +
(int) (randomNumber.nextDouble() * (ordMax - ordMin)) + ordMin,
log);
}
}
/**
* Resets the factory.
*/
public static void resetFactory() {
time = 0;
randomNumber = new Random(10);
}
}
In order to test a static method, you need a static context on Junit.
JUnit includes these useful methods.
#BeforeClass
public static void beforeClass() {}
#AfterClass
public static void afterClass() {}
Trying something like this,
import your.own.project.package;
import static org.junit.Assert.assertEquals;
#BeforeClass
public static void beforeClass() {
Ticketing.resetFactory()
}
Your static method would be executed before or after the whole test. Keep in mind that likely this isn't the desired behavior. You can also try coding a wrapper class as this answer shows. Are static methods offered by wrapper classes often used?
bests.
Related
I have a ParkingLot class with a getEmptySpaces() method that applies to ParkingLot objects, which are arrays of Car objects.
I want to call lot.getEmptySpaces(), but my IDE, Netbeans, throws a fit if I give it an array rather than a specific item. lot[1].getEmptySpaces() compiles fine, but crashes when it runs, as expected, since it's supposed to receive an array, not a null.
How do I call a method on an array defined by the same class?
// Main
ParkingLot[] lot = new ParkingLot[10];
lot[1].getEmptySpaces(); // compiles but doesn't run
lot.getEmptySpaces(); // what i want to run but doesn't
// Car class
public class Car {
private String color;
private String licensePlate; // lp #
public Car(String color, String licensePlate) {
this.color = color;
this.licensePlate = licensePlate;
}
/**
* #return the color
*/
public String getColor() {
return color;
}
/**
* #param color the color to set
*/
public void setColor(String color) {
this.color = color;
}
/**
* #return the licensePlate
*/
public String getLicensePlate() {
return licensePlate;
}
/**
* #param licensePlate the licensePlate to set
*/
public void setLicensePlate(String licensePlate) {
this.licensePlate = licensePlate;
}
#Override
public String toString() {
return "Car{" + "color=" + color + ", licensePlate=" + licensePlate + '}';
}
}
// ParkingLot class
public class ParkingLot {
private Car[] spaces; // lp=000000 color=none will represent an empty space
private int currentIndex;
/**
* Creates a parkingLot object
*
* #param size how many spaces are needed in the parking lot
*/
public ParkingLot(int size) {
// Array Example: String[] arr = new String[20];
this.spaces = new Car[size];
this.currentIndex = 0;
}
public int getEmptySpaces(){
int emptySpaces = 0;
for(int i = 0; i < spaces.length; i++){
if (spaces[i] == null){
emptySpaces++;
}
}
return emptySpaces;
}
/**
* Adds a car to the parking lot
*
* #param car the car to be added to the parking lot
*/
public void addCar(Car car){
spaces[currentIndex] = car;
currentIndex++;
}
}
ParkingLot[] lot = new ParkingLot[10];
It feels like you imagine this creates a single parking lot with 10 spaces.
It doesn't.
It creates a plot of land upon which up to 10 parking lots can be placed, though none are there yet (a ParkingLot is an object, if you want one to exist, somebody, somewhere, must invoke new ParkingLot(), or no parking lot objects exist).
lot[1].getEmptySpaces()
This goes to the second lot (java is 0-indexed, so, lot[1] is the second lot), and asks it: Oi, how much free space is there? Given that you're yelling this at an empty space where a parking lot can be, but isn't, you get a NullPointerException.
lot.getEmptySpaces();
This makes no sense at all. How can you ask 10 parking lots at once? Even worse, how can you ask a bit of terrain reserved for 10 parking lots, but where no lots exist right now?
Relevant:
for (int i = 0; i <lots.size; i++) lots[i] = new ParkingLot();
The problem I was having was that I created an array of ParkingLot objects. I only needed one ParkingLot, not 10.
My code should have been:
ParkingLot lot = new ParkingLot[10];
Instead of:
ParkingLot[] lot = new ParkingLot[10];
It was just a typo, like usual.
I'm attempting to create a method called "runExperiments()
the first step in the loop is to decrement a variable called "powerLevel" by a random number between 1 and 3 which is I have created a second method for which works.
the next step which is where I am having problem is if the "powerLevel" can be reduced then I need a message containing the experiment number (starting at 1) should displayed, if not then a different message should be displayed and the remaining experiments should not be attempted.
Then finally when all expierements have finished I need to display "Experiment run stopped" But I know how to do this section.
I have posted all the code below. The method is at the bottom. I have made a first attempt but I cannot seem to figure out the part in the bold. Any help or guidance would be fantastic. I'm not sure if I have used the correct type of loop either so that may be wrong as well.
public class SpaceRocket
{
private String name;
private int maxPowerLevel;
private int numberOfExperiments;
private int powerLevel;
private int decreasePowerLevel;
/**
* returns maxPowerLevel
*/
public int getMaxPowerLevel()
{
return this.maxPowerLevel;
}
/**
* returns numberOfExperiments
*/
public int getNumberofExperiments()
{
return this.numberOfExperiments;
}
/**
* returns powerLevel
*/
public int getPowerLevel()
{
return this.powerLevel;
}
/**
*
* Causes execution to pause by time number of milliseconds
*
*/
public void delay(int time)
{
try
{
Thread.sleep(time);
}
catch (Exception e)
{
System.out.println(e);
}
}
/**
*
* return a random integer between 1 and 3 inclusive
*/
public int randomInteger()
{
java.util.Random r = new java.util.Random();
return r.nextInt(3) + 1;
}
public SpaceRocket(String aName, int aNumberOfExperiments)
{
this.name = aName;
this.numberOfExperiments = aNumberOfExperiments;
this.powerLevel = 0;
this.maxPowerLevel = 15;
}
public boolean decrementPower(int adecreasePowerLevel)
{
this.decreasePowerLevel = adecreasePowerLevel;
if(decreasePowerLevel > this.powerLevel)
{
this.powerLevel = 0;
return true;
}
else
{
this.powerLevel =(this.powerLevel - this.decreasePowerLevel);
return false;
}
}
public runExperiments()
{
for(this.powerLevel =(this.powerLevel - randomIntegar())
{
if(this.powerLevel
}
}
If I understand your question correctly, every time the loop runs, you want to decrease "powerlevel" by a random value, then display a message depending on whether powerlevel can be reduced.
Here are two approaches.
1) use an if statement in your for loop
for (conditions){
if(powerlevel cannot be decremented){
//display a messsage
break;
}
// display a message
}
conditions could be iterating through all the experiments
2) use a while loop which checks whether powerlevel can be reduced in every loop
while(powerlevel can be decreased){
//display a message containing the experiment number (starting at 1)
}
//display a different message
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I just accepted that all my programs I made have to start with this. Then I was looking at a example #2 here regarding generation of a random number.
import java.util.Random;
/** Generate random integers in a certain range. */
public final class RandomRange {
public static final void main(String... aArgs){
log("Generating random integers in the range 1..10.");
int START = 1;
int END = 10;
Random random = new Random();
for (int idx = 1; idx <= 10; ++idx){
showRandomInteger(START, END, random);
}
log("Done.");
}
private static void showRandomInteger(int aStart, int aEnd, Random aRandom){
if (aStart > aEnd) {
throw new IllegalArgumentException("Start cannot exceed End.");
}
//get the range, casting to long to avoid overflow problems
long range = (long)aEnd - (long)aStart + 1;
// compute a fraction of the range, 0 <= frac < range
long fraction = (long)(range * aRandom.nextDouble());
int randomNumber = (int)(fraction + aStart);
log("Generated : " + randomNumber);
}
private static void log(String aMessage){
System.out.println(aMessage);
}
}
I noticed that this had a public static void and a private static void. Why not just combine the code into one thing under public static void? More importantly, what do these mean? I did research and saw the word "class" pop up often. What is a class? I hope my question meets the guidelines, this is my first time posting here. Thanks.
I will assume you asked here because you wanted a concise answer that gives you some intuition, rather than a deep dive into OOP which you can pull from the tutorial.
A class is a template from which objects are built. However, until you understand OOP, the class is just a necessary wrapper around the imperative code you are writing because Java requires all code to live inside a class.
public means the method is publicly accessible. Methods which are defined in classes other than this one can access it. private has the opposite meaning.
static means that this is a class-level function that is not tied to any particular instance of the class.
void means the method returns nothing.
You can certainly put all the code under a single method, but that carries at least the following problems.
Code is harder to read because the intent of the code is hidden by the details of the implementation.
Code is harder to reuse because you have to copy and paste whenever you need the same functionality in multiple places.
The following is not fully correct, it is very simplified:
Mostly one class equals one file. Even so they can access each other (if in the same project/folder) Here are 3 example classes:
Class withe the main method:
package ooexample;
public class OOExample {
public static void main(String[] args) {
int min = 2;
int max = 101;
// use of static method
int randomNumberA = MyMath.generateRandomNumber(min, max);
// use of non static method
RandomNumberGenerator generator = new RandomNumberGenerator();
int randomNumberB = generator.randomNumber(min, max);
/**
* does not work, method is private, can not be accessed from an outise class
* only RandomNumberGenerator can access it
*/
// generator.printSomeNumber(123);
}
}
Class with a static method. The method can be access by writing classname.nameOfStaticMethod(...) see main method.
package ooexample;
public class MyMath {
public static int generateRandomNumber(int min, int max) {
return min + (int) (Math.random() * ((max - min) + 1));
}
}
Class without static method. You have to create the class in the main method, using the new operator and assign the created class to a variable. Then you can use the variable to access PUBLIC methods of that class. You can not access private methods anywhere else but inside of the class itself. See main method.
package ooexample;
public class RandomNumberGenerator {
public RandomNumberGenerator() {
}
public int randomNumber(int min, int max) {
int randomNumber = min + (int) (Math.random() * ((max - min) + 1));
printSomeNumber(randomNumber);
return randomNumber;
}
private void printSomeNumber(int number) {
System.out.println(number);
}
}
I am working on a lab for school, the purpose is to go through a life insurance policy, and run tests to make sure my constructors are working properly. I have the regular constructors down, but I am confused about what is really needed in line 83. When I compile and submit my assignment, I get no information, except a pink highlight in that area. I tried creating a new policy object inserting...
WholeLifePolicy WholeLifePolicy2 = new WholeLifePolicy;
this is not what it wants.
}
/**
* Constructor for objects of class WholeLifePolicy.
* This constructor creates an exact copy of a
* WholeLifePolicy object.
*
* #param inPolicyObject WholeLifePolicy object.
*
*/
public WholeLifePolicy(WholeLifePolicy inPolicyObject)
{
this.setPolicyNum(inPolicyObject.getPolicyNum());
**// your code here, complete the constructor**
}
I also tried initializing instance variable from the WholeLifePolicy class, but I knew this wouldn't work since the copy takes on these parameters anyway.
I really just have no idea what to do. I have searched online and here, I keep getting information on clones, and dark copies. That is not what I am suppose to do. This is only the 6th week of my first programming class. I also contacted my teacher, but have not heard a reply yet.
public class WholeLifePolicy
{
// instance variables
private String policyNum;
private double faceValue;
private int policyYrs;
private String beneficiary;
// your code here - code the remaining 3 instance fields
// constants
/**
* surrender rate.
*/
public static final double SURRENDER_RATE = .65;
/**
* ADMINFEE.
*/
public static final double ADMINFEE = .005;
// constructors and methods
/**
* Constructor for objects of class WholeLifePolicy.
* This is the default constructor.
*
* Default values are:
* face value = 0.0
* policy years = 0
* policy number WLP9999999
* beneficiary Unknown
*
*/
public WholeLifePolicy()
{
this.setPolicyNum("WLP9999999");
this.setFaceValue(0.0);
this.setPolicyYrs(0);
this.setBeneficiary("Unknown");
}
/**
* Constructor for objects of class WholeLifePolicy.
* A policy number will be auto-generated.
*
* #param inPolicyNum Number of the policy
* #param inFaceValue Face Value of policy.
* #param inPolicyYrs Length of policy in years.
* #param inBeneficiary name of the beneficiary
*
*/
public WholeLifePolicy(String inPolicyNum, double inFaceValue,
int inPolicyYrs, String inBeneficiary)
{
// Initialize instance variables
// Using values passed in as parameters
this.policyNum = inPolicyNum;
this.faceValue = inFaceValue;
this.policyYrs = inPolicyYrs;
this.beneficiary = inBeneficiary;
*}
/
* Constructor for objects of class WholeLifePolicy.
* This constructor creates an exact copy of a
* WholeLifePolicy object.
*
* #param inPolicyObject WholeLifePolicy object.
*
*/
public WholeLifePolicy(WholeLifePolicy inPolicyObject)
{
this.setPolicyNum(inPolicyObject.getPolicyNum());
// your code here, complete the constructor
}***
/**
* Set the Policy Face Value.
*
* #param inFaceValue Face Value of policy.
*
*/
public void setFaceValue(double inFaceValue)
{
this.faceValue = inFaceValue;
}
/**
* Get the Policy Face Value.
*
* #return double Face Value of policy.
*
*/
public double getFaceValue()
{
return this.faceValue;
}
/**
* Set the Policy Years.
*
* #param inPolicyYrs Length of policy in years.
*
*/
public void setPolicyYrs(int inPolicyYrs)
{
this.policyYrs = inPolicyYrs;
}
/**
* Get the Policy Years.
*
* #return int Length of policy in years.
*
*/
public int getPolicyYrs()
{
return this.policyYrs;
}
/**
* Set the Policy Number. Use to override the default
* policy number or for copy object processing.
*
* #param inPolicyNum Policy Number.
*
*/
public void setPolicyNum(String inPolicyNum)
{
this.policyNum = inPolicyNum;
}
/**
* Get the Policy Number.
*
* #return String Policy Number.
*
*/
public String getPolicyNum()
{
// your code here, replace the following statement
return this.policyNum;
}
/**
* Set the beneficiary. Use to override the default
* beneficiary or for copy object processing.
*
* #param inBeneficiary Beneficiary to set up.
*
*/
public void setBeneficiary(String inBeneficiary)
{
this.beneficiary = inBeneficiary;
}
/**
* Get the Beneficiary.
*
* #return String Beneficiary.
*
*/
public String getBeneficiary()
{
// your code here, replace the following statement
return this.beneficiary;
}
/**
* Calculate surrender value.
* Surrender value is calculated as:
* (surrender rate * face value) *
* (years held / policy years) - amount borrowed -
* (face value * administrative fee)
*
* #param inYrsHeld Length in years policy held to date.
* #param inBorAmt Amount borrowed against policy if any.
* #return double Policy surrender value.
*
*/
public double surrenderVal(double inYrsHeld, double inBorAmt)
{
// Termination value is the surrender rate percentage of the face
// value as a proportion of the years held to policy years less any
// amount borrowed on the policy less a ADMINFEE on the
// face value.
// your code here, compute the surrender value and replace the
// following line
return (SURRENDER_RATE * faceValue) * (inYrsHeld) / (policyYrs)
- inBorAmt - (faceValue * ADMINFEE);
}
/**
* Return a string representation of the WholeLifePolicy.
*
* #return String output string.
*
* <pre>
* Produce output in the following format:
*
* Policy Information:
* Policy #: WLP1000000
* Policy Years: 20
* Face Value: 50000.0
* Beneficiary: John Doe
*
* </pre>
*/
public String toString()
{
String output = "Policy Information:\n";
output = output + "Policy #: " + this.getPolicyNum() + "\n";
// your code here, finish the output string
return output;
}
}
HERE IS THE TEST CLASS, JUST IN CASE.
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* The test class WholeLifePolicyTest.
*
* #author Tina & edited by Jeremy
* #version Fall 2015
*/
public class WholeLifePolicyTest
{
/**
* Default constructor for test class WholeLifePolicyTest.
*/
public WholeLifePolicyTest()
{
// not used
}
/**
* Sets up the test fixture.
*
* Called before every test case method.
*/
#Before
public void setUp()
{
// not used
}
/**
* Tears down the test fixture.
*
* Called after every test case method.
*/
#After
public void tearDown()
{
// not used
}
/**
* Test empty (default) constructor #1.
*/
#Test
public void testConstructor1()
{
WholeLifePolicy policy = new WholeLifePolicy();
// verify an object reference was created
assertNotNull(policy);
// verify policy number is not null
assertEquals("WLP9999999", policy.getPolicyNum());
// verify face value set to default values
assertEquals(0.0, policy.getFaceValue(), .001);
// verify policy years set to default values
assertEquals(0, policy.getPolicyYrs());
// verify beneficiary is Unknown
assertEquals("Unknown", policy.getBeneficiary());
}
/**
* Test explicit constructor #2 (policy#, face value, years, name).
*/
#Test
public void testConstructor2()
{
// we test passing in values greater than zero only
String pnum = "WLP1234567";
double value = 50000.0;
int years = 20;
String name = "Paul Young";
WholeLifePolicy policy = new WholeLifePolicy(pnum, value, years, name);
// your code here, verify the object exists and the instance
// fields contain the expected values
assertEquals("WLP1234567", policy.getPolicyNum());
assertEquals(50000.0, policy.getFaceValue(), .001);
assertEquals(20, policy.getPolicyYrs());
assertEquals("Paul Young", policy.getBeneficiary());
}
/**
* Test explicit constructor #3 (duplicate object).
*/
#Test
public void testConstructor3()
{
// we test passing in values greater than zero only
String pnum = "WLP1234567";
double value = 50000.0;
int years = 20;
String name = "Paul Young";
WholeLifePolicy policy1 = new WholeLifePolicy(pnum, value, years, name);
// your code here, verify the object exists and the instance
// fields contain the expected values
assertEquals("WLP1234567", policy1.getPolicyNum());
assertEquals(50000.0, policy1.getFaceValue(), .001);
assertEquals(20, policy1.getPolicyYrs());
assertEquals("Paul Young", policy1.getBeneficiary());
}
/**
* Test the setGetFaceValue method.
*/
#Test
public void testSetGetFaceValue()
{
// test passing in values greater than zero only
double value = 75000.0;
WholeLifePolicy policy = new WholeLifePolicy();
policy.setFaceValue(value);
assertEquals(value, policy.getFaceValue(), .0001);
}
/**
* Test the setGetPolicyYrs method.
*/
#Test
public void testSetGetPolicyYrs()
{
// your code goes here, test the set and get methods for the
// policy years methods
int years = 25;
WholeLifePolicy policy = new WholeLifePolicy();
policy.setPolicyYrs(years);
assertEquals(years, policy.getPolicyYrs());
}
/**
* Test the SetGetPolicyNum method.
*/
#Test
public void testSetGetPolicyNum()
{
// your code goes here, test the set and get methods for the
// policy number methods
String policyNumber = "WLP7654321";
WholeLifePolicy policy = new WholeLifePolicy();
policy.setPolicyNum(policyNumber);
assertEquals(policyNumber, policy.getPolicyNum());
}
/**
* Test the SetGetBeneficiary method.
*/
#Test
public void testSetGetBeneficiary()
{
// your code goes here, test the set and get methods for the
// beneficiary methods
String benefactor = "Beetlejuice! Beetlejuice!";
WholeLifePolicy policy = new WholeLifePolicy();
policy.setBeneficiary(benefactor);
assertEquals(benefactor, policy.getBeneficiary());
}
/**
* Test the surrenderVal method.
*/
#Test
public void testSurrenderVal()
{
// we test passing in values greater than zero only
String num = "WLP1234567";
double value = 50000.0;
int years = 20;
String name = "Elton John";
double yearsHeld = 15.5;
double amtBorrowed = 10000.00;
WholeLifePolicy policy = new WholeLifePolicy(num, value, years, name);
double surVal = policy.surrenderVal(yearsHeld, amtBorrowed);
// your code here, test to make sure the returned surrender value
// is what was expected
assertEquals(surVal, 14937.5, .001);
//your code here, test to make sure the returned surrender value
// is what is expected if the borrowed amount is 0
double surVal2 = policy.surrenderVal(yearsHeld, 0);
assertEquals(surVal2, 24937.5, .001);
}
/**
* Test the toString method.
*/
#Test
public void testToString()
{
String num = "WLP1234567";
double value = 50000.0;
int years = 20;
String name = "Katie Perry";
WholeLifePolicy policy = new WholeLifePolicy(num, value, years, name);
String text = policy.toString();
assertTrue(text.contains("Policy Information:"));
assertTrue(text.contains("Policy #:"));
assertTrue(text.contains(num));
// your code here, finish the testing of the toString() method
// checking for both the headings and face value, policy years
}
}
Complete the constructor properly here
public WholeLifePolicy(WholeLifePolicy inPolicyObject)
{
//this.setPolicyNum(inPolicyObject.getPolicyNum());
/* **your code here, complete the constructor** */
this.policyNum = inPolicyObject.policyNum;
this.faceValue = inPolicyObject.faceValue;
this.policyYrs = inPolicyObject.policyYrs;
this.beneficiary = inPolicyObject.beneficiary;
}
And somewhere else in your code,
WholeLifePolicy inPolicyObject = new WholeLifePolicy(policyNum,faceValue,policyYrs,benificiary);
WholeLifePolicy WholeLifePolicy2 = new WholeLifePolicy(inPolicyObject);
If you want to keep exact copy in other object, just remove setter methods of each attributes. Only constructor will set the attributes.
I've read all of the cries for "don't use static" and I understand that it reduces OOP and screws up unit tests and can break code when multi-threading. However, I'm attempting none of those.
I'm building a Java singleton utility that contains a public static number generator for issuing ID's - numbers which cannot be duplicated. I chose singleton so it can keep track of the numbers issued throughout the life of the program w/o having to reconstruct a million and having to worry about someone not de-referencing multiple instances. The initialization works, though it doesn't ever increment beyond its first invocation.
I've tried it this way:
public class SClass {
public static final SClass SINGLETON = getInstance();
...
public static final int GEN_ID = genID();
private static int base = 999999;
...
...
private static int genID() {
SClass.SINGLETON.base += 1;
return base
}
}
and I've tried it this way:
public class SClass {
public static final SClass SINGLETON = getInstance();
...
public static int GEN_ID = genID();
private int base;
...
private SClass () {
...
this.base = 999999;
...
}
...
...
private int genID() {
this.base += 1;
return base;
}
}
Yes, I've tried it with 'final' removed from everything...
In each implementation I invoke either strictly statically or I use an instance (SClass s = SClass.SINGLETON; s.Gen_ID) with both the static and object implementations described abaove. I only get "1000000" with both any initial and any consecutive invocations (of either methodology). Would someone be willing to explain what's going on here?
I'm not asking whether or not I should implement static (there's tons of pages with that already) - I'm only asking how to make this work, simply. Though I'm open to more elegant solutions.. Thanks in advance!
You could try this
class SClass {
static final AtomicInteger COUNTER = new AtomicInteger();
final int id = 1000000 + COUNTER.getAndIncrement();
}
No need to use synchronized as AtomicInteger is thread safe.
try this
public class IdGenerator {
public static IdGenerator generator = new IdGenerator();
private IdGenerator(){}
private static int currentID=0;
private int getNextID(){
synchronized (this) {
currentID=currentID+1;
}
return currentID;
}
public static IdGenerator getInstance(){
return generator;
}
public static void main(String[] args) {
IdGenerator generator = IdGenerator.getInstance();
for(int i=0;i<10;i++)
System.out.println(generator.getNextID());
}
}
Thank you to Jon, Peter and Upog for helping me on my issue. I wanted to show the real code for what my original issue was, and then show code for what solved it in the hopes that others may benefit from this particular case.
My original problem was that I couldn't increment a static, unrepeatable counter:
/**
* Generate numbers and increment
*/
public class BuggedGenerator {
/************** Public Constants / Factory ***********/
private static BuggedGenerator INSTANCE = null; // to contain the single instance
/**
* The single instance of BuggedGenerator.
*/
public static final BuggedGenerator READ_IN = getInstance();
public static final int GEN_ID = genID();
private static int base = 999999;
/************ Singleton SetUp ************/
/**
* Utility Constructor.
*/
private BuggedGenerator() {
super(); // unnessesary, but I always invoke super()
}
/**
* Initialize the counter singleton
*/
private static int genID() {
BuggedGenerator.SINGLETON.base += 1;
return base
}
/**
* Determine whether BuggedGenerator already has an instance
* and return that instance.
*/
public static BuggedGenerator getInstance() {
if (null == BuggedGenerator.INSTANCE) {
BuggedGenerator.INSTANCE = new BuggedGenerator();
}
return BuggedGenerator.INSTANCE;
} // end getInstance()
}
This is what I was getting from this implementation:
> BuggedGenerator.READ_IN.GEN_ID
> 1000000
> BuggedGenerator.READ_IN.GEN_ID
> 1000000
> BuggedGenerator b = BuggedGenerator.READ_IN
> b.GEN_ID
> 1000000
When prompted with assistance, I used the AtomicInteger class to replace the GEN_ID implementation as shown in Peter's example, but I recieved compile-time errors about static initializations. I decided that it was too much of a pain to go against OOP and implemented the AtomicInteger as a conventional singleton, being a property of the object. Per Jon's suggestion I've included the whole of the code instead of a snapshot. Feel free to use:
/**
* Copyright 2013, Phil Reason. preason intisive com
* Permission to copy, modify, resell and or freely distribute - provided an
* exact copy of this file is explicitly accompanied and unaltered alongside
* of any distribution of works using this file or any modified version of
* this file.
*/
import java.util.concurrent.atomic.AtomicInteger;
/**
* This is a class to generate numbers for various purposes.
* #author Phil Reason
* #conceptionDate 9/6/13
* #version 1.1
* #revisionDate 9/8/13
*/
public class Generator {
/************** Constants *********************/
/**
* The single instance of Generator.
*/
public static final Generator READ_IN = getInstance();
private static Generator INSTANCE = null; // to contain the single instance
/******** Instance Vars: *******************/
private AtomicInteger counter; // construct an AtomicInteger
private int iDRange;
/************ Singleton SetUp ************/
/**
* non-public default constructor override.
*/
private Generator() {
super(); // unnessesary, but I always invoke super()
this.iDRange = 1000000; // the starting number to range increments
this.counter = new AtomicInteger(); // the AtomicInteger instance
} //END Generator()
/**
* Determine whether Generator already has an instance
* and return that instance.
*/
private static Generator getInstance() {
if (null == Generator.INSTANCE) { // upon first use...
Generator.INSTANCE = new Generator(); // construct the single instance
}
return Generator.INSTANCE; // return ony that instance
} // END Generator getInstance()
/**
* Generate non-repeating numbers. This can be useful for serializing when
* inherited serialization isn't useful or needed.
*
* Return the current count generation then increment the AtomicInteger.
* #ensure genID() >= 1000000 && genID() != genID() (never repeats a number)
*/
public int genID () {
return iDRange + counter.getAndIncrement(); // increments the sum of counter
} // END int genID()
}
The output from this implementation is exactly what I needed, as it works for the lifespan of the class' memory residency. For that property, I only had to forecast each increment for JUnit in between tests when setUp() gets rerun - which does not de-reference the static class reference from memory. For the package I was testing, this was actually to my benefit. Here's what I got from output on this latter implement:
> Generator.READ_IN.GEN_ID
> 1000000
> Generator.READ_IN.GEN_ID
> 1000001
> Generator b = Generator.READ_IN
> b.GEN_ID
> 1000002
... and so on ...
In this implementation the AtomicInteger is used as like in any other object with traditional method invocation, though as a singleton. Not only did it work for what I needed, but I was also able to avoid breaking OOP design. I will need more practice before I'm comfortable enough to committing to static factories. Thanks again to you three for taking your time to answer my question!
~phil