আমি কীভাবে জেনেরিক টাইপ টি এর ক্লাস উদাহরণ পেতে পারি?


699

আমার জেনেরিক ক্লাস আছে Foo<T>,। একটি পদ্ধতিতে Foo, আমি শ্রেণীর উদাহরণ টাইপ পেতে চাই T, তবে আমি কেবল কল করতে পারি না T.class

এটি ব্যবহার করে চারপাশে যাওয়ার পছন্দের উপায় কী T.class?


2
এই প্রশ্নের উত্তর চেষ্টা করুন। আমি এটির অনুরূপ বলে মনে করি। stackoverflow.com/questions/1942644/…
এমিল



1
import com.fasterxml.jackson.core.type.TypeReference; new TypeReference<T>(){}
বোগদান শুলগা

উত্তর:


567

সংক্ষিপ্ত উত্তরটি হ'ল, জাভাতে রানটাইম ধরণের জেনেরিক ধরণের পরামিতিগুলি খুঁজে বের করার কোনও উপায় নেই। আমি আরও বিশদে জাভা টিউটোরিয়ালে টাইপ মোছা সম্পর্কে অধ্যায়টি পড়ার পরামর্শ দিচ্ছি ।

এর একটি জনপ্রিয় সমাধান হ'ল Classজেনেরিক টাইপের কনস্ট্রাক্টরের মধ্যে টাইপ প্যারামিটারের পাস করা, যেমন

class Foo<T> {
    final Class<T> typeParameterClass;

    public Foo(Class<T> typeParameterClass) {
        this.typeParameterClass = typeParameterClass;
    }

    public void bar() {
        // you can access the typeParameterClass here and do whatever you like
    }
}

73
এই উত্তরটি একটি বৈধ সমাধান সরবরাহ করে তবে রানটাইমের সময় জেনেরিক ধরণের কোনও উপায় খুঁজে পাওয়ার কোনও উপায় নেই তা বলা সঠিক নয়। এটিতে দেখা যায় টাইপ ইরেজোর কম্বল মুছে যাওয়ার চেয়ে অনেক জটিল। আমার উত্তর আপনাকে দেখায় কিভাবে ক্লাসগুলি জেনেরিক ধরণের পাওয়া যায়।
বেন থারলি

3
@ বেনথর্লি ঝরঝরে কৌশল, তবে যতদূর আমি দেখতে পাচ্ছি এটির ব্যবহারের জন্য যদি জেনেরিক সুপার টাইপ না থাকে তবেই এটি কাজ করে। আমার উদাহরণস্বরূপ, আপনি ফু <T> তে টিয়ের ধরণটি পুনরুদ্ধার করতে পারবেন না।
Zsolt Török

@ ওয়েবেজকি না, আপনার উচিত হবে না। বরাদ্দ করা typeParameterClassকন্সট্রাকটর একটি ডিফল্ট নিয়োগ ছাড়া পুরোপুরি জরিমানা। এটি দ্বিতীয়বার সেট করার দরকার নেই।
অ্যাডোওরথ

এটি মাথায় আসে এমন প্রথম সমাধান, তবে কখনও কখনও এটি আপনি নয় যারা অবজেক্ট তৈরি / সূচনা করবেন। সুতরাং আপনি কনস্ট্রাক্টর ব্যবহার করতে পারবেন না। যেমন ডাটাবেস থেকে জেপিএ সত্তাগুলি পুনরুদ্ধার করার সময়।
পরমবীর সিং কারওয়াল

233

আমি ক্লাসপথে অতিরিক্ত নির্ভরতা যুক্ত না করে নিজেই এটি করার উপায় খুঁজছিলাম। কিছু তদন্তের পরে আমি দেখতে পেয়েছি যে যতক্ষণ আপনার জেনেরিক সুপারটাইপ থাকে ততক্ষণ এটি সম্ভব। এটি আমার পক্ষে ঠিক ছিল কারণ আমি জেনেরিক স্তর সুপারটাইপের সাথে ডিএও স্তর নিয়ে কাজ করছিলাম। যদি এটি আপনার দৃশ্যের সাথে মানানসই হয় তবে এটি আইএমএইচওর নিকটতম পদ্ধতির।

