Java Rätsel

Hallo,

hier das Beispiel für eine generische Methoden Deklaration, welche einen zu zwei Typen A(,B) kompatiblen Argumenttyp verlangt:
Java:
package de.tutorials.training;

public class MultipleInheritanceGenericsExample {

    interface A {
        int getA();
    }

    interface B {
        int getB();
    }

    static class C implements A, B{

        @Override
        public int getA() {
            return 42;
        }

        @Override
        public int getB() {
            return 43;
        }
    }

    public static void main(String[] args) {
        op(new C());
    }

    public static <Arg extends A & B> void op(Arg arg){
        System.out.println("A: " + arg.getA());
        System.out.println("B: " + arg.getB());
    }
}

Gruß Tom
 
Hallo,

was soll uns dein zweites Rätsel sagen, außer dass bei int und float wahrscheinlich wg. Ungenauigkeiten eine Differenz != 0 raus kommt.

Das von Hand nachzuvollziehen finde ich aber ziemlich mühsam... ;-)

Anyway hier noch ein "hands-on" Rätsel für euch:
Java:
package de.thomasdarimont.labs;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SerializableLockExample {

    static class BusinessObject implements Serializable{

        Object lock = new Object();

        public void buisinessMethod(){
            synchronized (lock){
                //...
            }
        }
    }

    public static void main(String[] args) throws Exception{
        new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(new BusinessObject());
    }
}

Wenn man obiges Programm ausführt bekommt man folgende Exception:
Code:
de.thomasdarimont.labs.SerializableLockExample
Exception in thread "main" java.io.NotSerializableException: java.lang.Object
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at de.thomasdarimont.labs.SerializableLockExample.main(SerializableLockExample.java:21)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

Wie bekommt man eine BusinessObject Instanz trotzdem serialisiert ohne Code in der main-Methode, der buisinessMethod-Methode oder den Typ des lock Feldes zu ändern? Was ist die minimale Codeänderung die das Problem löst? Das lock als transient zu deklarieren oder über serialPersistentFields auszuschließen gilt natürlich nicht ;-)

Gruß Tom
 
Ich gebe zu, eher ein wenig geraten zu haben und einen Volltreffer gelandet zu haben, als konzentriert nachgedacht zu haben, aber hier die Lösung:
Folgende Methode zu BusinessObject hinzufügen:
Java:
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
}

Ideone-Link: http://ideone.com/xI8ZpQ
 
Hallo ComFreek,

deine Lösung funktioniert, ist aber nicht das auf was ich mit dem Rätsel hinaus wollte... ;-)
... als Erweiterung der Regeln gilt: Es dürfen keine Methoden zu BusinessObject hinzugefügt und auch keine Klassen durch lokale Definitionen überlagert / geshadowed werden.

Fällt dir unter den Bedingungen noch eine andere Lösung ein?

Gruß Tom
 
Hallo,

die Lösung auf die ich hinaus wollte schaut so aus:
Java:
package de.thomasdarimont.labs;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
 
public class SerializableLockExample {
 
    static class BusinessObject implements Serializable{

        Object lock = new Object[0];
 
        public void buisinessMethod(){
            synchronized (lock){
                //...
            }
        }
    }
 
    public static void main(String[] args) throws Exception{
        new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(new BusinessObject());
    }
}

... d.h. aus
Java:
Object lock = new Object();
wird:
Java:
Object lock = new Object[0];

Object ist nicht serialisierbar, leere Object Arrays schon ;-)

Gruß Tom
 
Danke für die Lösung!

Kannst du mir erklären bzw. den Namen vom Feature nennen, dass du einfach Code in die Klassendeklaration schreiben darfst?
Object lock = ... steht ja nicht innerhalb einer Methode o.Ä. Wann wird dann der Code ausgeführt?
Ich kenne static-Blöcke, ist das das gleiche?
 
Ich lass mich gern über Sonderfälle/Unterschiede(?) etc. aufklären,
aber im Wesentlichen hätte es den selben Effekt,
die Zuweisung vom new-irgendwas im Konstruktor zu machen.
Nur an einen anderen Ort geschrieben.
 
Hallo,

es wird mal wieder Zeit für ein neues Java Rätsel:

Gegeben sei folgendes Java Programm mit vielen unterschiedlichen Arten von Klassendefinitionen:
Java:
import java.io.Serializable;

class F{} //1

public class ClassNameConventionTests { //2

    class A{} //3
    static class B{} //4

    public ClassNameConventionTests(){
        class C{} //5

        new Serializable(){ //6
            class D{} //7

            void foo(){
                class E{} //8
            }

            void bar(){
                class E{} //9
            }
        };
    }
   
    static{
        class X{} //10
    }

    static{
        class X{} //11
    }
}

Frage: Welche .class-Filenames resultieren aus den jeweiligen Class-Definitions?

Gruß Tom
 
Zurück