I read this code in Thinking in Java and get puzzled:
package generics;
//: generics/Mixins.java
import java.util.*;
interface TimeStamped { long getStamp(); }
class TimeStampedImp implements TimeStamped {
private final long timeStamp;
public TimeStampedImp() {
timeStamp = new Date().getTime();
}
public long getStamp() { return timeStamp; }
}
interface SerialNumbered { long getSerialNumber(); }
class SerialNumberedImp implements SerialNumbered {
private static long counter = 1;
private final long serialNumber = counter++;
public long getSerialNumber() { return serialNumber; }
}
interface Basic {
public void set(String val);
public String get();
}
class BasicImp implements Basic {
private String value;
public void set(String val) { value = val; }
public String get() { return value; }
}
class Mixin extends BasicImp
implements TimeStamped, SerialNumbered {
private TimeStamped timeStamp = new TimeStampedImp();
private SerialNumbered serialNumber =
new SerialNumberedImp();
public long getStamp() { return timeStamp.getStamp(); }
public long getSerialNumber() {
return serialNumber.getSerialNumber();
}
}
public class Mixins {
public static void main(String[] args) {
Mixin mixin1 = new Mixin(), mixin2 = new Mixin();
mixin1.set("test string 1");
mixin2.set("test string 2");
System.out.println(mixin1.get() + " " +
mixin1.getStamp() + " " + mixin1.getSerialNumber());
System.out.println(mixin2.get() + " " +
mixin2.getStamp() + " " + mixin2.getSerialNumber());
while(true)System.out.println(new Date().getTime());
}
} /* Output: (Sample)
test string 1 1132437151359 1
test string 2 1132437151359 2
*///:~
Why are the values returned of getStamp() the same? (1132437151359 == 1132437151359)?
Two objects are created and they have different propoties created in different time, so Why?
The expression new Date().getTime() is a slow way of doing System.currentTimeMillis() which has a minimum resolution of one milli-seconds (but can be as much as 16 ms on some OSes)
This means if the method is called less than one milli-second apart it can give the same result.
A better option is to use AtomicLong.getAndIncrement() for ids.
Using time for serial numbers is not a good idea. The reason you're getting the same time is probably because the code runs rather quickly and enough time doesn't elapse between instantiation of the first object and the second. The time stamp is returned in milliseconds and so if the instantiation of both objects is within 1ms of each other, you won't see a difference.
If you increase load on the system, you might see a difference, or if you use Thread.sleep(5) to cause your program to pause. Both approaches aren't very good.
Instead of using the time for a unique id, use UUID.
Try something like this:
Mixin mixin1 = new Mixin();
Thread.sleep(10);
Mixin mixin2 = new Mixin();
Now you got 10 ms pause in the process of creating those 2 objects.
Your class is simple and you have fast computer so distance in time between two instantations is so small that Java can't see it.
Related
I am trying to use the Methods from a class that i have in an Array list.
The ArrayList is ArrayList With Appliance being a super Class.
the ArrayList contans objects that extends Appliance such as a Clock and Lamp.
when i use
arrayList.get(x) to grab the object at that point i cant see the methods that the object has, I can only see the superClass Objects.
Please can someone help me.
Thank you for reading
Code (Some of it)
public abstract class Appliance implements Serializable {
protected boolean power;
protected ImageIcon picture;
public Appliance() {
}
public void setPower(boolean power) {
this.power = power;
}
public boolean getPower() {
return power;
}
abstract ImageIcon getPicture();
#Override
public String toString() {
String powerVal;
if (this.power == true) {
powerVal = "ON";
} else {
powerVal = "OFF";
}
return "Power: " + powerVal;
}
}
public class Clock extends Appliance {
private int hours;
private int minutes;
private int seconds;
public Clock() {
super();
this.power = false;
this.picture = new ImageIcon("src/res/clock.jpg");
this.hours = 23;
this.minutes = 59;
this.seconds = 59;
}
public Clock(boolean pow, int hours, int minutes, int seconds) {
super();
this.power = pow;
this.picture = new ImageIcon("src/res/clock.jpg");
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
}
public int getHour() {
return this.hours;
}
public void setHours(int hours) {
this.hours = hours;
}
public int getMinutes() {
return this.minutes;
}
public void setMinutes(int minutes) {
this.minutes = minutes;
}
public int getSeconds() {
return this.seconds;
}
public void setSeconds(int seconds) {
this.seconds = seconds;
}
#Override
public ImageIcon getPicture() {
return this.picture;
}
#Override
public String toString(){
return super.toString() + String.format(" and the time is %d:%d:%d",this.hours, this.minutes, this.seconds);
}
}
public class Lamp extends Appliance{
//Default constructor or Empty argument constructor
public Lamp(){
super();
this.power = false;
this.picture = new ImageIcon("src/res/lamp.jpg");
}
public Lamp(boolean pow){
super();
this.power = pow;
this.picture = new ImageIcon("src/res/lamp.jpg");
}
#Override
ImageIcon getPicture() {
return picture;
}
#Override
public String toString(){
return super.toString();
}
}
public class Controller {
private ArrayList<Appliance> myAppliances = new ArrayList<>();
private JLabel[] labelArray;
...................................................
#Override
public void mouseClicked(MouseEvent me) {
String[] options = new String[]{"yes","no"};
if (me.getButton() == 1){
try{
int x = Integer.parseInt( me.getComponent().getName());
Appliance myApp = this.myAppliances.get(x);
if(myApp.getClass().equals(Clock.class)){
JOptionPane.showOptionDialog(null, "Clock Info: /nTime: " + myApp., "Clock", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,options,options[1] );
}
} catch (Exception e){
System.out.println("Null Poiter");
}
}
}
}
Its the myApp. part in the clicked method
I assume you are doing something like this (sorry but it is not clear from your question):
ArrayList<SuperClass> al;
...populated with instances of Appliance
al.get(1).getClock(); //Compile error.
The problem is that java does not know if your element at that position is a SuperClass, Appliance, or something else that inherits from SuperClass. You can cast the code, to make it behave the way you want:
((Appliance)al.get(1)).getClock();
You may also want to use the instanceOf operator to make sure you do have an instance of the class you are expecting.
It sounds like you're writing
List<Appliance> appliances = new ArrayList<>();
appliances.add(new Lamp());
appliances.add(new Clock());
Appliance appliance = appliances.get(0);
appliance.setAlarm(TOMORROW);
I think from this example you can see why you can't access the subclass methods. When you have a list of Appliance, you don't know if the objects in it are Clocks or Lamps, so when you get one out you can't call the subclass methods.
If you are positive the object is a clock, you could cast it:
Clock clock = (Clock) appliances.get(1);
clock.setAlarm(TOMORROW);
But this is not the Java Way. Typically you would use only superclass methods on Appliance, or maintain a separate list for Clocks and Lamps.
ArrayList<Appliance> mylist = new ArrayList();
for(Appliance app : mylist){
boolean isAclock = app instanceof Clock;
boolean isALamp = app instanceof Lame;
if(isAlamp){
Lamp l = (Lamp)app;
}else{
Clock c = (Clock)app;
}
}
making your arralist to accept appliacnces will accept its sub classes bt the problem is receving the correct class object . you can use instance of and check the object type and then cast the object to its original type
try using this approach
That's the expected behavior. It's how polymorphism works.
Let's take a look at an example using your own classes. Imagine holding a bag. You know that only Appliance objects can go into this bag, so you go around all the appliances in your house into this bag - your Lamp, your Clock, maybe your Toaster and a Blender, and a bunch of others.
Now imagine you put on a blindfold and randomly pull out one of the appliances. Without looking at it, how can you tell what appliance it is? You can't! If you assume the thing you just pulled out was a Toaster and you tried to toast() your bread with it, what would happen if you were actually holding a Blender? You'd get a bloody mess, probably. Therefore, the only thing you know for a fact that all Appliance objects can do is turnOn() or turnOff(), so those are the only methods available to you.
In this example, you are the compiler and the bag is the list. If you tell the compiler that the list can hold only Appliance objects, it will not assume anything else about the objects in the list unless you explicitly tell it to (for example, if you downcast the Appliance object to a Toaster by doing something like ((Toaster)applianceList.get(0)).toast()).
I have recently learned Joshua Bloch's builder pattern for creating objects with many optional fields. I've been using something like it for years, but never used an inner-class until Bloch's book suggested it to me. I love it.
I understand that another thread may alter the bulider's configuration, before it's actually built (with build()), such that it may be necessary to re-validate all values in the constructor of the enclosing class. Below is an example of a builder class that optionally reverifies its data.
So my question is this: Assuming this is a robust enough design, when there are defaults for all values--knowing this class is a poor choice for using defaults--and when every set-attempt is validated, is this re-check necessary? Although it may be different, it would never be invalid. Is that correct?
(Although this design is manageable, it is certainly complicated by the potential need for re-verification. And, honestly, I never multi-thread, but I don't want to make my library unusable by people that do.)
Thank you for any advice.
/**
<P><CODE>java ReverifyBuilderInEnclosingCnstrXmpl</CODE></P>
**/
public class ReverifyBuilderInEnclosingCnstrXmpl {
public static final void main(String[] igno_red) {
//Don't reverify
ReverifyBuilderInEnclosingCnstrXmpl rvbdx = new ReverifyBuilderInEnclosingCnstrXmpl.Cfg().
name("Big Bird").age(6).build();
System.out.println(rvbdx.sName);
System.out.println(rvbdx.iAge);
//Do reverify
rvbdx = new ReverifyBuilderInEnclosingCnstrXmpl.Cfg().
reverifyInEnclosing().
name("Big Bird").age(6).build();
}
public final String sName;
public final int iAge;
/**
<P>Create a new <CODE>ReverifyBuilderInEnclosingCnstrXmpl</CODE> with defaults.</P>
**/
public ReverifyBuilderInEnclosingCnstrXmpl() {
//Does not reverify. No need.
this(new ReverifyBuilderInEnclosingCnstrXmpl.Cfg());
}
private ReverifyBuilderInEnclosingCnstrXmpl(ReverifyBuilderInEnclosingCnstrXmpl.Cfg rbdx_c) {
sName = rbdx_c.sName;
iAge = rbdx_c.iAge;
ReverifyBuilderInEnclosingCnstrXmpl.Cfg.zcibValues(rbdx_c, sName, iAge, "constructor");
}
public static class Cfg {
private String sName = null;
private int iAge = -1;
private boolean bReVrfy = false;
public Cfg() {
//Defaults
bReVrfy = false;
name("Broom Hilda");
age(127);
}
//Self-returning configuration...START
//No way to unset.
public Cfg reverifyInEnclosing() {
bReVrfy = true;
return this;
}
public Cfg name(String s_name) {
zcib_name(s_name, "name");
sName = s_name;
return this;
}
public Cfg age(int i_age) {
zcib_age(i_age, "age");
iAge = i_age;
return this;
}
//Self-returning configuration...END
//Validate config...START
public static final void zcibValues(ReverifyBuilderInEnclosingCnstrXmpl.Cfg rbdx_c, String s_name, int i_age, String s_clgFunc) {
try {
if(!rbdx_c.bReVrfy) {
return;
}
} catch(NullPointerException npx) {
throw new NullPointerException("zcibValues: rbdx_c");
}
zcib_name(s_name, s_clgFunc);
zcib_age(i_age, s_clgFunc);
}
public static final void zcib_name(String s_name, String s_clgFunc) {
if(s_name == null || s_name.length() == 0) {
throw new IllegalArgumentException(s_clgFunc + ": s_name (" + s_name + ") is null or empty.");
}
}
public static final void zcib_age(int i_age, String s_clgFunc) {
if(i_age < 0) {
throw new IllegalArgumentException(s_clgFunc + ": i_age (" + i_age + ") is negative.");
}
}
//Validate config...END
public ReverifyBuilderInEnclosingCnstrXmpl build() {
return (new ReverifyBuilderInEnclosingCnstrXmpl(this));
}
}
}
Firstly - the builder pattern is not inherently thread unsafe. I am not sure how you are concluding that it is. Each thread that intends to use the builder will create its own Builder object, populate it in Joshua Bloch's pragmatic and beautiful way and use it to construct the object. There are no static variables being affected anywhere in that mechanism, there is no thread unsafety unless you introduce it yourself.
Your concern about validation is - in my humble opinion - a gross pre-optimisation that produces hideously contrived and horribly bloated code. There is no reason to try to avoid validation just because you know the data is valid. Validation is almost always trivial and often takes little more that a few instructions. By bloating the class with these horrible static validation methods you are probably adding thousands of times more cpu cycles just to load this bloated code than you are saving by avoiding the validation.
Compare your contrived and bloated code with this lucid, succinct and patently correct and thread safe code and see what I mean:
public class Thing {
public final String name;
public final int age;
public Thing() {
this(new Thing.Builder());
}
private Thing(Thing.Builder builder) {
name = builder.name;
age = builder.age;
}
public static class Builder {
private String name = null;
private int age = -1;
public Builder() {
name("Broom Hilda");
age(127);
}
public Builder name(String name) {
if (name == null || name.length() == 0) {
throw new IllegalArgumentException("Thing.Builder.name (" + name + ") is null or empty.");
}
this.name = name;
return this;
}
public Builder age(int age) {
if (age < 0) {
throw new IllegalArgumentException("Thing.Builder.age (" + age + ") is negative.");
}
this.age = age;
return this;
}
public Thing build() {
return (new Thing(this));
}
}
}
You are misunderstanding the pattern on an architectural level: all data during construction is tied to the local thread and not to be exposed to any external handler. The very moment build is called, the now finalized set of parameters is passed to an immutable object, which then first should verify the validity of those parameters in the constructor, then either return the final object or throw an exception.
As long as you keep the builder parameters thread-local, you cannot cause any threading-issues. If you violate this rule, you should ask yourself if what you are doing is correct and/or how you could solve it in a more fine-grained way.
So if you in your example need to use the builder from different threads, the simplest and safest way is to create a new builder instance instead of doing it statically. If you worry about performance, ThreadLocal is your friend.
I am implementing a webservice witch is used to attack one DB.
i need to generate ID for objects that i store and i don't know what's the best way to do it.
i need to increment a INT.
Obviously the webservice must to be used for so much people and maybe various at same time.
so, what's is a good solution?
singleton/synchronize??
i think is the only way i know, maybe there are others better.
if u can show me one example it will be very appreciated.
thanks in advance!
Synchronize has horrible overhead. If all you need is an incremental counter, you can use AtomicLong's incrementAndGet(). Put the AtomicLong in a Singleton to have a server-wide access.
Edit: Some code example:
import java.util.concurrent.atomic.AtomicLong;
public class AtomicIdGenerator
{
private static class SingletonHolder
{
public static final AtomicIdGenerator instance = new AtomicIdGenerator();
}
public static AtomicIdGenerator getInstance()
{
return SingletonHolder.instance;
}
private AtomicLong mIdGenerator = null;
private AtomicIdGenerator()
{
mIdGenerator = new AtomicLong();
}
private AtomicLong getGenerator()
{
return mIdGenerator;
}
public long getNewId()
{
return getGenerator().incrementAndGet();
}
}
Usage example is simply:
long tNewId = AtomicIdGenerator.getInstance().getNewId();
This will be thread-safe, and without any overhead from synchronization. If you foresee yourself handling lots of concurrent use cases in the future, the java.util.concurrent package provides lots of battle-proven implementations for your use cases.
Use synchronize block to achieve this. In synchronized block only one thread can enter inside it.
JVM guarantees that Java synchronized code will only be executed by one thread at a time.
You can do something like this. I've done it a while back, it was based on PostgreSql and iBatis, but you can get the idea.
public class Sequence implements Serializable {
private static final long serialVersionUID = 7526471155622776147L;
private String name = null;
private int nextId = 0;
public Sequence () {
}
public Sequence (String name, int nextId) {
this.name = name;
this.nextId = nextId;
}
public final String getName () {
return name;
}
public final void setName (String name) {
this.name = name;
}
public final int getNextId () {
return nextId;
}
public final void setNextId (int nextId) {
this.nextId = nextId;
}
}
public class SequenceSqlMapDao extends SqlMapClientDaoSupport implements SequenceDao {
/**
* This is a generic sequence ID generator that is based on a database
* table called 'SEQUENCE', which contains two columns (NAME, NEXTID).
* <p/>
* This approach should work with any database.
*
* #param name The name of the sequence.
* #return The Next ID
* #
*/
public final synchronized int getNextId(String name) {
Sequence sequence = new Sequence(name, -1);
//Sequence sequence = new Sequence();
sequence = (Sequence) getSqlMapClientTemplate ().queryForObject("getSequence", sequence);
if (sequence == null) {
try {
throw new IllegalArgumentException("Error: SHOOT! A null sequence was returned from the database (could not get next " + name + " sequence).");
} catch (Exception ex) {
Logger.getLogger(SequenceSqlMapDao.class.getName()).log(Level.SEVERE, null, ex);
}
}
Object parameterObject = new Sequence(name, sequence.getNextId() + 1);
getSqlMapClientTemplate ().update("updateSequence", parameterObject);
int nextId = sequence.getNextId();
parameterObject = null;
sequence = null;
return nextId;
}
}
If nothing else this is pretty database agnostic. You'd still have to expose the method in your webservice.
PS - I forgot where I got this from, otherwise I'd give credit to proper source.
I have a ThreadPool class that has a method add which takes a Runnable and a number of milliseconds as a task to schedule:
public static void addScheduler(Runnable r, long millis) {
//scheduling code
//now I want to save it to check later
ScheduledTask st = new ScheduledTask();
st.setTaskType(r.getClass());
st.setFrequency(millis);
persistentes.add(st); //this is an ArrayList<ScheduledTask>
}
Now I want to store the task info to an ArrayList to check it later, but when I save the information of the task, and check the taskType, it is always java.lang.Class. I understand this is because java type erasure, but is there a way to store the type of the class?
This is my ScheduledTask class:
public class ScheduledTask {
private Class<?> taskType;
private long frequency;
public Class<?> getTaskType() {
return taskType;
}
public void setTaskType(Class<?> taskType) {
this.taskType = taskType;
}
public long getFrequency() {
return frequency;
}
public void setFrequency(long frequency) {
this.frequency = frequency;
}
public String toString(){
return taskType.getClass().getName()+ ": " + (frequency / 1000) + " seg.";
}
}
I believe your mistake is that you call getClass() one too many times:
public String toString(){
return taskType.getClass().getName() + ": " + (frequency / 1000) + " seg.";
}
taskType is the class you're looking for (such as MyTask). Its (raw) type and what is returned by the superfluous call to getClass() is java.lang.Class.
public String toString(){
return taskType.getName() + ": " + (frequency / 1000) + " seg.";
}
You can create the new instance using newInstance() and can check the type (using instanceof operator). You can also get the name of class using getName() and use String comparison
I have a server on which I keep track of some data. When I connect to the server with the administrator application to check out the current state of the data. I use a refresh rate of 5 seconds. The first time the server sends the data, it works. But the second time, when the data changed, the admin-side does not receive the up-to-date data. I'm sending the data, wrapped in a class, through an ObjectOutputStream and ObjectInputStream:
This is the wrapper class for the data:
public class Leerling implements Serializable {
public int llnID;
public String naam;
public String voornaam;
public String klas;
public int klasNummer;
public Date geboorteDatum;
public String getFullName()
{
return voornaam + " " + naam;
}
#Override
public String toString() {
return "Leerling{" + "llnID=" + llnID + ", naam=" + naam + ", voornaam=" + voornaam + ", klas=" + klas + ", klasNummer=" + klasNummer + ", geboorteDatum=" + geboorteDatum + '}';
}
}
public class SLeerling extends Leerling implements Serializable{
public boolean voted;
public int vote = -2;
}
What I tried is before reading the Object from the stream to call System.gc(); to make sure the object old object is not longer in memory. But without success.
Does someone know what the exact problem is? And how to make it possible to get the real up-to-date data?
Thanks in advance.
A second example of the problem:
I have again a wrapper class for some other data (It is an inner class):
public static class MonitorResponse implements Serializable
{
public int numberOfLLN;
public int blocked;
public int blancos;
public List<Integer> votes;
}
When I send the data the first time, it works. But the second time I send it (to update it), everything EXCEPT the List<Integer> votes is updated. So votes isn't refreshed.
Then I solved it a bit tricky by replacing the List by an array:
public static class MonitorResponse implements Serializable
{
public int numberOfLLN;
public int blocked;
public int blancos;
public Integer[] votes;
}
And this works perfect. Strange if you ask me. The the other part of the code I changed almost nothing... (except to implement the array instead of the List)
It's probably the ObjectOutputStream causing the trouble.
If you use a single ObjectOutputStream object on the server then you need to make sure you call reset on it, otherwise it will write shared references to previously-written objects. This sounds like what you are seeing.
To illustrate the problem:
class BrokenServer {
void sendBrokenVoteData(ObjectOutputStream out) {
out.writeObject(votes);
changeVoteData(votes);
out.writeObject(votes); // Writes a shared reference to "votes" WITHOUT updating any data.
}
}
class FixedServer {
void sendFixedVoteData(ObjectOutputStream out) {
out.writeObject(votes);
changeVoteData(votes);
out.reset(); // Clears all shared references.
out.writeObject(votes); // Writes a new copy of "votes" with the new data.
}
}