views:

103

answers:

5

Term over-type structure = a data structure that accepts different types, can be primitive or user-defined.

I think ruby supports many types in structures such as tables. I tried a table with types 'String', 'char' and 'File' in Java but errs.

  1. How can I have over-typed structure in Java?
  2. How to show types in declaration? What about in initilization? Suppose a structure:

          INDEX    VAR      FILETYPE
            //0 -> file     FILE
            //1 -> lineMap  SizeSequence
            //2 -> type     char
            //3 -> binary   boolean
            //4 -> name     String
            //5 -> path     String
    

Code

import java.io.*;
import java.util.*;

public class Object
{
        public static void print(char a)
        {
                System.out.println(a);
        }
        public static void print(String s)
        {
                System.out.println(s);
        }

        public static void main(String[] args)
        {
                Object[] d = new Object[6];
                d[0] = new File(".");
                d[2] = 'T';
                d[4] = ".";

                print(d[2]);
                print(d[4]);
        }
}

Errors

Object.java:18: incompatible types
found   : java.io.File
required: Object
        d[0] = new File(".");
               ^
Object.java:19: incompatible types
found   : char
required: Object
        d[2] = 'T';
               ^

After the nuisance to the real problem:

d[2] stores char-type, but methods sees it as Object. Many of my methods do not have Object, so changing them because of this one feels too much.

  1. How can I change the types before giving them as pars?
  2. Should I do it in separate processing class or is there ready method?

Code

package file;

import java.io.*;
import java.util.*;

public class ObjectTest
{
        //I have this kind of methods
        //I want them to work with Object
        // without changing the par type,
        // possible?
        public static void print(char a)
        {
                System.out.println(a);
        }
        public static void print(String s)
        {
                System.out.println(s);
        }

        public static void main(String[] args)
        {
                java.lang.Object[] d = new java.lang.Object[6];
                d[0] = (Object) new File(".");
                d[2] = (Object) new Character('T');
                d[4] = (Object) new String(".");

                print(d[2]);
                print(d[4]);
        }
        //I can get it this way working
        // but some of my methods are not Objects
        // and they need to be types like String
        private static void print(Object object) {
            System.out.println(object);
        }
}
A: 

'T' is a primitive character, so it is not an Object. You can change it:

d[2] = new Character('T');

The String type is an Object.

As to why it doesn't accept a new File object... I don't have a good answer to that off the top of my head.

EDIT: I just noticed that your class name is Object - try changing it to something else (Test, MyTest, etc) - see if that helps.

aperkins
+6  A: 

You've named your class Object, so it conflicts with java.lang.Object. Give it another name or alternatively include the package name in your array declaration. e.g.

java.lang.Object[] d = new java.lang.Object[6];
nxt
A: 

The name of your class is Object, which is a really good way to cause confusion. Rename it to something else, because the type of d is not java.lang.Object[] in your case. After you fix that,

 d[0] = new File(".");

and

 d[4] = ".";

will be perfectly valid.

waxwing
A: 

Doing that dispatch is going to be fairly hard. The problem is that Java works out what method to dispatch to at compile time. To be able to select which method to dispatch to, you'll have to use reflection to do dynamic dispatch. Messy.

In the simple case, you'll dispatch like this (with exception handling omitted):

java.lang.Object arg = d[2]; // or whatever
java.lang.reflect.Method m = this.getClass().getMethod("print", arg.getClass());
m.invoke(null, arg); // first arg should be this if non-static method

Note that adding the exception handling bulks this out a lot; there are a great many things that can go wrong. This is why most Java programs aren't written in the way the question describes.

Donal Fellows
BTW, I'm assuming that @nxt's fix is applied.
Donal Fellows
+3  A: 

@nxt already nailed down the root cause.

But I suggest to forget this approach at all. Wrap the data in a custom Javabean-like class such as:

public class MyFile {
    private File file;
    private SizeSequence lineMap;
    private char type;
    private boolean binary;
    private String name;
    private String path;
    // Add/generate constructors, getters, setters, equals, hashcode, toString.
    // An IDE can do that in few clicks.
}

Then just use new MyFile() the usual Java way. It's not only typesafe, but also more self-documenting, reuseable and maintainable. It's the normal approach of using "over-typed structures".

BalusC
well what would have been cooler than just arr.toString().replace("],", ":") --- have to change back to the old style :)
HH
"Javabean" is a *standard*. There exist **a lot** of Javabean mapping/introspection/massaging tools. Dozer, Commons Beanutils, XStream, XMLBeans, Hibernate, JPA, MVC frameworks, etc..etc.. To serialize/unserialize the data, just checkout `java.io.Serializable` and so on.
BalusC