বেশিরভাগ জেনেরিকের ক্ষেত্রে আমি যে ধরণের ক্ষেত্রে এসেছি সেগুলির List<T>ব্যবহার একরকম জেনেরিক সুপার টাইপের উদাহরণস্বরূপ ArrayList<T>বা এর GenericDAO<T>জন্য DAO<T>ইত্যাদি etc.

খাঁটি জাভা সমাধান

জাভাতে রানটাইমের সময় জেনেরিক ধরণের অ্যাক্সেস নিবন্ধটি ব্যাখ্যা করে যে আপনি খাঁটি জাভা ব্যবহার করে কীভাবে এটি করতে পারেন।

@SuppressWarnings("unchecked")
public GenericJpaDao() {
  this.entityBeanType = ((Class) ((ParameterizedType) getClass()
      .getGenericSuperclass()).getActualTypeArguments()[0]);
}

বসন্ত সমাধান

আমার প্রকল্পটি স্প্রিং ব্যবহার করছিল যা আরও ভাল কারণ স্প্রিংয়ের ধরণটি সন্ধানের জন্য কার্যকর উপযোগী পদ্ধতি রয়েছে। এটি আমার নিকটতম দেখতে সবচেয়ে ভাল পন্থা। আমার ধারণা আপনি যদি বসন্ত ব্যবহার না করেন আপনি নিজের ইউটিলিটি পদ্ধতি লিখতে পারেন।

import org.springframework.core.GenericTypeResolver;

public abstract class AbstractHibernateDao<T extends DomainObject> implements DataAccessObject<T>
{

    @Autowired
    private SessionFactory sessionFactory;

    private final Class<T> genericType;

    private final String RECORD_COUNT_HQL;
    private final String FIND_ALL_HQL;

    @SuppressWarnings("unchecked")
    public AbstractHibernateDao()
    {
        this.genericType = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(), AbstractHibernateDao.class);
        this.RECORD_COUNT_HQL = "select count(*) from " + this.genericType.getName();
        this.FIND_ALL_HQL = "from " + this.genericType.getName() + " t ";
    }

1
দয়া করে সমাধানটি টাইপআর্গুমেন্ট আর্গুমেন্টের অর্থ স্পষ্ট করুন
gstackoverflow

getClass () হল java.lang.Object এর একটি পদ্ধতি যা রানটাইমের সময় নির্দিষ্ট অবজেক্টের শ্রেণি ফিরিয়ে দেবে, এটি সেই বস্তু যা আপনি ধরণের সমাধান করতে চান। অ্যাবস্ট্রাক্ট হাইবারনেটডাও.ক্লাস হল জেনেরিক টাইপ শ্রেণীর শ্রেণিবিন্যাসের বেস ক্লাস বা সুপারক্লাসের নাম মাত্র। আমদানির বিবৃতি অন্তর্ভুক্ত করা হয়েছে যাতে আপনার ডক্স সহজেই খুঁজে পেতে এবং নিজেকে চেক করতে সক্ষম হওয়া উচিত। এই পৃষ্ঠাটি ডক্স.স্প্রিং.আইও
বেন

সংস্করণ ৪.৩ . higher এবং এর চেয়েও উচ্চতর সহ বসন্ত সমাধান কী । এটি বসন্ত ৪.৩..6 এর সাথে কাজ করে না।
এর্লান

1
"খাঁটি জাভা সমাধান" -এর লিঙ্কটি নষ্ট হয়ে গেছে, এটি এখন ব্লগ.এক্সিয়া
নিক ব্রিন

