এটি সংকলন করে না, কোনও পরামর্শ প্রশংসা করেছে।
...
List<Object> list = getList();
return (List<Customer>) list;
সংকলক বলেছেন: কাস্ট List<Object>
করতে পারবেন নাList<Customer>
এটি সংকলন করে না, কোনও পরামর্শ প্রশংসা করেছে।
...
List<Object> list = getList();
return (List<Customer>) list;
সংকলক বলেছেন: কাস্ট List<Object>
করতে পারবেন নাList<Customer>
উত্তর:
আপনি সর্বদা অবজেক্টে আপ-কাস্টিং করে যে কোনও অবজেক্টকে সর্বদা কাস্ট করতে পারেন। আপনার ক্ষেত্রে:
(List<Customer>)(Object)list;
আপনাকে অবশ্যই নিশ্চিত হতে হবে যে রানটাইমের সময় তালিকায় গ্রাহক সামগ্রী ছাড়া কিছুই নেই nothing
সমালোচকরা বলেছেন যে এই জাতীয় castালাই আপনার কোডের সাথে কিছু ভুল বোঝায়; আপনার প্রকারের ঘোষণাগুলি এড়াতে আপনার টুইঙ্ক করতে সক্ষম হওয়া উচিত। তবে জাভা জেনেরিকগুলি খুব জটিল এবং এটি নিখুঁত নয়। সংকলকটি সন্তুষ্ট করার জন্য কোনও দুর্দান্ত সমাধান আছে কিনা তা আপনি মাঝে মাঝে জানতেন না, যদিও আপনি রানটাইম টাইপগুলি খুব ভাল জানেন এবং আপনি কী জানেন যে আপনি কী চেষ্টা করছেন তা নিরাপদ। সেক্ষেত্রে প্রয়োজন অনুসারে কেবল অশোধিত castালাই করুন, যাতে আপনি বাড়ির জন্য কাজ ছেড়ে যেতে পারেন।
কারণ গ্রাহক একটি অবজেক্ট হলেও গ্রাহকদের একটি তালিকা বস্তুর তালিকা নয় । যদি তা হয় তবে গ্রাহকদের তালিকায় আপনি কোনও বস্তু রাখতে পারেন ।
.Cast<T>()
এবং একটি কল .OfType<T>()
। পূর্ববর্তী প্রতিটি উপাদানটিতে একটি কাস্ট সম্পাদন করে (পছন্দসই ব্যতিক্রমগুলি ছুঁড়ে ফেলে) যখন পরবর্তীকৃত উপাদানগুলি কাস্ট করা যায় না তা ফিল্টার করে (যাতে আপনি আপনার ব্যবহারের দৃশ্যের উপর নির্ভর করে কোনওটিকে বেছে নিতে পারেন)।
instanceof
গ্রাহক না হলে কী হবে ?
আপনার অন্যান্য কোডের উপর নির্ভর করে সেরা উত্তরটি ভিন্ন হতে পারে। চেষ্টা করুন:
List<? extends Object> list = getList();
return (List<Customer>) list;
বা
List list = getList();
return (List<Customer>) list;
তবে মনে রাখবেন এ জাতীয় চেক করা ক্যাসেটগুলি করার পরামর্শ দেওয়া হয় না।
জাভা 8 স্ট্রিম সহ :
কখনও কখনও নিষ্ঠুর বল castালাই ঠিক আছে:
List<MyClass> mythings = (List<MyClass>) (Object) objects
তবে এখানে আরও বহুমুখী সমাধান রয়েছে:
List<Object> objects = Arrays.asList("String1", "String2");
List<String> strings = objects.stream()
.map(element->(String) element)
.collect(Collectors.toList());
এক টন সুবিধাগুলি রয়েছে তবে একটি হ'ল আপনি যদি আপনার তালিকাটি আরও মার্জিতভাবে কাস্ট করতে পারেন তবে এটিতে কী রয়েছে তা নিশ্চিত না করতে পারলে:
objects.stream()
.filter(element->element instanceof String)
.map(element->(String)element)
.collect(Collectors.toList());
FluentIterable
আমার পক্ষে কাজ করেছিল।
মনে রাখবেন যে আমি কোনও জাভা প্রোগ্রামার নই, তবে। নেট এবং সি # তে এই বৈশিষ্ট্যটিকে কন্ট্রভ্যারিয়েন্স বা কোভেরিয়েন্স বলা হয়। আমি এখনও এই জিনিসগুলিতে প্রবেশ করিনি, যেহেতু সেগুলি নেট নেট in.০ এ নতুন, আমি এটি কেবল বিটা যেহেতু ব্যবহার করছি না, তাই আমি জানি না যে দুটি পদগুলির মধ্যে কোনটি আপনার সমস্যার বর্ণনা দেয়, তবে আমাকে বর্ণনা করতে দিন এই সঙ্গে প্রযুক্তিগত সমস্যা।
ধরে নেওয়া যাক আপনাকে কাস্ট করার অনুমতি দেওয়া হয়েছিল। দ্রষ্টব্য, আমি কাস্ট বলি , যেহেতু আপনি যা বলেছিলেন, কিন্তু দুটি ক্রিয়াকলাপ সম্ভব যা কাস্টিং এবং রূপান্তরিত হতে পারে ।
রূপান্তরকরণের অর্থ হ'ল আপনি একটি নতুন তালিকার অবজেক্ট পাবেন তবে আপনি কাস্টিং বলেছেন, যার অর্থ আপনি সাময়িকভাবে একটি অবজেক্টকে অন্য ধরণের হিসাবে বিবেচনা করতে চান।
এখানে যে সমস্যা আছে।
নিম্নলিখিতগুলির অনুমতি দেওয়া হলে কী হবে (দ্রষ্টব্য, আমি ধরে নিচ্ছি যে কাস্টের আগে, বস্তুর তালিকায় আসলে কেবল গ্রাহক বস্তু থাকে, অন্যথায় জাভা এই অনুমানীয় সংস্করণেও কাস্ট কাজ করবে না):
List<Object> list = getList();
List<Customer> customers = (List<Customer>)list;
list.Insert(0, new someOtherObjectNotACustomer());
Customer c = customers[0];
এই ক্ষেত্রে, এটি কোনও গ্রাহক হিসাবে গ্রাহক নয়, কোনও বস্তুর চিকিত্সার চেষ্টা করবে এবং তালিকার অভ্যন্তরে অথবা অ্যাসাইনমেন্ট থেকে আপনি এক পর্যায়ে রানটাইম ত্রুটি পাবেন।
জেনারিকস, তবে আপনাকে সংগ্রহের মতো টাইপ-সেফ ডেটা টাইপ দেওয়ার কথা বলেছে এবং যেহেতু তারা 'গ্যারান্টিযুক্ত' শব্দটি চারপাশে ছুঁড়ে ফেলতে পছন্দ করে, এই সমস্যাগুলি অনুসরণ করে এমন সমস্যা সহ, এই ধরণের কাস্টের অনুমতি দেওয়া হয় না।
নেট 4.0 এ (আমি জানি, আপনার প্রশ্ন জাভা সম্পর্কে ছিল), এটি খুব নির্দিষ্ট কিছু ক্ষেত্রে অনুমোদিত হবে , যেখানে সংকলকটি গ্যারান্টি দিতে পারে যে আপনি যে কাজগুলি করেন সেগুলি নিরাপদ, তবে সাধারণ অর্থে এই ধরণের castালাই না অনুমতি দেওয়া। একইভাবে জাভাটির পক্ষে রয়েছে, যদিও আমি জাভা ভাষার সাথে সহযোগিতা এবং বৈপরীত্য প্রবর্তনের কোনও পরিকল্পনা সম্পর্কে অনিশ্চিত।
আশা করি, আমার চেয়ে আরও ভাল জাভা জ্ঞানের কেউ আপনাকে জাভা ভবিষ্যত বা বাস্তবায়নের সুনির্দিষ্ট কথা বলতে পারেন।
আর একটি পদ্ধতিতে জাভা 8 স্ট্রিম ব্যবহার করা হবে।
List<Customer> customer = myObjects.stream()
.filter(Customer.class::isInstance)
.map(Customer.class::cast)
.collect(toList());
List<Customer> cusList = new ArrayList<Customer>();
for(Object o: list){
cusList.add((Customer)o);
}
return cusList;
list.stream().forEach(x->cusList.add((Customer)x))
return cuslist;
আপনি পারবেন না কারণ List<Object>
এবং List<Customer>
একই উত্তরাধিকার গাছে নেই।
তুমি তোমার কাছে নতুন কন্সট্রাকটর যোগ করতে পারিনি List<Customer>
বর্গ করে একটি সময় লাগে List<Object>
এবং তারপর বারবার তালিকা মাধ্যমে একে ভোটদান Object
একটি থেকে Customer
এবং আপনার সংগ্রহে এটি যোগ। সচেতন হন যে কলারটির List<Object>
মধ্যে এমন কিছু নেই যা একটি অবৈধ কাস্ট ব্যতিক্রম ঘটতে পারে Customer
।
জেনেরিক তালিকার মূল বিষয় হ'ল এগুলি নির্দিষ্ট ধরণের সীমাবদ্ধ করা। আপনি এমন একটি তালিকা নেওয়ার চেষ্টা করছেন যাতে কিছু থাকতে পারে (অর্ডার, পণ্য ইত্যাদি) এবং এটিকে এমন একটি তালিকাতে চেপে নিন যা কেবল গ্রাহকদের নিতে পারে।
আপনার সেরা বাজি হ'ল একটি নতুন তৈরি করা List<Customer>
, এর মাধ্যমে পুনরাবৃত্তি করা List<Object>
, প্রতিটি আইটেমকে নতুন তালিকায় যুক্ত করা এবং এটি ফিরিয়ে দেওয়া।
অন্যরা যেমন উল্লেখ করেছে, আপনি সেগুলি সংরক্ষণের সাথে সংরক্ষণ করতে পারবেন না, যেহেতু এটি একটি List<Object>
নয় List<Customer>
। আপনি যা করতে পারেন তা হ'ল তালিকার একটি ভিউ সংজ্ঞায়িত করা যা স্থানের ধরণের চেক করে। গুগল সংগ্রহগুলি যেগুলি হবে তা ব্যবহার করে :
return Lists.transform(list, new Function<Object, Customer>() {
public Customer apply(Object from) {
if (from instanceof Customer) {
return (Customer)from;
}
return null; // or throw an exception, or do something else that makes sense.
}
});
উপরের বোজোর সাথে একই রকম। এই পদ্ধতির মাধ্যমে আপনি এখানে কিছুটা কাজ করতে পারেন (যদিও আমি নিজে এটি পছন্দ করি না):
public <T> List<T> convert(List list, T t){
return list;
}
হ্যাঁ. এটি আপনার দাবি করা জেনেরিক প্রকারে আপনার তালিকাটি ফেলে দেবে।
উপরের প্রদত্ত ক্ষেত্রে, আপনি এর মতো কিছু কোড করতে পারেন:
List<Object> list = getList();
return convert(list, new Customer());
আপনি তালিকার সাথে কী করতে চান তার উপর নির্ভর করে আপনার এটি এটিকে কাস্ট করার দরকারও পড়তে পারে না List<Customer>
। আপনি যদি কেবলমাত্র Customer
তালিকায় অবজেক্টগুলি যুক্ত করতে চান তবে আপনি এটি নীচে ঘোষণা করতে পারেন:
...
List<Object> list = getList();
return (List<? super Customer>) list;
এটি আইনী (ভাল, কেবল আইনী নয়, তবে সঠিক) - তালিকাটি "গ্রাহকের কাছে কিছু ধরণের ধরণের ধরণের রয়েছে") এবং আপনি যদি এমন কোনও পদ্ধতিতে যাচ্ছেন যা কেবল তালিকায় অবজেক্ট যুক্ত করবে তবে উপরের অংশটি জেনেরিক সীমা এই জন্য যথেষ্ট।
অন্যদিকে, আপনি যদি তালিকা থেকে অবজেক্টগুলি পুনরুদ্ধার করতে এবং সেগুলি গ্রাহক হিসাবে দৃ strongly়ভাবে টাইপ করতে চান - তবে আপনার ভাগ্য খুব খারাপ, এবং ঠিক তাই। তালিকাটি যেহেতু List<Object>
সামগ্রীগুলির গ্রাহকগণের কোনও গ্যারান্টি নেই তাই আপনাকে পুনরুদ্ধারে নিজের কাস্টিং সরবরাহ করতে হবে। (বা সত্যই, একেবারে দ্বিগুণ নিশ্চিত হন যে তালিকার মধ্যে কেবলমাত্র Customers
অন্য উত্তরগুলির মধ্যে একটি রয়েছে এবং ডাবল কাস্ট ব্যবহার করবে তবে বুঝতে হবে যে আপনি জেনারিকগুলি থেকে প্রাপ্ত কম্পাইল-টাইম টাইপ-সুরক্ষাটি সম্পূর্ণরূপে নষ্ট করছেন) কেস)।
বিস্তৃতভাবে বলতে গেলে কোনও পদ্ধতি লেখার সময় গ্রহণযোগ্য হবে এমন বিস্তৃত সম্ভাব্য জেনেরিক সীমা বিবেচনা করা সর্বদা ভাল, যদি এটি কোনও গ্রন্থাগার পদ্ধতি হিসাবে ব্যবহার করা হয় তবে দ্বিগুণ। আপনি শুধুমাত্র একটি তালিকা থেকে পড়তে যাচ্ছেন করেন, ব্যবহার List<? extends T>
পরিবর্তে List<T>
, উদাহরণস্বরূপ - আপনার কলারের দেয় অনেক আর্গুমেন্ট এবং মানে তারা সম্ভাবনা কম এক আপনি 'অনুরূপ পরিহার্য সমস্যার সম্মূখীন হয় তারা পাস করতে পারেন আরও সুযোগ এখানে আছে।
List<Object[]> testNovedads = crudService.createNativeQuery(
"SELECT ID_NOVEDAD_PK, OBSERVACIONES, ID_SOLICITUD_PAGO_FK FROM DBSEGUIMIENTO.SC_NOVEDADES WHERE ID_NOVEDAD_PK < 2000");
Convertir<TestNovedad> convertir = new Convertir<TestNovedad>();
Collection<TestNovedad> novedads = convertir.toList(testNovedads, TestNovedad.class);
for (TestNovedad testNovedad : novedads) {
System.out.println(testNovedad.toString());
}
public Collection<T> toList(List<Object[]> objects, Class<T> type) {
Gson gson = new Gson();
JSONObject jsonObject = new JSONObject();
Collection<T> collection = new ArrayList<>();
Field[] fields = TestNovedad.class.getDeclaredFields();
for (Object[] object : objects) {
int pos = 0;
for (Field field : fields) {
jsonObject.put(field.getName(), object[pos++]);
}
collection.add(gson.fromJson(jsonObject.toString(), type));
}
return collection;
}
@SuppressWarnings("unchecked")
। নোট করুন যে আপনি(List)
পরিবর্তে পরিবর্তে আপকাস্ট করতে পারেন(Object)
।