আমার কেন যত্ন নেওয়া উচিত যে জাভাতে জেনারিকগুলি সংশোধিত হয়নি?


102

সাম্প্রতিককালে আমি একটি সাক্ষাত্কারে এমন প্রশ্ন হিসাবে জিজ্ঞাসা করা প্রশ্নটি প্রকাশ পেয়েছিল যা প্রার্থী জাভা ভাষায় যুক্ত হওয়া চাইবে। এটিকে সাধারণত একটি ব্যথা হিসাবে চিহ্নিত করা হয় যা জাভা জেনারিকসকে সংস্কার করে না তবে যখন ধাক্কা দেওয়া হয়, তখন প্রার্থী আসলে আমাকে বলতে পারেন না যে তিনি সেখানে কী কী জিনিস অর্জন করতে পারতেন they

স্পষ্টতই যেহেতু কাঁচা ধরণের জাভাতে (এবং অনিরাপদ চেকগুলি) অনুমোদিত, তাই জেনেরিকসকে বিকৃত করা এবং এটির List<Integer>(উদাহরণস্বরূপ) আসলে রয়েছে এমনটি দিয়ে শেষ করা সম্ভব String। এগুলি স্পষ্টতই অসম্ভব হিসাবে বর্ণনা করা যেতে পারে টাইপ তথ্যগুলিকে পুনরায় সংশোধন করা; তবে এর চেয়ে আরও বেশি কিছু থাকতে হবে !

লোকেরা কী সত্যিই তারা করতে চাইবে এমন উদাহরণগুলি পোস্ট করতে পারত , কী জেনেরিকগুলি উপলব্ধ ছিল? আমি বোঝাতে চাইছি স্পষ্টতই আপনি Listরানটাইমের সময় একটি ধরণের পেতে পারেন - তবে আপনি এটি দিয়ে কী করবেন?