1
@ অ্যালিকেলজিন-কিলাকা এটি বসন্ত শ্রেণীর জেনেরিক টাইপ রিসোলভার ব্যবহার করে নির্মাতায় প্রাথমিক হয়।
বেন থারলি

103

একটি ছোট ফাঁক আছে: আপনি যদি নিজের Fooশ্রেণিকে বিমূর্ত হিসাবে সংজ্ঞায়িত করেন । এর অর্থ হ'ল আপনাকে ক্লাসটি ইনস্ট্যান্ট করতে হবে যেমন:

Foo<MyType> myFoo = new Foo<MyType>(){};

(শেষে ডাবল ধনুর্বন্ধনী নোট করুন।)

এখন আপনি Tরানটাইমের সময়টি পুনরুদ্ধার করতে পারেন :

Type mySuperclass = myFoo.getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];

তবে নোট করুন যে mySuperclassক্লাস সংজ্ঞাটির জন্য সুপারক্লাস হতে হবে যার জন্য চূড়ান্ত প্রকারটি সংজ্ঞায়িত করা হয় T

এটি খুব মার্জিতও নয়, তবে আপনাকে সিদ্ধান্ত নিতে হবে যে আপনি পছন্দ করেন new Foo<MyType>(){}বা new Foo<MyType>(MyType.class);আপনার কোডে।


উদাহরণ স্বরূপ:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.NoSuchElementException;

/**
 * Captures and silently ignores stack exceptions upon popping.
 */
public abstract class SilentStack<E> extends ArrayDeque<E> {
  public E pop() {
    try {
      return super.pop();
    }
    catch( NoSuchElementException nsee ) {
      return create();
    }
  }

  public E create() {
    try {
      Type sooper = getClass().getGenericSuperclass();
      Type t = ((ParameterizedType)sooper).getActualTypeArguments()[ 0 ];

      return (E)(Class.forName( t.toString() ).newInstance());
    }
    catch( Exception e ) {
      return null;
    }
  }
}

তারপর:

public class Main {
    // Note the braces...
    private Deque<String> stack = new SilentStack<String>(){};

    public static void main( String args[] ) {
      // Returns a new instance of String.
      String s = stack.pop();
      System.out.printf( "s = '%s'\n", s );
    }
}

5
এটি সহজেই এখানে সেরা উত্তর! এছাড়াও, এটির মূল্য কী তা জন্য, গুগল গুইস এর সাথে বাধ্যতামূলক ক্লাসগুলির জন্য ব্যবহার করে এমন কৌশলTypeLiteral
এটিজি

14
মনে রাখবেন যে প্রতিবার অবজেক্ট নির্মাণের এই পদ্ধতিটি ব্যবহৃত হয়, একটি নতুন বেনাম শ্রেণি তৈরি হয়। অন্য কথায়, দুটি অবজেক্ট aএবং bএইভাবে তৈরি করা উভয়ই একই বর্গ বাড়িয়ে তুলবে তবে অভিন্ন উদাহরণ শ্রেণি নেই। a.getClass() != b.getClass()
মার্টিন সেরানো

3
একটি দৃশ্যে এটি কাজ করে না। যদি অজ্ঞাত শ্রেণীর চেয়ে ক্লাস ইনস্ট্যানটিটিং না করা হয় তবে অজ্ঞাত শ্রেণীর চেয়ে সিরিয়ালিজেবলের মতো ফু'র যদি কোনও ইন্টারফেস প্রয়োগ করা উচিত। আমি একটি সিরিয়ালযোগ্যযোগ্য ফ্যাক্টরি ক্লাস তৈরি করে এটি চেষ্টা করার চেষ্টা করেছি যা ফু থেকে প্রাপ্ত বেনাম শ্রেণি তৈরি করে, তবে কোনও কারণে, getActualTypeArguments প্রকৃত শ্রেণির পরিবর্তে জেনেরিক ধরণটি দেয়। উদাহরণস্বরূপ: (নতুন ফুফ্যাক্টরি <আমার টাইপ> ())। তৈরিফু ()
লিওর চাগা

