কিভাবে একটি জাভা জেনেরিক পদ্ধতি স্থির করতে?


172

অ্যারেতে একটি আইটেম সংযোজন করার জন্য জাভা জেনেরিক ক্লাসটি কীভাবে তৈরি করা যায় সে সম্পর্কে নীচে একটি স্নিপেট রয়েছে। কীভাবে আমি অ্যাপেন্ডটোরআরে স্ট্যাটিক পদ্ধতি করতে পারি। স্থিতিশীল যুক্ত পদ্ধতিতে স্বাক্ষর যুক্ত করে ত্রুটিগুলি সংকলন করে।

public class ArrayUtils<E> {

        public E[] appendToArray(E[] array, E item) {
            E[] result = (E[])new Object[array.length+1];
            result[array.length] = item;
            return result;
        }
}

আপনি কি সংকলন ত্রুটি পেতে পারি? এছাড়াও, কেন কেবল একটি স্ট্যান্ডার্ড লাইব্রেরি পাত্রে ব্যবহার করবেন না?
কার্ল নচেটেল

1
সংকলন ত্রুটি: আমি প্রকৃতপক্ষে স্থিতিশীল সংশোধকটিকে ভুলভাবে যুক্ত করেছিলাম .. সংগ্রহগুলি ব্যবহার করে: হ্যাঁ একটি সংগ্রহ ব্যবহার করা আদর্শ হবে তবে প্রশ্ন বনাম অ্যারের সংগ্রহ সম্পর্কিত নয়, আমার ব্যবহারের ক্ষেত্রে অ্যারের প্রয়োজন।
ক্রিস জনসন

নোট করুন কিছু ক্ষেত্রে ব্যতিক্রম ছড়িয়ে থাকা ক্লায়েন্ট কোড বন্ধ করার জন্য আপনাকে (EVIL) প্রতিবিম্বটি ব্যবহার করতে হবে তবে সমস্ত পরিস্থিতিতে নয় (দুর্দান্ত)। রেফারেন্স অ্যারেগুলি এড়ানো ভাল।
টম হাটিন -

উত্তর:


283

কেবলমাত্র আপনি যা করতে পারেন তা হ'ল আপনার স্বাক্ষরটি এতে পরিবর্তন করা

public static <E> E[] appendToArray(E[] array, E item)

গুরুত্বপূর্ণ বিশদ:

প্রত্যাবর্তনের মানের পূর্বে জেনেরিক এক্সপ্রেশনগুলি সর্বদা একটি নতুন জেনেরিক ধরণের পরিবর্তনশীল প্রবর্তন করে (ঘোষণা করে)।

অতিরিক্তভাবে, প্রকার ( ArrayUtils) এবং স্থির পদ্ধতিগুলির ( appendToArray) এর মধ্যে ভেরিয়েবলগুলি টাইপ করুন কখনই একে অপরের সাথে হস্তক্ষেপ করে না।

সুতরাং, এর অর্থ কী: আমার উত্তরে যদি পদ্ধতিটি না হয় তবে <E>এগুলি লুকিয়ে রাখব । এবং সঙ্গে কিছুই করার আছে থেকে ।EArrayUtils<E>static<E>EArrayUtils<E>

এই সত্যটি আরও ভালভাবে প্রতিফলিত করার জন্য, আরও সঠিক উত্তর হবে:

public static <I> I[] appendToArray(I[] array, I item)

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

তবে এই ক্ষেত্রে আমি বিভিন্ন ধরণের একটি বস্তুকে প্যারামগুলিতে পাস করতে পারি। যেমন আমি প্রথম প্যারাম এবং ডাবল আইটেম হিসাবে পূর্ণসংখ্যা [] অ্যারে পাস করতে পারি।
গোলাপী প্যান্থার

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

80
public static <E> E[] appendToArray(E[] array, E item) { ...

নোট করুন <E>

স্ট্যাটিক জেনেরিক পদ্ধতিগুলির নিজস্ব জেনেরিক ঘোষণা ( public static <E>) শ্রেণীর জেনেরিক ঘোষণা ( public class ArrayUtils<E>) থেকে পৃথক হওয়া প্রয়োজন need

যদি সংকলক স্থিতিশীল জেনেরিক পদ্ধতিতে অনুরোধ করার ক্ষেত্রে কোনও ধরণের অস্পষ্টতা সম্পর্কে অভিযোগ করে (তবে আপনার ক্ষেত্রে সম্ভবত এটি সম্ভবত নয়, তবে সাধারণত বলছেন, তবে সুনির্দিষ্টভাবে ( _class_.<_generictypeparams_>_methodname_)) ব্যবহার করে স্থির জেনেরিক পদ্ধতিটি কীভাবে স্পষ্টভাবে আবেদন করা যায় তা এখানে :

String[] newStrings = ArrayUtils.<String>appendToArray(strings, "another string");

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


10

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

public class ArrayUtils {
    public static <T> E[] appendToArray(E[] array, E item) {
        E[] result = (E[])new Object[array.length+1];
        result[array.length] = item;
        return result;
    }
}

1
এটি কাজ করবে না কারণ আপনি জেনেরিক টাইপ ই সংজ্ঞায়িত করেন নি this এক্ষেত্রে আপনার এখনও ক্লাস সংজ্ঞাতে জেনেরিক প্রকার <E> থাকতে হবে।
জর্জ জাভিয়ার

0

আমি এটি একটি সহজ পদ্ধতিতে ব্যাখ্যা করব।

ক্লাস স্তরে সংজ্ঞায়িত জেনারিকস (স্ট্যাটিক) পদ্ধতি স্তরে সংজ্ঞায়িত জেনেরিক থেকে সম্পূর্ণ পৃথক।

class Greet<T> {

    public static <T> void sayHello(T obj) {
        System.out.println("Hello " + obj);
    }
}

আপনি যখন কোথাও উপরের কোডটি দেখতে পাচ্ছেন, দয়া করে নোট করুন যে শ্রেণি পর্যায়ে সংজ্ঞায়িত টিটির স্থির পদ্ধতিতে সংজ্ঞায়িত টি এর সাথে কোনও সম্পর্ক নেই। নিম্নলিখিত কোডটিও সম্পূর্ণ বৈধ এবং উপরের কোডের সমতুল্য।

class Greet<T> {

    public static <E> void sayHello(E obj) {
        System.out.println("Hello " + obj);
    }
}

স্থির পদ্ধতিটির নিজস্ব জেনেরিকগুলি ক্লাসের থেকে আলাদা হওয়া দরকার কেন?

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

সুতরাং, আপনি যখনই স্থির পদ্ধতি কল করছেন,

Greet.sayHello("Bob");
Greet.sayHello(123);

জেভিএম নিম্নলিখিত হিসাবে এটি ব্যাখ্যা করে।

Greet.<String>sayHello("Bob");
Greet.<Integer>sayHello(123);

উভয় একই আউটপুট দেয়।

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