public <T> void foo(List<T> l) {
   if (l.getGenericType() == Integer.class) {
       //yeah baby! err, what now?

সম্পাদনা : উত্তরগুলির উত্তর হিসাবে এটির একটি দ্রুত আপডেট প্রধানত Classপ্যারামিটার হিসাবে পাস করার প্রয়োজন সম্পর্কে উদ্বিগ্ন বলে মনে হয় (উদাহরণস্বরূপ EnumSet.noneOf(TimeUnit.class))। আমি যেখানে কেবল এটি সম্ভব নয় তার লাইন ধরে আরও কিছু সন্ধান করছিলাম । উদাহরণ স্বরূপ:

List<?> l1 = api.gimmeAList();
List<?> l2 = api.gimmeAnotherList();

if (l1.getGenericType().isAssignableFrom(l2.getGenericType())) {
    l1.addAll(l2); //why on earth would I be doing this anyway?

এর অর্থ কি আপনি রানটাইমে জেনেরিক ধরণের শ্রেণি পেতে পারেন? (যদি তা হয় তবে আমার একটি উদাহরণ আছে!)
জেমস বি

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

2
আরও আকর্ষণীয় প্রশ্ন (আমার কাছে): জাভাতে সি ++ স্টাইল জেনেরিকগুলি প্রয়োগ করতে কি লাগবে? এটি অবশ্যই রানটাইমে করণে সক্ষম বলে মনে হচ্ছে তবে এটি উপস্থিত সমস্ত শ্রেণিবদ্ধকে ভেঙে ফেলবে (কারণ findClass()প্যারামিটারাইজেশন উপেক্ষা করতে হবে, তবে defineClass()পারে নি)। এবং যেমনটি আমরা জানি, সেই শক্তিগুলি যে সামঞ্জস্যতার প্যারামাউন্টকে পিছনে রাখে।
কেডগ্রিগরি

1
আসলে, জাভা খুব সীমাবদ্ধ উপায়ে সংশোধিত জেনেরিক সরবরাহ করে । আমি এই এসও থ্রেডে আরও বিশদ সরবরাহ করি: স্ট্যাকওভারফ্লো
রিচার্ড গোমেস

জাভাওয়ান কীনোট ইঙ্গিত করে যে জাভা 9 reification সমর্থন করবে।
রাঙ্গী কেইন

উত্তর:


81

আমি এই "প্রয়োজনীয়তা "টি যে কয়েকবার এসেছি, সেগুলি শেষ পর্যন্ত এই নির্মাণে ফোটে:

public class Foo<T> {

    private T t;

    public Foo() {
        this.t = new T(); // Help?
    }

}

এটি সি # তে ধরে ধরে কাজ করে যে Tএকটি ডিফল্ট কনস্ট্রাক্টর রয়েছে। এমনকি আপনি রানটাইম টাইপটি দ্বারা typeof(T)এবং কনস্ট্রাক্টরগুলি পেতে পারেন Type.GetConstructor()

সাধারণ জাভা সমাধানটি Class<T>যুক্তি হিসাবে পাস করা হবে ।

public class Foo<T> {

    private T t;

    public Foo(Class<T> cls) throws Exception {
        this.t = cls.newInstance();
    }

}

(এটি অবিচ্ছেদ্যভাবে কন্সট্রাক্টর আর্গুমেন্ট হিসাবে পাস করার প্রয়োজন হয় না, যেমন একটি পদ্ধতি আর্গুমেন্টও জরিমানা, উপরেরটি কেবল একটি উদাহরণ, এছাড়াও try-catch উপরেরটি ব্রেভিটি বাদ দেওয়া হয়)

অন্যান্য সমস্ত জেনেরিক ধরণের নির্মাণের জন্য, প্রকৃত প্রকারটি প্রতিবিম্বের সাহায্যে খুব সহজেই সমাধান করা যায়। নীচের প্রশ্নোত্তর ব্যবহারের কেস এবং সম্ভাবনার চিত্রিত করে:


5
এটি সি # তে উদাহরণস্বরূপ (উদাহরণস্বরূপ) কাজ করে? আপনি কীভাবে জানতে পারবেন যে টিতে একটি ডিফল্ট কনস্ট্রাক্টর রয়েছে?
থমাস জং

4
হ্যাঁ, এটা না। এবং এটি কেবলমাত্র একটি প্রাথমিক উদাহরণ (ধরে নেওয়া যাক যে আমরা জাবাবেইনের সাথে কাজ করি)। পুরো পয়েন্ট যে জাভা সঙ্গে আপনি না বর্গ সময় পেতে পারেন রানটাইম দ্বারা T.classবা T.getClass(), তাই আপনি সব তার ক্ষেত্র, কনস্ট্রাকটর ও পদ্ধতি অ্যাক্সেস করতে পারে যে। এটি নির্মাণকেও অসম্ভব করে তোলে।
বালুসিসি

3
এটি "বড় সমস্যা" হিসাবে আমার কাছে সত্যই দুর্বল বলে মনে হচ্ছে, বিশেষত এটি নির্মাণকারী / প্যারামিটার ইত্যাদির আশেপাশে কিছু ভঙ্গুর প্রতিবিম্বের সাথে একত্রে কার্যকর হতে পারে
অক্সবো_লাক্স

33
এটি সি # তে সংকলন করে যদি আপনি প্রকারটিকে এইরূপে ঘোষণা করেন: পাবলিক ক্লাস ফু <T> যেখানে টি: নতুন ()। যা প্যারামিটারলেস কনস্ট্রাক্টর সহ তাদের বৈধ প্রকারের টি সীমাবদ্ধ করবে।
মার্টিন হ্যারিস

3
@ কলিন আপনি আসলে জাভা বলতে পারেন যে প্রদত্ত জেনেরিক ধরণের একাধিক শ্রেণি বা ইন্টারফেস প্রসারিত করা প্রয়োজন। Docs.oracle.com/javase/tutorial/java/generics/bounded.html এর "একাধিক সীমা " বিভাগটি দেখুন । (অবশ্যই, আপনি এটি বলতে পারবেন না যে অবজেক্টটি একটি নির্দিষ্ট সেটগুলির মধ্যে একটি হবে যা এমন পদ্ধতিগুলি ভাগ করে না যা কোনও ইন্টারফেসে বিমৃত হতে পারে, যা টেমপ্লেট বিশেষীকরণ ব্যবহার করে কিছুটা সি ++ এ প্রয়োগ করা যেতে পারে))
জ্যাব

99

যে জিনিসটি আমাকে সবচেয়ে বেশি দংশিত করে তা হ'ল একাধিক জেনেরিক ধরণের একাধিক প্রেরণের সুবিধা নিতে। নিম্নলিখিতটি সম্ভব নয় এবং অনেক ক্ষেত্রেই এটি সেরা সমাধান হতে পারে:

public void my_method(List<String> input) { ... }
public void my_method(List<Integer> input) { ... }

5
এটি করতে সক্ষম হওয়ার জন্য পুনর্নির্মাণের কোনও প্রয়োজন নেই। সংকলন-সময় ধরণের তথ্য উপলভ্য হলে সংকলনের সময় পদ্ধতি নির্বাচন করা হয়।
টম হাটিন - 18:25

26
@ টম: মুছে ফেলার কারণে এটি সংকলন করে না। উভয় হিসাবে সংকলিত পেতে public void my_method(List input) {}। আমি অবশ্য কখনও এই প্রয়োজনটি পূরণ করতে পারি নি, কেবল কারণ তাদের একই নাম হবে না। যদি তাদের একই নাম থাকে তবে আমি প্রশ্ন করব যদি public <T extends Object> void my_method(List<T> input) {}এটি আরও ভাল ধারণা না হয়।
বালুসি

1
হুঁ, আমি পুরাপুরি প্যারামিটার অভিন্ন নম্বর দিয়ে ওভারলোডিং এড়াতে ঝোঁক হবে, এবং ভালো কিছু পছন্দ করা myStringsMethod(List<String> input)এবং myIntegersMethod(List<Integer> input)এমনকি যদি এই ধরনের একটি ক্ষেত্রে জন্য ওভারলোডিং জাভা সম্ভব ছিল।
ফ্যাবিয়ান স্টেগ

4
@ ফ্যাবিয়ান: যার অর্থ আপনার আলাদা কোড থাকতে হবে <algorithm>এবং সি ++ এ আপনি যে ধরণের সুবিধা পাবেন তা আটকাবেন ।
ডেভিড থর্নলি

আমি বিভ্রান্ত হয়ে পড়েছি, এটি মূলত আমার দ্বিতীয় পয়েন্টের সমান, তবুও আমি এতে 2 টি ডাউনওয়েট পেয়েছি? কেউ কি আমাকে আলোকিত করার চিন্তা করে?
আরএসপি

34

প্রকার সুরক্ষা মাথায় আসে। একটি প্যারাম্যাট্রাইজড ধরণের ডাউন কাস্টিং রিফাইড জেনেরিকগুলি ছাড়াই সর্বদা অনিরাপদ থাকবে:

List<String> myFriends = new ArrayList();
myFriends.add("Alice");
getSession().put("friends", myFriends);
// later, elsewhere
List<Friend> myFriends = (List<Friend>) getSession().get("friends");
myFriends.add(new Friend("Bob")); // works like a charm!
// and so...
List<String> myFriends = (List<String>) getSession().get("friends");
for (String friend : myFriends) print(friend); // ClassCastException, wtf!? 

এছাড়াও, বিমূর্ততা কম ফাঁস হবে - কমপক্ষে যা তাদের টাইপ পরামিতি সম্পর্কে রানটাইম তথ্যে আগ্রহী হতে পারে। আজ, আপনার যদি জেনেরিক প্যারামিটারগুলির একটির ধরণ সম্পর্কে কোনও ধরণের রানটাইম তথ্যের প্রয়োজন হয় তবে আপনাকে এটির Classপাশাপাশি পাস করতে হবে । এইভাবে, আপনার বাহ্যিক ইন্টারফেস আপনার প্রয়োগের উপর নির্ভর করে (আপনি যদি নিজের প্যারামিটারগুলি সম্পর্কে আরটিটিআই ব্যবহার করেন বা না করেন)।


1
হ্যাঁ - আমার ParametrizedListএগুলির চারপাশে একটি উপায় রয়েছে যা আমি উত্স সংগ্রহের পরীক্ষার ধরণগুলিতে ডেটা অনুলিপি করে এমন একটি তৈরি করি । এটি বেশ খানিকটা পছন্দ Collections.checkedListতবে শুরুতে সংগ্রহ সহ সিড করা যায়।
অক্সবো_লাক্স

@ ট্যাকলাইন - ভাল, কয়েকটি বিমূর্ততা কম ফাঁস হবে। আপনার প্রয়োগে যদি মেটাডেটা টাইপ করতে আপনার অ্যাক্সেসের প্রয়োজন হয় তবে বাহ্যিক ইন্টারফেস আপনাকে জানিয়ে দেবে কারণ ক্লায়েন্টদের আপনাকে একটি শ্রেণীর অবজেক্ট পাঠাতে হবে।
gustafc

... এর অর্থ হ'ল সংশোধিত জেনেরিকের সাহায্যে আপনি বাহ্যিক ইন্টারফেস পরিবর্তন না করে T.class.getAnnotation(MyAnnotation.class)( Tযেমন জেনেরিক ধরণের) স্টাফ যুক্ত করতে পারেন ।
gustafc

@ গুস্তাফ্যাক: আপনি যদি ভাবেন যে সি ++ টেমপ্লেটগুলি আপনাকে সম্পূর্ণ ধরণের সুরক্ষা দেয়, তবে এটি পড়ুন: kdgregory.com/index.php?page=java.generics.cpp
kdgregory

@ কেডিগ্রিগরি: আমি কখনই বলিনি যে সি ++ 100% প্রকারের নিরাপদ ছিল - কেবল এই ক্ষয়টি ক্ষয়ক্ষতির প্রকারের সুরক্ষা। আপনি যেমন নিজেকে বলেছিলেন, "সি ++, এটি দেখা যাচ্ছে, এর নিজস্ব ক্ষয়করণের নিজস্ব রূপ রয়েছে যা সি-স্টাইল পয়েন্টার কাস্ট হিসাবে পরিচিত।" তবে জাভা কেবল গতিশীল কাস্ট করে না (পুনরায় ব্যাখ্যা না করে), সুতরাং পুনর্নির্মাণটি টাইপ সিস্টেমে এটি পুরোপুরি প্লাগ করে।
gustafc

26

আপনি আপনার কোডটিতে জেনেরিক অ্যারে তৈরি করতে সক্ষম হবেন।

public <T> static void DoStuff() {
    T[] myArray = new T[42]; // No can do
}

অবজেক্টে কী ভুল? বস্তুর একটি অ্যারে যাইহোক রেফারেন্সের অ্যারে হয় is এটি স্ট্যাকের উপরে অবজেক্টের ডেটা বসার মতো নয় - এটি সমস্তই গাদা।
রণ বিরন

19
সুরক্ষা টাইপ করুন। আমি অবজেক্ট [] তে যা খুশি রাখতে পারি, তবে কেবল স্ট্রিংগুলিতে স্ট্রিং []।
টার্নার

3
দৌড়: ব্যঙ্গাত্মক না হয়ে: আপনি জাভার পরিবর্তে স্ক্রিপ্টিং ভাষা ব্যবহার করতে পছন্দ করতে পারেন, তবে আপনার যে কোনও জায়গায় টাইপযুক্ত ভেরিয়েবলের নমনীয়তা থাকতে পারে!
উড়ন্ত ভেড়া

2
অ্যারে উভয় ভাষায় সমবায় (এবং তাই টাইপসেফ নয়)। String[] strings = new String[1]; Object[] objects = strings; objects[0] = new Object();উভয় ভাষায় সূক্ষ্ম সংকলন। নসফাইন চালায়।
মার্টিজন

16

এটি একটি পুরানো প্রশ্ন, উত্তরগুলির একটি টন রয়েছে, তবে আমি মনে করি যে বিদ্যমান উত্তরগুলি চিহ্নের বাইরে রয়েছে।

"রিফাইফড" এর অর্থ আসল এবং সাধারণভাবে কেবল মুছে যাওয়া প্রকারের বিপরীত অর্থ।

জাভা জেনারিক্স সম্পর্কিত বড় সমস্যা:

  • এই ভয়ঙ্কর বক্সিংয়ের প্রয়োজনীয়তা এবং আদিম এবং রেফারেন্স ধরণের মধ্যে সংযোগ বিচ্ছিন্ন। এটি সরাসরি সংস্কার বা মুছে ফেলার সাথে সম্পর্কিত নয়। সি # / স্কেলা এটিকে ঠিক করুন।
  • কোন স্ব ধরণের। জাভাএফএক্স 8 এই কারণে "বিল্ডার" মুছে ফেলতে হয়েছিল। ধরণের মুছে ফেলার সাথে একেবারে কিছু করার নেই। স্কেলা এটিকে ঠিক করে দেয়, সি # সম্পর্কে নিশ্চিত নয়।
  • কোনও ঘোষণার পার্শ্ব প্রকারের বৈকল্পিকতা নেই। সি # 4.0 / স্কালায় এটি আছে। ধরণের মুছে ফেলার সাথে একেবারে কিছু করার নেই।
  • ওভারলোড void method(List<A> l)এবং method(List<B> l)। এটি ক্ষয় টাইপ করার কারণে তবে এটি অত্যন্ত ক্ষুদ্র।
  • রানটাইম টাইপ প্রতিবিম্ব জন্য কোন সমর্থন। এটি মুছে ফেলার হৃদয়। যদি আপনি এমন সুপার অ্যাডভান্সড কম্পাইলারগুলি পছন্দ করেন যা সংকলনের সময় আপনার প্রোগ্রামের লজিকটি যথাযথভাবে যাচাই করে এবং প্রমাণ করে, আপনার যতটা সম্ভব প্রতিফলনটি ব্যবহার করা উচিত এবং এই ধরণের ক্ষয়টি আপনাকে বিরক্ত করা উচিত নয়। আপনি যদি আরও প্যাচী, স্ক্রিপি, ডায়নামিক টাইপ প্রোগ্রামিং পছন্দ করেন এবং আপনার যৌক্তিকতাকে যথাসম্ভব সঠিক প্রমাণিত করে এমন একটি সংকলক সম্পর্কে এতটা যত্নশীল না হন, তবে আপনি আরও ভাল প্রতিচ্ছবি এবং ফিক্সিং টাইপের ক্ষয়টি গুরুত্বপূর্ণ তা চান।

1
সিরিয়ালাইজেশনের ক্ষেত্রে বেশিরভাগ ক্ষেত্রেই আমার কাছে এটি হার্ড মনে হয়। আপনি প্রায়শই ক্লাসের ধরণের জেনেরিক জিনিসগুলি সিরিয়ালীকৃত হওয়ার জন্য স্নিগ্ধ করতে সক্ষম হতে চান তবে ক্ষয় ক্ষয়ের কারণে আপনার সংক্ষিপ্ততা বন্ধ হয়ে যায়। এরকম কিছু করা শক্ত করে তোলেdeserialize(thingy, List<Integer>.class)
কগম্যান

3
আমি মনে করি এটিই সেরা উত্তর। বিশেষত অংশগুলি যা মুছে ফেলার কারণে টাইপগুলি প্রকৃতপক্ষে তহবিলের ভিত্তিতে এবং কেবল জাভা ভাষার নকশা সমস্যাগুলির মধ্যে রয়েছে describ আমি লোকেদের মুছে ফেলা-ঝকঝকে শুরু করার প্রথম কথাটি হ'ল স্কালা এবং হাস্কেল খুব ভালভাবে মুছে ফেলাতেও কাজ করছে।
aemxdp

13

ক্রমিকরণ সংশোধন আরও সহজবোধ্য হবে। আমরা যা চাই তা হ'ল

deserialize(thingy, List<Integer>.class);

আমাদের যা করতে হবে তা হচ্ছে

deserialize(thing, new TypeReference<List<Integer>>(){});

দেখতে কুরুচিপূর্ণ এবং মজাদার কাজ করে।

এমন কিছু ঘটনাও রয়েছে যেখানে এরকম কিছু বলা সত্যিই সহায়ক হবে

public <T> void doThings(List<T> thingy) {
    if (T instanceof Q)
      doCrazyness();
  }

এই জিনিসগুলি প্রায়শই কামড়ায় না, তবে যখন ঘটে তখন তারা কামড় দেয়।


এই. এই হাজার বার। আমি যখনই জাভাতে ডিসিরিয়ালিশন কোডটি লেখার চেষ্টা করি তখনই আমি এই শোকের জন্য দিনটি কাটাতে থাকি যে আমি অন্য কোনও কাজ করছি না
বেসিক

11

জাভা জেনেরিক্সের সাথে আমার এক্সপোজারটি বেশ সীমাবদ্ধ, এবং অন্যান্য উত্তরগুলি ইতিমধ্যে উল্লেখ করেছেন যে পয়েন্টগুলি বাদ দিয়ে জাভা জেনেরিকস এবং সংগ্রহ বইটিতে ব্যাখ্যা করা একটি দৃশ্য রয়েছে মরিস নাফটালিন এবং ফিলিপ ওয়াল্ডারের , যেখানে রেফাইড জেনেরিকগুলি কার্যকর।

যেহেতু প্রকারগুলি পুনরায় সংশোধনযোগ্য নয় তাই প্যারামিটারাইজড ব্যতিক্রমগুলি হওয়া সম্ভব নয়।

উদাহরণস্বরূপ নীচের ফর্মের ঘোষণা বৈধ নয়।

class ParametericException<T> extends Exception // compile error

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

যদি উপরের কোডটি বৈধ হয় তবে নীচের পদ্ধতিতে ব্যতিক্রম হ্যান্ডলিং সম্ভব হত:

try {
     throw new ParametericException<Integer>(42);
} catch (ParametericException<Integer> e) { // compile error
  ...
}

বইটিতে আরও উল্লেখ করা হয়েছে যে জাভা জেনেরিকগুলি সি ++ টেমপ্লেটগুলি সংজ্ঞায়িত (সম্প্রসারণ) করার মতো করে সংজ্ঞায়িত করা হলে এটি আরও কার্যকর প্রয়োগের দিকে পরিচালিত করতে পারে কারণ এটি অপ্টিমাইজেশনের জন্য আরও বেশি সুযোগ দেয়। তবে এর চেয়ে বেশি কোনও ব্যাখ্যা সরবরাহ করে না, সুতরাং জ্ঞাত লোকদের থেকে কোনও ব্যাখ্যা (পয়েন্টার) সহায়ক হবে।


1
এটি একটি বৈধ পয়েন্ট তবে আমি কেন সম্পূর্ণ প্যারামেট্রাইজযুক্ত একটি ব্যতিক্রম শ্রেণি কার্যকর হবে তা নিশ্চিত নই। এটি কখন কার্যকর হতে পারে তার একটি সংক্ষিপ্ত উদাহরণ ধারণ করতে আপনি নিজের উত্তরটি পরিবর্তন করতে পারেন?
অক্সবো_লাক্স

@ অক্সবো_লাকস: দুঃখিত জাভা জেনারিক্স সম্পর্কে আমার জ্ঞান যথেষ্ট সীমাবদ্ধ এবং আমি এটির উন্নতি করার চেষ্টা করছি। সুতরাং এখন আমি এমন কোনও উদাহরণের কথা ভাবতে পারছি না যেখানে প্যারামেট্রাইজড ব্যতিক্রম কার্যকর হতে পারে। এটি সম্পর্কে চিন্তা করার চেষ্টা করবে। ধন্যবাদ.
সতীশ

এটি ব্যতিক্রম ধরণের একাধিক উত্তরাধিকারের বিকল্প হিসাবে কাজ করতে পারে।
মেরিটন

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

8

অ্যারেগুলি পুনরায় সংশোধন করা হলে তারা জেনেরিকের সাথে খুব সুন্দর খেলবে।


2
অবশ্যই, তবে তাদের এখনও সমস্যা হবে। List<String>একটি না List<Object>
টম হাটিন -

সম্মত হন - তবে কেবল আদিমদের জন্য (পূর্ণসংখ্যা, দীর্ঘ, ইত্যাদি)। "নিয়মিত" অবজেক্টের জন্য, এটি একই। যেহেতু আদিমতাগুলি প্যারামিটারাইজড ধরণের হতে পারে না (এটি আরও গুরুতর সমস্যা, কমপক্ষে আইএমএইচও), তাই আমি এটিকে বাস্তব ব্যথা হিসাবে দেখছি না।
রণ বিরন

3
অ্যারেগুলির সমস্যা হ'ল তাদের আভিজাত্য, সংস্কারের সাথে কিছুই করার নেই।
পুনরাবৃত্তি করুন

5

আমার কাছে একটি মোড়ক রয়েছে যা একটি জেডিবিসি রেজাল্টকে একটি পুনরুক্তি হিসাবে উপস্থাপন করে, (এর অর্থ আমি নির্ভরশীলতা ইনজেকশনের মাধ্যমে ডেটাবেস-উত্পন্ন ক্রিয়াকলাপকে আরও সহজ করতে পারি)।

এপিআই দেখে মনে হচ্ছে Iterator<T> টি যেখানে টি এমন কিছু প্রকার যা কেবল কনস্ট্রাক্টরের কেবল স্ট্রিং ব্যবহার করে নির্মিত যেতে পারে। Iterator এর পরে স্ক্যালের ক্যোয়ারী থেকে স্ট্রিংগুলি ফিরে আসার দিকে তাকায় এবং তারপরে এটি টি টাইপের একটি নির্মাণকারীর সাথে মেলানোর চেষ্টা করে

জেনেরিকগুলি যেভাবে প্রয়োগ করা হয় সেভাবে, আমার ফলাফলসংশ্লিষ্টতা থেকে আমি যে বস্তুগুলি তৈরি করব তা আমার ক্লাসেও পাস করতে হবে। যদি আমি সঠিকভাবে বুঝতে পারি, জেনেরিকগুলি যদি পুনরায় সংজ্ঞায়িত করা হয় তবে আমি কেবল T.getClass () এর নির্মাণকারীদের কল করতে পারি এবং তারপরে Class.newInstance () এর ফলাফল দিতে হবে না, যা আরও নিকটতর হবে।

মূলত, আমি মনে করি এটি এপিআইগুলি লিখতে (কেবলমাত্র একটি অ্যাপ্লিকেশন লেখার বিপরীতে) সহজ করে তোলে, কারণ আপনি বস্তুগুলি থেকে আরও অনেক কিছু অনুমান করতে পারেন, এবং এর মাধ্যমে কম কনফিগারেশন করা প্রয়োজন হবে ... আমি না হওয়া পর্যন্ত টীকাগুলির প্রভাবগুলির প্রশংসা করি না সেগুলি কনফিগের রিমগুলির পরিবর্তে বসন্ত বা এক্সস্ট্রিমের মতো জিনিসগুলিতে ব্যবহার হতে দেখেছে।


তবে ক্লাসে পাস করা আমার কাছে চারপাশে নিরাপদ বলে মনে হচ্ছে। যে কোনও ক্ষেত্রে, প্রতিবিম্বিতভাবে ডাটাবেস ক্যোয়ারীগুলি থেকে উদাহরণ তৈরি করা যেমন কোনওভাবেই রিফ্যাক্টরিং (আপনার কোড এবং ডাটাবেস উভয় ক্ষেত্রে) পরিবর্তনের পক্ষে অত্যন্ত ভঙ্গুর। আমার ধারণা আমি এমন জিনিসগুলি সন্ধান করছিলাম যার দ্বারা ক্লাস সরবরাহ করা সম্ভব নয়
অক্সবো_লাক্স

5

একটি দুর্দান্ত জিনিস আদিম (মান) ধরণের জন্য বক্সিং এড়ানো হবে। এটি অন্যরকম উত্থাপিত অ্যারে অভিযোগের সাথে কিছুটা সম্পর্কিত, এবং স্মৃতি ব্যবহারের ক্ষেত্রে বাধা রয়েছে এমন ক্ষেত্রে এটি একটি উল্লেখযোগ্য পার্থক্য করতে পারে।

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


2
মূলত new T[]টি যেখানে আদিম ধরণের সেখানে তা করতে সক্ষম হয়ে উঠছে!
অক্সবো_লোক

2

এমন নয় যে আপনি অসাধারণ কিছু অর্জন করবেন। এটি বুঝতে সহজ হবে। প্রকারের ক্ষয়টি নতুনদের জন্য কঠিন সময়ের মতো মনে হয় এবং সংকলকটি যেভাবে কাজ করে তার পরিণামে এটির বোঝার প্রয়োজন।

আমার মতে, জেনেরিকগুলি কেবল একটি অতিরিক্ত যা প্রচুর অনর্থক ingালাই সংরক্ষণ করে।


এটি অবশ্যই জেনারিক্সগুলি জাভাতে রয়েছে । সি # এবং অন্যান্য ভাষায় তারা একটি শক্তিশালী হাতিয়ার
বেসিক

1

এখানকার সমস্ত উত্তরগুলি যা হারিয়েছে তা আমার জন্য নিয়মিত মাথা ব্যথার কারণ হ'ল ধরণগুলি মুছে ফেলা হচ্ছে, আপনি দুবার জেনেরিক ইন্টারফেসের উত্তরাধিকারী হতে পারবেন না। আপনি যখন সূক্ষ্ম দানযুক্ত ইন্টারফেস করতে চান এটি একটি সমস্যা হতে পারে।

    public interface Service<KEY,VALUE> {
           VALUE get(KEY key);
    }

    public class PersonService implements Service<Long, Person>,
        Service<String, Person> //Can not do!!

0

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

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

(এনবি: আমি এখানে একটি ভুল করে থাকতে পারি, তবে "জেনেরিক ভেরাগস" এর আশেপাশে গুগল করা, উপরেরটি ঠিক আপনি প্রত্যাশা করছিলেন বলে মনে হয় this যে বিষয়টি ব্যবহারিক সমস্যা তৈরি করে তা ক্লাসের ব্যবহার, আমি মনে করি - কলকারীরা মনে হয় কম সতর্কতা অবলম্বন করা উচিত :()


উদাহরণস্বরূপ, আমি শ্রেণীর অবজেক্টগুলিকে মানচিত্রে কী হিসাবে ব্যবহার করে এমন একটি দৃষ্টান্ত ব্যবহার করছি (এটি একটি সাধারণ মানচিত্রের চেয়ে জটিল - তবে ধারণাগত যা চলছে তা)।

উদাহরণস্বরূপ এটি জাভা জেনারিকসে দুর্দান্ত কাজ করে (তুচ্ছ উদাহরণ):

public <T extends Component> Set<UUID> getEntitiesPossessingComponent( Class<T> componentType)
    {
        // find the entities that are mapped (somehow) from that class. Very type-safe
    }

উদাহরণস্বরূপ জাভা জেনারিক্সে রেফারেন্স ছাড়াই, এটি কোনও "ক্লাস" অবজেক্ট গ্রহণ করে। এবং এটি পূর্ববর্তী কোডটির কেবলমাত্র একটি ছোট এক্সটেনশন:

public <T extends Component> Set<UUID> getEntitiesPossessingComponents( Class<T>... componentType )
    {
        // find the entities that are mapped (somehow) to ALL of those classes
    }

উপরোক্ত পদ্ধতিগুলি পৃথক প্রকল্পে কয়েকবার লিখতে হবে - সুতরাং মানুষের ত্রুটির সম্ভাবনা বেশি হয়ে যায়। ডিবাগিং ভুলগুলি "মজাদার নয়" প্রমাণ করছে। আমি বর্তমানে একটি বিকল্প সন্ধান করার চেষ্টা করছি, তবে খুব বেশি আশা রাখবেন না।

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