38

স্ট্যান্ডার্ড অ্যাপ্রোচ / ওয়ার্কআরাউন্ড / সলিউশন হ'ল classকনস্ট্রাক্টরগুলিতে কোনও বস্তু যুক্ত করা, যেমন:

 public class Foo<T> {

    private Class<T> type;
    public Foo(Class<T> type) {
      this.type = type;
    }

    public Class<T> getType() {
      return type;
    }

    public T newInstance() {
      return type.newInstance();
    }
 }

1
তবে দেখে মনে হচ্ছে এটি ব্যবহারকারীর পক্ষে প্রকৃত ব্যবহারের কোনও উপায় নয়?
আলফ্রেড হুয়াং

@ অ্যালফ্রেডহুয়াং এর চারপাশের কাজটি ক্লাসের জন্য একটি শিম তৈরি করা হবে যা এটি করে এবং অটোয়ারিংয়ের উপর নির্ভর করে না।
কালেব ২৮

20

কল্পনা করুন আপনার কাছে একটি বিমূর্ত সুপারক্লাস রয়েছে যা জেনেরিক:

public abstract class Foo<? extends T> {}

এবং তারপরে আপনার একটি দ্বিতীয় শ্রেণি রয়েছে যা জেনেরিক বারের সাথে ফু বাড়িয়ে দেয় যা টি প্রসারিত করে:

public class Second extends Foo<Bar> {}

আপনি (বার্ট ব্রুইনোঘে উত্তর থেকে) Bar.classনির্বাচন করে Typeএবং Classউদাহরণটি ব্যবহার করে অনুমান করে ফু ফু ক্লাসে ক্লাস পেতে পারেন :

Type mySuperclass = myFoo.getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
//Parse it as String
String className = tType.toString().split(" ")[1];
Class clazz = Class.forName(className);

আপনাকে লক্ষ্য রাখতে হবে যে এই অপারেশনটি আদর্শ নয়, সুতরাং এটির একাধিক গণনা এড়াতে গণনা করা মানটি ক্যাশে করা ভাল ধারণা। সাধারণ ব্যবহারগুলির মধ্যে একটি হল জেনেরিক ডিএও প্রয়োগকরণ implementation

চূড়ান্ত বাস্তবায়ন:

public abstract class Foo<T> {

    private Class<T> inferedClass;

    public Class<T> getGenericClass(){
        if(inferedClass == null){
            Type mySuperclass = getClass().getGenericSuperclass();
            Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
            String className = tType.toString().split(" ")[1];
            inferedClass = Class.forName(className);
        }
        return inferedClass;
    }
}

অন্য ফাংশনে বা বার ক্লাস থেকে ফু ক্লাস থেকে আহবান করা হলে প্রাপ্ত মান বারক্লাস হয়।


1
toString().split(" ")[1]সমস্যাটি ছিল, এড়িয়ে যান"class "
ইগনিট কোডার্স

16

এখানে একটি কার্যক্ষম সমাধান:

@SuppressWarnings("unchecked")
private Class<T> getGenericTypeClass() {
    try {
        String className = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].getTypeName();
        Class<?> clazz = Class.forName(className);
        return (Class<T>) clazz;
    } catch (Exception e) {
        throw new IllegalStateException("Class is not parametrized with generic type!!! Please use extends <> ");
    }
} 

দ্রষ্টব্য: কেবল সুপারক্লাস হিসাবে ব্যবহার করা যেতে পারে

  1. টাইপ করা শ্রেণীর ( Child extends Generic<Integer>) দিয়ে প্রসারিত করতে হবে

অথবা

  1. বেনামে বাস্তবায়ন হিসাবে তৈরি করতে হবে ( new Generic<Integer>() {};)

3
getTypeName কল স্ট্রিংয়ে, তাই .getActualTypeArguments () [0] .toString () দ্বারা প্রতিস্থাপন করা যেতে পারে;
ইয়ারোস্লাভ কোব্বাস 20'16


