Results 1 to 11 of 11
Like Tree1Likes
  • 1 Post By sunde887

Thread: Type parameter

  1. #1
    Pojahn_M's Avatar
    Pojahn_M is offline Senior Member
    Join Date
    Mar 2011
    Location
    Sweden
    Posts
    197
    Rep Power
    4

    Default Type parameter

    Well, this is the first time I my own class using type parameter.
    This definition class is like StringTokenizer, but instead of using a delimiter, it uses offsets(index).
    I am having some compile error, I dont know how to fix.

    Java Code:
    package pjjava.misc;
    
    import java.util.*;
    
    public class TokenOffset<T extends String, StringBuilder, StringBuffer> implements Cloneable
    {
    	private T line;
    	private int offset;
    	private int sOffset;
    	private int eOffset;
    
    	public TokenOffset ()
    	{
    		line =  null;
    		offset = 0;
    		sOffset = 0;
    		eOffset = 0;
    	}
    
    	public TokenOffset (T line, int offset)
    	{
    		this.line = new T (line);
    		this.offset = offset;
    		sOffset = 0;
    		eOffset = 0;
    	}
    
    	public void setLine (T line)
    	{
    		this.line = new T (line);
    	}
    
    	public void setTokenLenth (int offset)
    	{
    		this.offset = offset;
    	}
    
    	public void resetCounter ()
    	{
    		sOffset = 0;
    		eOffset = 0;
    	}
    
    	public void nextPosition ()
    	{
    		if (eOffset == 0)
    		{
    			sOffset = 0;
    			eOffset = offset;
    		}
    
    		else
    		{
    			sOffset += offset;
    			eOffset += offset;
    		}
    	}
    
    	public String getNext ()
    	{
    		this.nextPosition ();
    
    		return line.substring (sOffset, eOffset);
    	}
    
    	public boolean hasNext ()
    	{
    		boolean b = false;
    
    		if (eOffset < line.length ())
    			b = true;
    
    		return b;
    	}
    
    	public boolean equals (Object obj)
    	{
    		boolean equals = false;
    
    		if (obj instanceof TokenOffset)
    		{
    			TokenOffset to = (TokenOffset) obj;
    			equals = this.line.equals(to.line) && this.offset == to.offset;
    		}
    
    		return equals;
    	}
    
    	public T clone ()
    	{
    		T obj = null;
    
    		try
    		{
    			obj = (T) super.clone ();
    		}
    		catch (CloneNotSupportedException e)
    		{
    		}
    
    		return obj;
    	}
    
    	public String toString ()
    	{
    		return new T (line);
    	}
    }
    Java Code:
    C:\Program\Java\jdk1.7.0\jre\classes\pjjava\misc\TokenOffset.java:22: error: unexpected type
    		this.line = new T (line);
    		                ^
      required: class
      found:    type parameter T
      where T is a type-variable:
        T extends String declared in class TokenOffset
    C:\Program\Java\jdk1.7.0\jre\classes\pjjava\misc\TokenOffset.java:30: error: unexpected type
    		this.line = new T (line);
    		                ^
      required: class
      found:    type parameter T
      where T is a type-variable:
        T extends String declared in class TokenOffset
    C:\Program\Java\jdk1.7.0\jre\classes\pjjava\misc\TokenOffset.java:106: error: unexpected type
    		return new T (line);
    		           ^
      required: class
      found:    type parameter T
      where T is a type-variable:
        T extends String declared in class TokenOffset
    Note: C:\Program\Java\jdk1.7.0\jre\classes\pjjava\misc\TokenOffset.java uses unchecked or unsafe operations.
    Note: Recompile with -Xlint:unchecked for details.
    3 errors
    
    Tool completed with exit code 1
    this.line = new T (line);
    Why does this give compile error? I am using new keyword because I dont want a simple reference copy(I want a new object).

    Also this mean <T extends String, StringBuilder, StringBuffer>, when I create an object of TokenOffset, the type parameter must be either a String, StringBuilder or StringBuffer, right?

  2. #2
    Tolls is online now Moderator
    Join Date
    Apr 2009
    Posts
    11,824
    Rep Power
    19

    Default Re: Type parameter

    I'm not sure the compiler knows enough about the classes that type can extend in order to determine whether a particular new would be allowed (in most cases it wouldn't) so I suspect it's simply not allowed.

  3. #3
    sunde887's Avatar
    sunde887 is offline Moderator
    Join Date
    Jan 2011
    Location
    Richmond, Virginia
    Posts
    3,069
    Blog Entries
    3
    Rep Power
    8

    Default Re: Type parameter

    Instead of doing
    Java Code:
    line = new T(line);
    You will probably want to do
    Java Code:
    this.line = line;
    Just assign the passed in parameter to the instance variable. As tolls mentioned, the compiler doesn't know what type T is. So it can't be sure it has a constructor which takes an object of type T. You should also check out this interface: CharSequence (Java Platform SE 6) - rather than extending string, stringbuilder, etc, just having the type extend what they all implement would probably be helpful.
    Fubarable likes this.

  4. #4
    Pojahn_M's Avatar
    Pojahn_M is offline Senior Member
    Join Date
    Mar 2011
    Location
    Sweden
    Posts
    197
    Rep Power
    4

    Default Re: Type parameter

    I will start on interface chapter soon, until then, I put this class on hold.

    But an other thing
    Quote Originally Posted by Pojahn_M View Post
    public class TokenOffse<T extends String, StringBuilder, StringBuffer>
    This was not at all as I thought it was.
    When I try to create an object of this class, like this:
    TokenOffset<String> to = new TokenOffset<String> ("hello", 1);

    I get compile error like this:
    D:\ A N N A T \Java\Pojahns.java:16: error: wrong number of type arguments; required 3
    TokenOffset<String> to = new TokenOffset<String> ("hello", 1);


    Apparently, the compiler want it to look like this TokenOffset<String, String, String> to = new TokenOffset<String, String, String> ("hello", 1);

    I completely misunderstood what I read on the internet, and I was positive that it only would required one of the specified types.

  5. #5
    Pojahn_M's Avatar
    Pojahn_M is offline Senior Member
    Join Date
    Mar 2011
    Location
    Sweden
    Posts
    197
    Rep Power
    4

    Default Re: Type parameter

    This is still not really clear to me.
    How can I implant a typeparameter class and avoiding having a simple reference copy?

    This class demonstrate reference copy(unwanted effect).

    Java Code:
    public class testclass<T>
    {
    	private T name;
    
    	public testclass (T name)
    	{
    		this.name = name;
    	}
    
    	public T get ()
    	{
    		return name;
    	}
    
    	public void show ()
    	{
    		System.out.println (name);
    	}
    }
    Java Code:
    public class Pojahns 
    {
        public static void main(String[] args) throws Exception
        {
    		StringBuilder bu = new StringBuilder ("hej");
    		testclass<StringBuilder> tc = new testclass <StringBuilder> (bu);
    		bu = bu.append ("yo");
    		tc.show (); //Object tc is changed, the output will be: hejyo. This is unwanted
        }
    }
    And second question, how can I make a type parameter restricted to specified objects?
    Lets say I limit it to Integer and Long. Then it should be like this testclass<Integer> tc = new testclass <Integer> (); or testclass<Long> tc = new testclass <Long> ();.

  6. #6
    Tolls is online now Moderator
    Join Date
    Apr 2009
    Posts
    11,824
    Rep Power
    19

    Default Re: Type parameter

    Quote Originally Posted by Pojahn_M View Post
    I will start on interface chapter soon, until then, I put this class on hold.

    But an other thing

    This was not at all as I thought it was.
    When I try to create an object of this class, like this:
    TokenOffset<String> to = new TokenOffset<String> ("hello", 1);

    I get compile error like this:
    D:\˜”•„ A N N A T „•”˜\Java\Pojahns.java:16: error: wrong number of type arguments; required 3
    TokenOffset<String> to = new TokenOffset<String> ("hello", 1);


    Apparently, the compiler want it to look like this TokenOffset<String, String, String> to = new TokenOffset<String, String, String> ("hello", 1);

    I completely misunderstood what I read on the internet, and I was positive that it only would required one of the specified types.
    I actually missed this bit, but you can't list an allowed set of classes. You need to find something that relates them to each other.

    In other words, T needs to be a single type (class or set of interfaces). You might want to think about using CharSequence, which is implemented by all three of your classes.

    Quote Originally Posted by Pojahn_M View Post
    This is still not really clear to me.
    How can I implant a typeparameter class and avoiding having a simple reference copy?

    This class demonstrate reference copy(unwanted effect).

    Java Code:
    public class testclass<T>
    {
    	private T name;
    
    	public testclass (T name)
    	{
    		this.name = name;
    	}
    
    	public T get ()
    	{
    		return name;
    	}
    
    	public void show ()
    	{
    		System.out.println (name);
    	}
    }
    Java Code:
    public class Pojahns 
    {
        public static void main(String[] args) throws Exception
        {
    		StringBuilder bu = new StringBuilder ("hej");
    		testclass<StringBuilder> tc = new testclass <StringBuilder> (bu);
    		bu = bu.append ("yo");
    		tc.show (); //Object tc is changed, the output will be: hejyo. This is unwanted
        }
    }
    Unless the object is cloneable you can't easily. Getting the user to provide a copy factory of some sort is one option, but will make the thing slightly clunky. It seems to me you are fighting against Java here a bit. If the user of the generic class only wants to save a copy of their opbject then I would argue it's up to the user to supply a copy.

    Quote Originally Posted by Pojahn_M View Post
    And second question, how can I make a type parameter restricted to specified objects?
    Lets say I limit it to Integer and Long. Then it should be like this testclass<Integer> tc = new testclass <Integer> (); or testclass<Long> tc = new testclass <Long> ();.
    Not sure I understand this question.

  7. #7
    sunde887's Avatar
    sunde887 is offline Moderator
    Join Date
    Jan 2011
    Location
    Richmond, Virginia
    Posts
    3,069
    Blog Entries
    3
    Rep Power
    8

    Default Re: Type parameter

    For the second question, to my knowledge, you can't limit it to just those two classes, you can however limit it so it's only subclasses of class X. Since Long and Integer both share a common super class you can have it only take subclasses of that super class. For example,

    Java Code:
    public class TestClass<T extends Number>{
      ...
    }
    And then you can do
    Java Code:
    TestClass<Integer> x = new TestClass<Integer>();
    TestClass<Long> longtc = new TestClass<Long>();
    To my knowledge you cannot limit it to just float and long.

    The only approach I can think of, which may be bad, and I hope others will correct me if so is to create holder classes for long and float, give them a common superclass and handle it like that.

    Java Code:
    public class MyClass{}
    public class MyLong extends MyClass{
      private Long l;
      public MyLong(Long l){
        this.l = l;
      }
      public MyLong(){}
      public Long getLong(){ 
        return l;
      }
    }
    
    public class MyFloat extends MyClass{
      private Float f;
      public MyFloat(Float f){
        this.f = f;
      }
      public MyFloat(){}
      public Float getFloat(){ return f; }
    }
    
    public class TestClass<T extends MyClass>{
      T lOrF;
      ...
    }
    And now this class will only take classes that extend MyClass. This may not be a good approach, but I'm offering it to you for now, and hopefully someone smarter will come by and tell you whether it's reasonable.

  8. #8
    Pojahn_M's Avatar
    Pojahn_M is offline Senior Member
    Join Date
    Mar 2011
    Location
    Sweden
    Posts
    197
    Rep Power
    4

    Default Re: Type parameter

    thanks guys


    Java Code:
    And now this class will only take classes that extend MyClass. This may not be a good approach, but I'm offering it to you for now, and hopefully someone smarter will come by and tell you whether it's reasonable.
    I will check it out.
    I also got an idea, please comment it.

    Java Code:
    class testclass<T>
    {
    	private T unknownStringType;
    	
    	//Constructor
    	public testclass (T unknownStringType)
    	{
    		if (! (unknownStringType.getClass == String.class || StringBuilder.class || StringBuffer.class) )
    			throw new ClassCastException();
    
    		this.unknownStringType = unknownStringType;
    	}
    ... More code
    }
    This class should limit the type-paramteters to String, StringBuilder and StringBuffer(sure, I could use CharSequence, this is just an example).

  9. #9
    Pojahn_M's Avatar
    Pojahn_M is offline Senior Member
    Join Date
    Mar 2011
    Location
    Sweden
    Posts
    197
    Rep Power
    4

    Default Re: Type parameter

    New question. I have some problems with static methods that use type parameters.
    I am trying to make a method that take a Vector object, and nothing else.
    Java Code:
    public class Pojahns
    {
        public static void main(String[] args) throws Exception
        {
    		Vector<Integer> v = new Vector<Integer> ();
    		v.add (11);
    		v.add (20);
    		v.add (30);
    		printString (v);
    	}
    
    	public static <T extends Vector> void printString (T vector)
    	{
    		Object obj = (T) vector.get (1);
    		System.out.println (obj);
    	}
    }
    This compile, but I get classcastexception: Integer cannot cast Vector

    So how do I make a method that only accept object of Vector(and its subclasses)?

  10. #10
    sunde887's Avatar
    sunde887 is offline Moderator
    Join Date
    Jan 2011
    Location
    Richmond, Virginia
    Posts
    3,069
    Blog Entries
    3
    Rep Power
    8

    Default Re: Type parameter

    T is a vector, so when you cast vector.get(1), you are trying to cast an integer to an item of type T which extends Vector, hence the error.

  11. #11
    Pojahn_M's Avatar
    Pojahn_M is offline Senior Member
    Join Date
    Mar 2011
    Location
    Sweden
    Posts
    197
    Rep Power
    4

    Default Re: Type parameter

    Alright, I am finally understanding type parameters. Just some minor stuff left.

    Java Code:
    public static <T> void copy (List<? super T> dest, List<? extends T> src)
    Can someone explain this line? What is accepted and what is not accepted? An example would also be nice.

Similar Threads

  1. Replies: 4
    Last Post: 08-01-2011, 10:29 AM
  2. Getting the class of a type parameter
    By Muskar in forum Advanced Java
    Replies: 21
    Last Post: 06-04-2011, 03:28 PM
  3. doubt regarding <type parameter>
    By subith86 in forum New To Java
    Replies: 7
    Last Post: 03-01-2011, 03:35 PM
  4. using instanceof to get Object type and parent type?
    By xcallmejudasx in forum New To Java
    Replies: 2
    Last Post: 11-06-2008, 06:24 PM
  5. passing an enum type as a parameter ??!
    By SCS17 in forum New To Java
    Replies: 11
    Last Post: 07-13-2008, 01:44 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •