Unexpected exception expected <nameoftheclass> but was <java.lang.AssertionError> - java

i don´t know how to pass this test. I tried every solution i thought of and didnt find a solution on the internet neither. Its my exam to school.
So, I have this class MojeException.java:
public class MojeException extends RuntimeException {
/**
* Creates a new instance of <code>NewException</code> without detail
* message.
*/
public MojeException() throws AssertionError{
}
/**
* Constructs an instance of <code>NewException</code> with the specified
* detail message.
*
* #param msg the detail message.
*/
public MojeException(String msg) throws AssertionError {
super(msg);
}
}
And i have this test:
#Test(expected = MojeException.class)
public void testKonstruktor11() {
Rozmer rozmer = new Rozmer(0, 0, 0);
fail() ;
}
The error i got is "Unexpected exception, expected but was<java.lang.AssertionError>"
The main class is this, however i dont know if its not irelevant:
public class Rozmer {
public static final double DIMENZE_MAX = 100;
public static final double DIMENZE_MIN = .1;
private static final double TO_CM = 100.00;
private final long delka;
private final long sirka;
private final long vyska;
public Rozmer(double delka, double sirka, double vyska){
this.delka = (long)(delka * TO_CM);
this.sirka = (long) (sirka * TO_CM);
this.vyska = (long) (vyska * TO_CM);
}
public double getDelka() {
return delka/TO_CM;
}
public double getSirka() {
return sirka/TO_CM;
}
public double getVyska() {
return vyska/TO_CM;
}
#Override
public String toString() {
return "Rozmer{" + "delka= " + delka/TO_CM + "0,sirka= " + sirka/TO_CM + "0,vyska= " + vyska/TO_CM + "0}";
}
#Override
public int hashCode() {
int hash = 7;
hash = 89 * hash + (int) (this.delka ^ (this.delka >>> 32));
hash = 89 * hash + (int) (this.sirka ^ (this.sirka >>> 32));
hash = 89 * hash + (int) (this.vyska ^ (this.vyska >>> 32));
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Rozmer other = (Rozmer) obj;
if (this.delka != other.delka) {
return false;
}
if (this.sirka != other.sirka) {
return false;
}
if (this.vyska != other.vyska) {
return false;
}
return true;
}
public static boolean kontrolaDimenze(double dimenze) {
return DIMENZE_MIN <= dimenze && dimenze<=DIMENZE_MAX;
}
Thanks for all your ideas and solutions :)

Basically, you are instructing JUnit that in your test you expect that a MojeException (which is a RuntimeException) will be eventually thrown, and that it's not done by fail(), which instead throws an AssertionException, so a total different one.
So, you have to throw that specific exception somewhere, otherwise your test will always fail.
The best point to do that is possibly in your constructor, because it's the only method you invoked in the test, so it looks like you are testing that specific constructor. Maybe after checking one of the input parameters, which doesn't match an expected value, you can throw your exception.
Here is just an example of how you can modify your Rozmer class constructor:
public Rozmer(double delka, double sirka, double vyska) throws MojeException {
if(delka == 0.0 || sirka == 0.0 || vyska == 0.0) {
throw new MojeException("Unsupported value for delka, sirka or vyska");
}
this.delka = (long)(delka * TO_CM);
this.sirka = (long) (sirka * TO_CM);
this.vyska = (long) (vyska * TO_CM);
}
Then remove the fail() from your test.

Related

Strange bootloader casting issue caused by different packages: "class [Ljava.lang.Object; cannot be cast to class ([Ljava.lang.Object; "