9

অন্যরা প্রস্তাবিত শ্রেণীর চেয়ে আরও ভাল রুট হ'ল কোনও বস্তুটি পাস করা যা ক্লাসটি দিয়ে আপনি যা করতে পারেন তা করতে পারে, উদাহরণস্বরূপ, একটি নতুন উদাহরণ তৈরি করুন।

interface Factory<T> {
  T apply();
}

<T> void List<T> make10(Factory<T> factory) {
  List<T> result = new ArrayList<T>();
  for (int a = 0; a < 10; a++)
    result.add(factory.apply());
  return result;
}

class FooFactory<T> implements Factory<Foo<T>> {
  public Foo<T> apply() {
    return new Foo<T>();
  }
}

List<Foo<Integer>> foos = make10(new FooFactory<Integer>());

@ রিকি ক্লার্কসন: আমি দেখতে পাচ্ছি না যে এই কারখানায় কীভাবে প্যারামেট্রাইজড ফুস ফিরিয়ে দেওয়া উচিত। আপনি দয়া করে ব্যাখ্যা করতে পারেন কীভাবে আপনি এর মাধ্যমে ফু <T> পান? এটা আমার কাছে মনে হচ্ছে এটি কেবল অপ্রতিদ্বন্দ্বী ফু দেয়। মেক 10 তে টি কি এখানে কেবল ফু ফু নেই?
ইবি 84

@ আইব 84 আমি কোডটি ঠিক করেছি; আমি মনে করি মনে হয় যে আমি যখন উত্তরটি মূলত লিখেছিলাম তখন ফু প্যারামিটারাইজড ছিল।
রিকি ক্লার্কসন

9

আমার একটি বিমূর্ত জেনেরিক ক্লাসে এই সমস্যা ছিল। এই বিশেষ ক্ষেত্রে, সমাধানটি সহজ:

abstract class Foo<T> {
    abstract Class<T> getTClass();
    //...
}

এবং পরে উদ্ভূত শ্রেণিতে:

class Bar extends Foo<Whatever> {
    @Override
    Class<T> getTClass() {
        return Whatever.class;
    }
}

হ্যাঁ এটি হ'ল, তবে আমি খুব কম ন্যূনতম যা এই ক্লাসটি বাড়ানোর সময় করা দরকার তা ছেড়ে যেতে চাই। Droidpl এর উত্তরটি দেখুন
সিং

5

এই সমস্যাটির জন্য আমার একটি (কুরুচিপূর্ণ তবে কার্যকর) সমাধান রয়েছে, যা আমি সম্প্রতি ব্যবহার করেছি:

import java.lang.reflect.TypeVariable;


public static <T> Class<T> getGenericClass()
{
    __<T> ins = new __<T>();
    TypeVariable<?>[] cls = ins.getClass().getTypeParameters(); 

    return (Class<T>)cls[0].getClass();
}

private final class __<T> // generic helper class which does only provide type information
{
    private __()
    {
    }
}

5

এটা সম্ভব:

class Foo<T> {
  Class<T> clazz = (Class<T>) DAOUtil.getTypeArguments(Foo.class, this.getClass()).get(0);
}

হাইবারনেট-জেনেরিক-দাও / ব্লব / মাস্টার / দাও / এসসিআর / মেইন / জাভা / কম / গুগলকোড / জেনেরিকদাও / দাও / ডিএউটিল.জাভা থেকে আপনার দুটি ফাংশন প্রয়োজন ।

আরও ব্যাখ্যার জন্য, জেনেরিকগুলি প্রতিবিম্বিত করা দেখুন ।


3

আমি এটি করার একটি সাধারণ এবং সহজ উপায় পেয়েছি। আমার ক্লাসে আমি এমন একটি পদ্ধতি তৈরি করেছি যা শ্রেণীর সংজ্ঞায় তার অবস্থান অনুযায়ী জেনেরিক টাইপ প্রদান করে। আসুন এর মতো শ্রেণির সংজ্ঞাটি ধরে নেওয়া যাক:

public class MyClass<A, B, C> {

}

প্রকারগুলি ধরে রাখতে কিছু বৈশিষ্ট্য তৈরি করা যাক:

public class MyClass<A, B, C> {

    private Class<A> aType;

    private Class<B> bType;

    private Class<C> cType;

// Getters and setters (not necessary if you are going to use them internally)

    } 

তারপরে আপনি একটি জেনেরিক পদ্ধতি তৈরি করতে পারেন যা জেনেরিক সংজ্ঞাটির সূচকের ভিত্তিতে প্রকারটি প্রদান করে:

   /**
     * Returns a {@link Type} object to identify generic types
     * @return type
     */
    private Type getGenericClassType(int index) {
        // To make it use generics without supplying the class type
        Type type = getClass().getGenericSuperclass();

        while (!(type instanceof ParameterizedType)) {
            if (type instanceof ParameterizedType) {
                type = ((Class<?>) ((ParameterizedType) type).getRawType()).getGenericSuperclass();
            } else {
                type = ((Class<?>) type).getGenericSuperclass();
            }
        }

        return ((ParameterizedType) type).getActualTypeArguments()[index];
    }

অবশেষে, কনস্ট্রাক্টরটিতে কেবল পদ্ধতিটি কল করুন এবং প্রতিটি ধরণের জন্য সূচকটি প্রেরণ করুন। সম্পূর্ণ কোডটি দেখতে হবে:

public class MyClass<A, B, C> {

    private Class<A> aType;

    private Class<B> bType;

    private Class<C> cType;


    public MyClass() {
      this.aType = (Class<A>) getGenericClassType(0);
      this.bType = (Class<B>) getGenericClassType(1);
      this.cType = (Class<C>) getGenericClassType(2);
    }

   /**
     * Returns a {@link Type} object to identify generic types
     * @return type
     */
    private Type getGenericClassType(int index) {

        Type type = getClass().getGenericSuperclass();

        while (!(type instanceof ParameterizedType)) {
            if (type instanceof ParameterizedType) {
                type = ((Class<?>) ((ParameterizedType) type).getRawType()).getGenericSuperclass();
            } else {
                type = ((Class<?>) type).getGenericSuperclass();
            }
        }

        return ((ParameterizedType) type).getActualTypeArguments()[index];
    }
}

2

অন্যান্য ParameterizedTypeউত্তরে যেমন ব্যাখ্যা করা হয়েছে, এই পদ্ধতির ব্যবহার করতে আপনাকে ক্লাসটি প্রসারিত করতে হবে, তবে এটি সম্পূর্ণ নতুন শ্রেণি তৈরি করার জন্য অতিরিক্ত কাজের মতো মনে হচ্ছে যা এটি প্রসারিত করে ...

সুতরাং, ক্লাসটিকে বিমূর্ত করে তোলে এটি আপনাকে প্রসারিত করতে বাধ্য করে, এইভাবে সাবক্লাসিংয়ের প্রয়োজনীয়তাকে সন্তুষ্ট করে। (লম্বকের @ গেটার ব্যবহার করে)।

@Getter
public abstract class ConfigurationDefinition<T> {

    private Class<T> type;
    ...

    public ConfigurationDefinition(...) {
        this.type = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        ...
    }
}

এখন একটি নতুন শ্রেণি সংজ্ঞায়িত না করে এটি প্রসারিত করা। (শেষের দিকে} Note নোট করুন ... প্রসারিত, তবে কোনও কিছু ওভাররাইট করবেন না - আপনি না চাইলে)।

private ConfigurationDefinition<String> myConfigA = new ConfigurationDefinition<String>(...){};
private ConfigurationDefinition<File> myConfigB = new ConfigurationDefinition<File>(...){};
...
Class stringType = myConfigA.getType();
Class fileType = myConfigB.getType();