I'm trying to create a nativeQuery in Spring Boot, but I'm getting a strange bootloader message when I try it:
"class [Ljava.lang.Object; cannot be cast to class com.sick.as.models.common.v1.INorcaSummarySystemDTO ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; com.sick.as.models.common.v1.INorcaSummarySystemDTO is in unnamed module of loader 'app')",
Here's the code which triggers the exception:
#Override
public List<INorcaSummarySystemDTO> getNorcaSummaryBySystem(Long startDate, Long endDate){
Query nativeQuery = this.entityManager.createNativeQuery(norcaSummaryBySystemAndDeviceQuery);
nativeQuery.setParameter("startDate", startDate);
nativeQuery.setParameter("endDate", endDate);
List<INorcaSummarySystemDTO> results = (List<INorcaSummarySystemDTO>) nativeQuery.getResultList();
for (INorcaSummarySystemDTO norcaSummarySystemDTO:results) {
LOG.error(norcaSummarySystemDTO.toString()); <========== exception here
}
The exception is generated on the LOG message.
When I hover over the results returned, it shows a list of objects rather than INorcaSummarySystemDTO
[[Ljava.lang.Object;#9648014, [Ljava.lang.Object;#35cfd4d1, [Ljava.lang.Object;#39be3202, [Ljava.lang.Object;#42efd1c9, [Ljava.lang.Object;#6fa68da0, [Ljava.lang.Object;
Based on the error message shown at the start (which is returned to Postman from an API call), there apparently is an issue with the fact that the executing code is getting the DTO from a different bootloader.
For reference, here is the code for the interface and the implementing class:
package com.sick.as.models.common.v1;
public interface INorcaSummarySystemDTO extends Comparable<INorcaSummarySystemDTO> {
/**
* #return system name
*/
public String getSystemName();
public void setSystemName(String systemName);
/**
* #return system label
*/
public String getSystemLabel();
public void setSystemLabel(String systemLabel);
/**
* #return Feature Vector
*/
public Long getFeatureVector();
public void setFeatureVector(Long featureVector);
/**
* #return Norca Code
*/
public String getNorcaCode();
public void setNorcaCode(String norcaCode);
/**
* #return count
*/
public Integer getSum();
public void setSum(Integer sum);
}
package com.sick.as.models.common.v1;
import java.util.Comparator;
public class NorcaSummarySystemDTO implements INorcaSummarySystemDTO {
private String systemName;
private String systemLabel;
private Long featureVector;
private String norcaCode;
private Integer sum;
public NorcaSummarySystemDTO() {
}
public NorcaSummarySystemDTO(INorcaSummarySystemDTO extractDTO) {
super();
this.systemName = extractDTO.getSystemName();
this.systemLabel = extractDTO.getSystemLabel();
this.featureVector = extractDTO.getFeatureVector();
this.norcaCode = extractDTO.getNorcaCode();
this.sum = extractDTO.getSum();
}
public String getSystemName() {
return systemName;
}
public void setSystemName(String systemName) {
this.systemName = systemName;
}
public String getSystemLabel() {
return systemLabel;
}
public void setSystemLabel(String systemLabel) {
this.systemLabel = systemLabel;
}
public Long getFeatureVector() {
return featureVector;
}
public void setFeatureVector(Long featureVector) {
this.featureVector = featureVector;
}
public String getNorcaCode() {
return norcaCode;
}
public void setNorcaCode(String norcaCode) {
this.norcaCode = norcaCode;
}
public Integer getSum() {
return sum;
}
public void setSum(Integer sum) {
this.sum = sum;
}
#Override
public int compareTo(INorcaSummarySystemDTO o){
return Comparator.comparing(INorcaSummarySystemDTO::getSystemName)
.thenComparing(INorcaSummarySystemDTO::getFeatureVector)
.compare(this, o);
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((featureVector == null) ? 0 : featureVector.hashCode());
result = prime * result + ((systemName == null) ? 0 : systemName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NorcaSummarySystemDTO other = (NorcaSummarySystemDTO) obj;
if (featureVector == null) {
if (other.featureVector != null)
return false;
} else if (!featureVector.equals(other.featureVector))
return false;
if (systemName == null) {
if (other.systemName != null)
return false;
} else if (!systemName.equals(other.systemName))
return false;
return true;
}
}
Any ideas what's causing this? The code is based on an example in this url:
https://thorben-janssen.com/jpa-native-queries/
Effectively the reason is that JPA does not know of any way convert the Object that is read, into your desired POJO.
One way you can achieve is to declare your DTO as an #Entity which will ensure that it is JPA managed and then you can call the following overloaded method of createNativeQuery :
/**
* Create an instance of <code>Query</code> for executing
* a native SQL query.
* #param sqlString a native SQL query string
* #param resultClass the class of the resulting instance(s)
* #return the new query instance
*/
public Query createNativeQuery(String sqlString, Class resultClass);
//-----------------
Query nativeQuery =
this.entityManager.createNativeQuery(norcaSummaryBySystemAndDeviceQuery, NorcaSummarySystemDTO.class);
Once you declare it as an entity there are multiple ways where you can map the result to the DTO.
You can also try one of the manual way , which is get the list and individually initialize the dto by fetching individual records.
List<Object[]> results = nativeQuery.getResultList();
for(Object[] entry: results){
//init NorcaSummarySystemDTO
// entry[0] - > set first attribute
// entry[1] - > set second attribute and so on
}

Error: No enclosing instance of type Main is accessible. Must qualify the allocation with an enclosing instance of type Main (e.g. x.new A() wh [duplicate]

This question already has answers here:
What causes error "No enclosing instance of type Foo is accessible" and how do I fix it?
(11 answers)
Closed 3 years ago.
My code does not work. I get the following error:
No enclosing instance of type Main is accessible. Must qualify the allocation with an enclosing instance of type Main (e.g. x.new A() where x is an instance of Main).
You see my code in the following:
class Main {
public class Room {
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + etage;
result = prime * result + gebäude;
result = prime * result + raumnummer;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Room other = (Room) obj;
if (etage != other.etage)
return false;
if (gebäude != other.gebäude)
return false;
if (raumnummer != other.raumnummer)
return false;
return true;
}
public int gebäude;
public int etage;
public int raumnummer;
public Room(int gebäude, int etage, int raumnummer) {
super();
this.gebäude = gebäude;
this.etage = etage;
this.raumnummer = raumnummer;
}
#Override
public String toString() {
String s = String.format("%2s-%s.%02d", this.gebäude, this.etage, this.raumnummer);
return s;
}
}
public static void main(String[] args) {
Room office = new Room(17, 0, 10);
Room lecture = new Room(2, 0, 10);
Room lab = new Room(18, 1, 1);
System.out.println(office); // => "17-0.10"
System.out.println(lecture); // => " 2-0.10"
System.out.println(lab); // => "18-1.01"
}
}
SOLUTION 1
Separating the class Room from the class Main did the trick for me:
File Main.java:
public class Main {
public static void main(String[] args) {
Room office = new Room(17, 0, 10);
Room lecture = new Room(2, 0, 10);
Room lab = new Room(18, 1, 1);
System.out.println(office); // => "17-0.10"
System.out.println(lecture); // => " 2-0.10"
System.out.println(lab); // => "18-1.01"
}
}
File Room.java:
public class Room {
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + etage;
result = prime * result + gebäude;
result = prime * result + raumnummer;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Room other = (Room) obj;
if (etage != other.etage)
return false;
if (gebäude != other.gebäude)
return false;
if (raumnummer != other.raumnummer)
return false;
return true;
}
public int gebäude;
public int etage;
public int raumnummer;
public Room(int gebäude, int etage, int raumnummer) {
super();
this.gebäude = gebäude;
this.etage = etage;
this.raumnummer = raumnummer;
}
#Override
public String toString() {
String s = String.format("%2s-%s.%02d", this.gebäude, this.etage, this.raumnummer);
return s;
}
}
Let me investigate why this happens and I will post the reason. By now, this is a suitable fix if you don't need both classes to be on the same file.
SOLUTION 2
Make room static:
...
class Main {
public static class Room {
#Override
public int hashCode() {
final int prime = 31;
...
WHY THIS HAPPENS
As stated in this post, by having Room as an inner class of Main, you are forcing the instances of Room to have an instance o Main. When using the operator new on the inner class Room without making a new instance of Main an error is produced.
By making the class Room static the class doesn't need an instance of Main.
This is because Room is an inner class of Main, but is not declared as a static member. When you have a non-static inner class, it can only be instantiated using an object of the outer class, otherwise the expression Main.this (which is legal in the inner class) would not have an instance of Main to refer to. Since the main method is static, there is no Main instance to pass to the Room constructor.
The solution is simply to replace the declaration public class Room with public static class Room.

hashCode changes each time the object is created [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
There is something that escapes me about hashCode. I know that if i override
equals, then i must override hashCode too. I also know that if two objects are
equal, then the hashCode of the two objects must be equal. If the fields that are checked in the equals method don't change, than the hashCode should not change, right?
If so, then i can't understand why each time i create an instance of the object below, i get a different hashCode:
public class Effect {
private long timestamp;
private int damage;
private SquareType squareType;
public Effect(long timestamp, int damage, SquareType squareType) {
this.timestamp = timestamp;
this.damage = damage;
this.squareType = squareType;
}
public long getTimestamp() {
return timestamp;
}
public int getDamage() {
return damage;
}
public SquareType getSquareType() {
return squareType;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Effect effect = (Effect) o;
if (getDamage() != effect.getDamage()) return false;
return getSquareType() == effect.getSquareType();
}
#Override
public int hashCode() {
int result = getDamage();
result = 31 * result + (getSquareType() != null ? getSquareType().hashCode() : 0);
return result;
}
#Override
public String toString() {
String ret = "Effect hashcode: " + hashCode();
return ret;
}
}
In the code i create this kind of objects continuously over time. The only field that changes each time is "timestamp", but the two other fields don't change (unless there is a specific event). What happens is that the hashCode value is always different, even if "damage" and "SquareType" are the same.
I don't use "timestamp" in my equals and hashCode, so i can't understand why i get this behavior.
Update
This is SquareType:
public enum SquareType {
FIRE, WIND, WATER, EARTH
}
Update 2
For example, if i create 10 instances of Effect, i iterate over them and i
print them (toString() returns the hashCode value) i get 10 different values.
If two instances of Effect have the same "damage" and "SquareType" then they must be equal and have the same hashCode.
Update 3
The effects are created like this:
#Override
public void friendlyFire(BaseBullet bullet, BaseSquare square) {
square.notifyFriendlyFire(new Effect(TimeUtils.millis(),
square.getDamage(), square.getSquareType()), new MyKey(square.getUniqueID()));
}
The only Effect's field that changes is the timestamp, and i don't use it in equals and hashCode.
public void notifyFriendlyFire(Effect newEffect, MyKey key) {
// System.out.println("The map contains the key? " + effectMap.containsKey(key));
if(effectMap.containsKey(key)) {
Effect oldEffect = effectMap.get(key);
System.out.println(newEffect);
if(!oldEffect.equals(newEffect)) {
System.out.println("old effect changed!");
// remove the old effect
removeEffect(oldEffect);
// update the map with the new effect
effectMap.put(key, newEffect); //
// apply the new effect
applyEffect(newEffect);
}
}
else {
// new effect
effectMap.put(key, newEffect);
applyEffect(newEffect);
}
}
The check "if(!oldEffect.equals(newEffect))" is always true, even if damage and type are the same.
Update 4
I've found the bug. Damage increases continuously. Now i've just to figure out why...
Here's my attempt at approximating your implementation:
package cruft;
import java.util.Date;
/**
* Equals and hashCode test
* Creation date 1/16/2016.
* #link https://stackoverflow.com/questions/34826585/hashcode-changes-each-time-the-object-is-created
*/
public class OverrideDemo {
private long timestamp;
private int damage;
private SquareType squareType;
public OverrideDemo(int damage, SquareType squareType) {
this(damage, squareType, new Date().getTime());
}
public OverrideDemo(int damage, SquareType squareType, long timestamp) {
if (squareType == null) throw new IllegalArgumentException("square type cannot be null");
this.timestamp = timestamp;
this.damage = damage;
this.squareType = squareType;
}
public long getTimestamp() {
return timestamp;
}
public int getDamage() {
return damage;
}
public SquareType getSquareType() {
return squareType;
}
#Override
public boolean equals(Object o) {
if (this == o) { return true; }
if (o == null || getClass() != o.getClass()) { return false; }
OverrideDemo that = (OverrideDemo) o;
if (damage != that.damage) { return false; }
return squareType == that.squareType;
}
#Override
public int hashCode() {
int result = damage;
result = 31 * result + squareType.hashCode();
return result;
}
#Override
public String toString() {
return "OverrideDemo{" +
"timestamp=" + timestamp +
", damage=" + damage +
", squareType=" + squareType +
'}';
}
}
enum SquareType { FIRE, WIND, WATER, EARTH }
Here's a Junit test that shows how the methods behave. All tests pass; I think this implementation is correct.
package cruft;
import org.junit.Assert;
import org.junit.Test;
/**
* Junit test demonstrates testing equals and hashcode contract
* Created by Michael
* Creation date 1/16/2016.
* #link https://stackoverflow.com/questions/34826585/hashcode-changes-each-time-the-object-is-created
*/
public class OverrideDemoTest {
#Test
public void testEquals_Null() {
OverrideDemo x = new OverrideDemo(5, SquareType.EARTH);
Assert.assertFalse(x.equals(null));
}
#Test
public void testEquals_Reflexive() {
OverrideDemo x = new OverrideDemo(5, SquareType.EARTH);
Assert.assertTrue(x.equals(x));
}
#Test
public void testEquals_Symmetric() {
OverrideDemo x = new OverrideDemo(5, SquareType.EARTH);
OverrideDemo y = new OverrideDemo(5, SquareType.EARTH);
Assert.assertTrue(x.equals(y));
Assert.assertTrue(y.equals(x));
Assert.assertTrue(x.hashCode() == y.hashCode());
}
#Test
public void testEquals_Transitive() {
OverrideDemo x = new OverrideDemo(5, SquareType.EARTH);
OverrideDemo y = new OverrideDemo(5, SquareType.EARTH);
OverrideDemo z = new OverrideDemo(5, SquareType.EARTH);
Assert.assertTrue(x.equals(y));
Assert.assertTrue(y.equals(z));
Assert.assertTrue(z.equals(x));
Assert.assertTrue(x.hashCode() == y.hashCode());
Assert.assertTrue(y.hashCode() == z.hashCode());
Assert.assertTrue(z.hashCode() == x.hashCode());
}
#Test
public void testEquals_DifferentDamage_NotEqual() {
OverrideDemo x = new OverrideDemo(5, SquareType.EARTH);
OverrideDemo y = new OverrideDemo(10, SquareType.EARTH);
Assert.assertFalse(x.equals(y));
Assert.assertFalse(y.equals(x));
Assert.assertFalse(x.hashCode() == y.hashCode());
}
#Test
public void testEquals_DifferentSquareType_NotEqual() {
OverrideDemo x = new OverrideDemo(10, SquareType.EARTH);
OverrideDemo y = new OverrideDemo(10, SquareType.FIRE);
Assert.assertFalse(x.equals(y));
Assert.assertFalse(y.equals(x));
Assert.assertFalse(x.hashCode() == y.hashCode());
}
}

Check with what object the method is triggered

I call this method in java:
private void updateDisplay()
{
displayString = hours.getDisplayValue() + ":" +
minutes.getDisplayValue();
}
What triggers this method two times for hours and minutes:
public String getDisplayValue()
{
if(value < 10) {
return "0" + value;
}
else {
return "" + value;
}
}
My question is how can i check in getDisplayValue if the method is triggerd as minute or as hour? For example:
public String getDisplayValue()
{ if(this == minutes){
if(value < 10) {
return "0" + value;
}
else {
return "" + value;
}
}
Entire code:
public class ClockDisplay
{
private NumberDisplay hours;
private NumberDisplay minutes;
private String displayString; // simulates the actual display
/**
* Constructor for ClockDisplay objects. This constructor
* creates a new clock set at 00:00.
*/
public ClockDisplay()
{
hours = new NumberDisplay(24);
minutes = new NumberDisplay(60);
updateDisplay();
}
/**
* Constructor for ClockDisplay objects. This constructor
* creates a new clock set at the time specified by the
* parameters.
*/
public ClockDisplay(int hour, int minute)
{
hours = new NumberDisplay(24);
minutes = new NumberDisplay(60);
setTime(hour, minute);
}
/**
* This method should get called once every minute - it makes
* the clock display go one minute forward.
*/
public void timeTick()
{
minutes.increment();
if(minutes.getValue() == 0) { // it just rolled over!
hours.increment();
}
updateDisplay();
}
/**
* Set the time of the display to the specified hour and
* minute.
*/
public void setTime(int hour, int minute)
{
hours.setValue(hour);
minutes.setValue(minute);
updateDisplay();
}
/**
* Return the current time of this display in the format HH:MM.
*/
public String getTime()
{
return displayString;
}
/**
* Update the internal string that represents the display.
*/
private void updateDisplay()
{
displayString = hours.getDisplayValue() + ":" +
minutes.getDisplayValue();
}
}
And:
public class NumberDisplay
{
private int limit;
private int value;
/**
* Constructor for objects of class NumberDisplay.
* Set the limit at which the display rolls over.
*/
public NumberDisplay(int rollOverLimit)
{
limit = rollOverLimit;
value = 0;
}
/**
* Return the current value.
*/
public int getValue()
{
return value;
}
/**
* Return the display value (that is, the current value as a two-digit
* String. If the value is less than ten, it will be padded with a leading
* zero).
*/
public String getDisplayValue()
{
if(value < 10) {
return "0" + value;
}
else {
return "" + value;
}
}
/**
* Set the value of the display to the new specified value. If the new
* value is less than zero or over the limit, do nothing.
*/
public void setValue(int replacementValue)
{
if((replacementValue >= 0) && (replacementValue < limit)) {
value = replacementValue;
}
}
/**
* Increment the display value by one, rolling over to zero if the
* limit is reached.
*/
public void increment()
{
value = (value + 1) % limit;
}
}
}
Do it using reflection by checking the stack trace, see Thread#getStackTrace:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace()
Go through the API and see what methods are useful for your needs.
But why don't you simply pass an identifier that allows you to detect who called the method?
pass a parameter into getDisplayValue() function like this
getDisplayValue(char c)
and change your function definition to :
public String getDisplayValue(char c)
{
if(c == 'h'){
if(value < 10) {
return "0" + value;
}
else {
return "" + value;
}
}
else if(c=='m'){
return value*60;
}
}
and change updateDisplay() to :
private void updateDisplay()
{
displayString = hours.getDisplayValue(h) + ":" +
minutes.getDisplayValue(m);
}
Introduce a boolean parameter in the function declaration
public String getDisplayValue(Boolean isMinute)
{
if(isMinute)
{
if(value < 10) {
return "0" + value;
}
else {
return "" + value;
}
}
else{
// not a minute, continue
}
}
you can call this like
displayString = hours.getDisplayValue(false) + ":" +
minutes.getDisplayValue(true);
i will added a boolean flag in ClockDisplay i.e. isHour. And will change the constructure:
class ClockDisplay{
boolean isHour;
public ClockDisplay(boolean isHour)
{
hours = new NumberDisplay(24);
minutes = new NumberDisplay(60);
updateDisplay();
this.isHour=isHour;
}
...........
...........
}
Now in NumberDisplay i will change the method:
public String getDisplayValue(ClockDisplay c)
{
if(value < 10) {
return "0" + value;
}
else {
return "" + value;
}
c.
}
Now inside the method getDisplayValue() you can call any method on top of c, and it can print accordingly because you have set isHour accordingly.
The reason behind my design is: The abstraction whether hour or minute it should be encapsulated inside ClockDisplay. So just pass the ClockDisplay reference to getDisplayValue().
You can introduce 2 sub-classes
public class HourDisplay extends NumberDisplay {
// override getDisplayValue method the way you want
}
public class MinuteDisplay extends NumberDisplay {
// override getDisplayValue method the way you want
}
Then in ClockDisplay constructor
public ClockDisplay()
{
hours = new HourDisplay(24);
minutes = new MinuteDisplay(60);
updateDisplay();
}

ObjectInputStream.GetField and ObjectOutputStream.PutField

Does anybody maybe know how ObjectInputStream.GetField and ObjectOutputStream.PutField are used. my program need to look for specific objects at specific times and the above classes would really help me get it right.
ObjectOutputStream.PutField:
private class PutFieldImpl extends PutField {
/** class descriptor describing serializable fields */
private final ObjectStreamClass desc;
/** primitive field values */
private final byte[] primVals;
/** object field values */
private final Object[] objVals;
/**
* Creates PutFieldImpl object for writing fields defined in given
* class descriptor.
*/
PutFieldImpl(ObjectStreamClass desc) {
this.desc = desc;
primVals = new byte[desc.getPrimDataSize()];
objVals = new Object[desc.getNumObjFields()];
}
public void put(String name, boolean val) {
Bits.putBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
}
public void put(String name, byte val) {
primVals[getFieldOffset(name, Byte.TYPE)] = val;
}
public void put(String name, char val) {
Bits.putChar(primVals, getFieldOffset(name, Character.TYPE), val);
}
public void put(String name, short val) {
Bits.putShort(primVals, getFieldOffset(name, Short.TYPE), val);
}
public void put(String name, int val) {
Bits.putInt(primVals, getFieldOffset(name, Integer.TYPE), val);
}
public void put(String name, float val) {
Bits.putFloat(primVals, getFieldOffset(name, Float.TYPE), val);
}
public void put(String name, long val) {
Bits.putLong(primVals, getFieldOffset(name, Long.TYPE), val);
}
public void put(String name, double val) {
Bits.putDouble(primVals, getFieldOffset(name, Double.TYPE), val);
}
public void put(String name, Object val) {
objVals[getFieldOffset(name, Object.class)] = val;
}
// deprecated in ObjectOutputStream.PutField
public void write(ObjectOutput out) throws IOException {
/*
* Applications should *not* use this method to write PutField
* data, as it will lead to stream corruption if the PutField
* object writes any primitive data (since block data mode is not
* unset/set properly, as is done in OOS.writeFields()). This
* broken implementation is being retained solely for behavioral
* compatibility, in order to support applications which use
* OOS.PutField.write() for writing only non-primitive data.
*
* Serialization of unshared objects is not implemented here since
* it is not necessary for backwards compatibility; also, unshared
* semantics may not be supported by the given ObjectOutput
* instance. Applications which write unshared objects using the
* PutField API must use OOS.writeFields().
*/
if (ObjectOutputStream.this != out) {
throw new IllegalArgumentException("wrong stream");
}
out.write(primVals, 0, primVals.length);
ObjectStreamField[] fields = desc.getFields(false);
int numPrimFields = fields.length - objVals.length;
// REMIND: warn if numPrimFields > 0?
for (int i = 0; i < objVals.length; i++) {
if (fields[numPrimFields + i].isUnshared()) {
throw new IOException("cannot write unshared object");
}
out.writeObject(objVals[i]);
}
}
/**
* Writes buffered primitive data and object fields to stream.
*/
void writeFields() throws IOException {
bout.write(primVals, 0, primVals.length, false);
ObjectStreamField[] fields = desc.getFields(false);
int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) {
if (extendedDebugInfo) {
debugInfoStack.push(
"field (class \"" + desc.getName() + "\", name: \"" +
fields[numPrimFields + i].getName() + "\", type: \"" +
fields[numPrimFields + i].getType() + "\")");
}
try {
writeObject0(objVals[i],
fields[numPrimFields + i].isUnshared());
} finally {
if (extendedDebugInfo) {
debugInfoStack.pop();
}
}
}
}
/**
* Returns offset of field with given name and type. A specified type
* of null matches all types, Object.class matches all non-primitive
* types, and any other non-null type matches assignable types only.
* Throws IllegalArgumentException if no matching field found.
*/
private int getFieldOffset(String name, Class type) {
ObjectStreamField field = desc.getField(name, type);
if (field == null) {
throw new IllegalArgumentException("no such field " + name +
" with type " + type);
}
return field.getOffset();
}
}
ObjectInputStream.GetField:
private class GetFieldImpl extends GetField {
/** class descriptor describing serializable fields */
private final ObjectStreamClass desc;
/** primitive field values */
private final byte[] primVals;
/** object field values */
private final Object[] objVals;
/** object field value handles */
private final int[] objHandles;
/**
* Creates GetFieldImpl object for reading fields defined in given
* class descriptor.
*/
GetFieldImpl(ObjectStreamClass desc) {
this.desc = desc;
primVals = new byte[desc.getPrimDataSize()];
objVals = new Object[desc.getNumObjFields()];
objHandles = new int[objVals.length];
}
public ObjectStreamClass getObjectStreamClass() {
return desc;
}
public boolean defaulted(String name) throws IOException {
return (getFieldOffset(name, null) < 0);
}
public boolean get(String name, boolean val) throws IOException {
int off = getFieldOffset(name, Boolean.TYPE);
return (off >= 0) ? Bits.getBoolean(primVals, off) : val;
}
public byte get(String name, byte val) throws IOException {
int off = getFieldOffset(name, Byte.TYPE);
return (off >= 0) ? primVals[off] : val;
}
public char get(String name, char val) throws IOException {
int off = getFieldOffset(name, Character.TYPE);
return (off >= 0) ? Bits.getChar(primVals, off) : val;
}
public short get(String name, short val) throws IOException {
int off = getFieldOffset(name, Short.TYPE);
return (off >= 0) ? Bits.getShort(primVals, off) : val;
}
public int get(String name, int val) throws IOException {
int off = getFieldOffset(name, Integer.TYPE);
return (off >= 0) ? Bits.getInt(primVals, off) : val;
}
public float get(String name, float val) throws IOException {
int off = getFieldOffset(name, Float.TYPE);
return (off >= 0) ? Bits.getFloat(primVals, off) : val;
}
public long get(String name, long val) throws IOException {
int off = getFieldOffset(name, Long.TYPE);
return (off >= 0) ? Bits.getLong(primVals, off) : val;
}
public double get(String name, double val) throws IOException {
int off = getFieldOffset(name, Double.TYPE);
return (off >= 0) ? Bits.getDouble(primVals, off) : val;
}
public Object get(String name, Object val) throws IOException {
int off = getFieldOffset(name, Object.class);
if (off >= 0) {
int objHandle = objHandles[off];
handles.markDependency(passHandle, objHandle);
return (handles.lookupException(objHandle) == null) ?
objVals[off] : null;
} else {
return val;
}
}
/**
* Reads primitive and object field values from stream.
*/
void readFields() throws IOException {
bin.readFully(primVals, 0, primVals.length, false);
int oldHandle = passHandle;
ObjectStreamField[] fields = desc.getFields(false);
int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) {
objVals[i] =
readObject0(fields[numPrimFields + i].isUnshared());
objHandles[i] = passHandle;
}
passHandle = oldHandle;
}
/**
* Returns offset of field with given name and type. A specified type
* of null matches all types, Object.class matches all non-primitive
* types, and any other non-null type matches assignable types only.
* If no matching field is found in the (incoming) class
* descriptor but a matching field is present in the associated local
* class descriptor, returns -1. Throws IllegalArgumentException if
* neither incoming nor local class descriptor contains a match.
*/
private int getFieldOffset(String name, Class type) {
ObjectStreamField field = desc.getField(name, type);
if (field != null) {
return field.getOffset();
} else if (desc.getLocalDesc().getField(name, type) != null) {
return -1;
} else {
throw new IllegalArgumentException("no such field " + name +
" with type " + type);
}
}
}
/e1
You get an instance of PutField by calling ObjectOutputStream#putFields and likewise you get an instance of GetField by calling ObjectInputStream#readFields.

Categories

Resources