2

আমি ধরে নিলাম যেহেতু আপনার একটি জেনেরিক ক্লাস রয়েছে তাই আপনার মতো চলক থাকতে পারে:

private T t;

(এই ভেরিয়েবলটি কনস্ট্রাক্টরের কাছে একটি মান নেওয়া দরকার)

সেক্ষেত্রে আপনি কেবল নিম্নলিখিত পদ্ধতিটি তৈরি করতে পারেন:

Class<T> getClassOfInstance()
{
    return (Class<T>) t.getClass();
}

আশা করি এটা সাহায্য করবে!


1
   public <T> T yourMethodSignature(Class<T> type) {

        // get some object and check the type match the given type
        Object result = ...            

        if (type.isAssignableFrom(result.getClass())) {
            return (T)result;
        } else {
            // handle the error
        }
   }

1

আপনি যদি জেনেরিকগুলি ব্যবহার করে এমন কোনও শ্রেণি / ইন্টারফেসটি প্রসারিত বা বাস্তবায়ন করে থাকেন তবে আপনি কোনও জেনারিক ধরণের প্যারেন্ট ক্লাস / ইন্টারফেস পেতে পারেন, কোনও বিদ্যমান শ্রেণি / ইন্টারফেসকে কোনও পরিবর্তন না করেই।

তিনটি সম্ভাবনা থাকতে পারে,

কেস 1 যখন আপনার ক্লাস জেনারিক্স ব্যবহার করে এমন একটি ক্লাস প্রসারিত করছে

public class TestGenerics {
    public static void main(String[] args) {
        Type type = TestMySuperGenericType.class.getGenericSuperclass();
        Type[] gTypes = ((ParameterizedType)type).getActualTypeArguments();
        for(Type gType : gTypes){
            System.out.println("Generic type:"+gType.toString());
        }
    }
}

class GenericClass<T> {
    public void print(T obj){};
}

class TestMySuperGenericType extends GenericClass<Integer> {
}

কেস 2 যখন আপনার শ্রেণি জেনারিক্স ব্যবহার করছে এমন একটি ইন্টারফেস কার্যকর করছে

public class TestGenerics {
    public static void main(String[] args) {
        Type[] interfaces = TestMySuperGenericType.class.getGenericInterfaces();
        for(Type type : interfaces){
            Type[] gTypes = ((ParameterizedType)type).getActualTypeArguments();
            for(Type gType : gTypes){
                System.out.println("Generic type:"+gType.toString());
            }
        }
    }
}

interface GenericClass<T> {
    public void print(T obj);
}

class TestMySuperGenericType implements GenericClass<Integer> {
    public void print(Integer obj){}
}

কেস 3 যখন আপনার ইন্টারফেস জেনারিক্স ব্যবহার করে এমন একটি ইন্টারফেস প্রসারিত করে is

public class TestGenerics {
    public static void main(String[] args) {
        Type[] interfaces = TestMySuperGenericType.class.getGenericInterfaces();
        for(Type type : interfaces){
            Type[] gTypes = ((ParameterizedType)type).getActualTypeArguments();
            for(Type gType : gTypes){
                System.out.println("Generic type:"+gType.toString());
            }
        }
    }
}

interface GenericClass<T> {
    public void print(T obj);
}

interface TestMySuperGenericType extends GenericClass<Integer> {
}

1

এটি বেশ সোজা এগিয়ে। আপনার যদি একই শ্রেণীর মধ্যে থেকে প্রয়োজন:

Class clazz = this.getClass();
ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass();
try {
        Class typeClass = Class.forName( parameterizedType.getActualTypeArguments()[0].getTypeName() );
        // You have the instance of type 'T' in typeClass variable

        System.out.println( "Class instance name: "+  typeClass.getName() );
    } catch (ClassNotFoundException e) {
        System.out.println( "ClassNotFound!! Something wrong! "+ e.getMessage() );
    }

0

প্রকৃতপক্ষে, আমি মনে করি আপনার টাইপ টি এর শ্রেণিতে আপনার একটি ক্ষেত্র রয়েছে T যদি টি টাইপের কোনও ক্ষেত্র নেই, তবে জেনেরিক প্রকারের কী লাভ? সুতরাং, আপনি কেবলমাত্র সেই ক্ষেত্রে একটি উদাহরণ করতে পারেন।

আমার ক্ষেত্রে, আমি একটি

<T> আইটেম তালিকা;
আমার ক্লাসে, এবং আমি পরীক্ষা করে দেখি যে শ্রেণীর ধরণটি "লোকাল" দ্বারা আছে কিনা

যদি (আইটেম.জেট (0) উদাহরণ স্থানীয়ভাবে) ...

অবশ্যই, সম্ভাব্য শ্রেণীর মোট সংখ্যা সীমাবদ্ধ থাকলে এটি কেবলমাত্র কাজ করে।


4
আইটেম.আইপিটি () সত্য হলে আমি কী করব?
বিশৃঙ্খল 3 কিলিব্রিয়াম

0

এই প্রশ্নটি পুরানো, তবে এখন গুগল ব্যবহারের মধ্যে সেরা Gson

কাস্টম পেতে একটি উদাহরণ viewModel

Class<CustomViewModel<String>> clazz = new GenericClass<CustomViewModel<String>>().getRawType();
CustomViewModel<String> viewModel = viewModelProvider.get(clazz);

জেনেরিক টাইপ ক্লাস

class GenericClass<T>(private val rawType: Class<*>) {

    constructor():this(`$Gson$Types`.getRawType(object : TypeToken<T>() {}.getType()))

    fun getRawType(): Class<T> {
        return rawType as Class<T>
    }
}

0

আমি জেনারিক্স ব্যবহার করে এমন একটি পদ্ধতিতে টি সি ক্লাস পাস করতে চেয়েছিলাম

পদ্ধতিটি পঠিত ফাইলটি পূর্ণপথ সহ ফাইলের নাম দ্বারা নির্দিষ্ট একটি .csv ফাইল পড়ে। বিভিন্ন বিষয়বস্তু সহ সিএসভি ফাইল থাকতে পারে তাই আমাকে মডেল ফাইল শ্রেণিটি পাস করতে হবে যাতে আমি উপযুক্ত জিনিসগুলি পেতে পারি। যেহেতু এটি সিএসভি ফাইলটি পড়ছে আমি জেনেরিক উপায়ে করতে চাইছিলাম। কোনও কারণে বা উপরের সমাধানগুলির কোনওটিই আমার পক্ষে কার্যকর হয়নি। Class<? extends T> typeএটি কাজ করতে আমার প্রয়োজন । আমি সিএসভি ফাইলগুলি বিশ্লেষণের জন্য ওপেনসিভি লাইব্রেরি ব্যবহার করি।

private <T>List<T> readFile(String fileName, Class<? extends T> type) {

    List<T> dataList = new ArrayList<T>();
    try {
        File file = new File(fileName);

        Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        Reader headerReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));

        CSVReader csvReader = new CSVReader(headerReader);
        // create csv bean reader
        CsvToBean<T> csvToBean = new CsvToBeanBuilder(reader)
                .withType(type)
                .withIgnoreLeadingWhiteSpace(true)
                .build();

        dataList = csvToBean.parse();
    }
    catch (Exception ex) {
        logger.error("Error: ", ex);
    }

    return dataList;
}

এভাবেই রিডফিল পদ্ধতিটি বলা হয়

List<RigSurfaceCSV> rigSurfaceCSVDataList = readSurfaceFile(surfaceFileName, RigSurfaceCSV.class);

-4

আমি এর জন্য কঠোর ব্যবহার করছি:

class MyClass extends Foo<T> {
....
}

MyClass myClassInstance = MyClass.class.newInstance();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.