অ স্থির পদ্ধতিতে স্থির রেফারেন্স তৈরি করতে পারে না


102

জাভাতে একটি বহু-ভাষা অ্যাপ্লিকেশন তৈরি করা। R.stringরিসোর্স এক্সএমএল ফাইল থেকে স্ট্রিংয়ের মান সন্নিবেশ করার সময় একটি ত্রুটি পাওয়া :

public static final String TTT =  (String) getText(R.string.TTT);

এটি ত্রুটি বার্তা:

ত্রুটি: প্রসঙ্গ প্রবন্ধ থেকে অ স্থিতিশীল পদ্ধতি getText (int) এর স্থিতিশীল রেফারেন্স তৈরি করতে পারে না

এটি কীভাবে হয় এবং আমি কীভাবে এটি সমাধান করতে পারি?


1
'মাল্টি ল্যাঙ্গুয়েজ অ্যাপ্লিকেশন'-এর জন্য আপনার এটি স্ট্যাটিক হওয়ার দরকার কেন? আসলেই বুঝতে পারছি না।
xil3

3
স্ট্যাটিক ডেটা সদস্যদের মধ্যে স্ট্রিং রিসোর্সগুলি কখনও সঞ্চয় করবেন না। getString()আপনার যখন প্রয়োজন হয় তখন সর্বদা তাদের মাধ্যমে অনুরোধ করুন। এইভাবে, আপনার অ্যাপ্লিকেশনটি তাদের চয়ন করা ভাষা পরিবর্তন করে ব্যবহারকারীদের সাথে সঠিকভাবে সামঞ্জস্য করে।
CommonsWare

উত্তর:


143

যেহেতু getText()অ স্থির হয় তাই আপনি এটিকে কোনও স্ট্যাটিক পদ্ধতি থেকে কল করতে পারবেন না।

কেন বুঝতে, আপনাকে দুজনের মধ্যে পার্থক্য বুঝতে হবে।

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

SomeClass myObject = new SomeClass();

একটি উদাহরণ পদ্ধতিতে কল করার জন্য, আপনি এটিকে কল করুন (myObject ):

myObject.getText(...)

তবে কোনও স্ট্যাটিক পদ্ধতি / ক্ষেত্র কেবলমাত্র প্রকারে সরাসরি কল করা যেতে পারে , এইভাবে বলুন: পূর্ববর্তী বিবৃতিটি সঠিক নয়। স্ট্যাটিক ক্ষেত্রগুলি যেমন কোনও অবজেক্ট রেফারেন্স সহ উল্লেখ করা যায় myObject.staticMethod() তবে এটি নিরুৎসাহিত করা হয় কারণ এটি ক্লাস ভেরিয়েবলগুলি তা পরিষ্কার করে না।

... = SomeClass.final

এবং তারা পৃথক ডেটা স্পেসে কাজ করার সময় একসাথে কাজ করতে পারে না (উদাহরণস্বরূপ ডেটা এবং শ্রেণি ডেটা)

আমাকে চেষ্টা এবং ব্যাখ্যা করতে দিন। এই শ্রেণিটি বিবেচনা করুন (psuedocode):

class Test {
     string somedata = "99";
     string getText() { return somedata; } 
     static string TTT = "0";
}

এখন আমি নিম্নলিখিত ব্যবহারের মামলা আছে:

Test item1 = new Test();
 item1.somedata = "200";

 Test item2 = new Test();

 Test.TTT = "1";

মান কি?

আমরা হব

in item1 TTT = 1 and somedata = 200
in item2 TTT = 1 and somedata = 99

অন্য কথায়, TTTএটি এমন একটি ডেটাম যা এই ধরণের সমস্ত দৃষ্টান্ত দ্বারা ভাগ করা হয়। সুতরাং এটি বলার কোনও মানে নেই

class Test {
         string somedata = "99";
         string getText() { return somedata; } 
  static string TTT = getText(); // error there is is no somedata at this point 
}

সুতরাং প্রশ্নটি হল কেন টিটিটি স্থির বা কেন গেট টেক্সট () স্থির নয়?

অপসারণ করুন staticএবং এটি এই ত্রুটিটি অতিক্রম করতে হবে - তবে আপনার ধরণটি কী করে তা না বুঝেই পরবর্তী ত্রুটি পর্যন্ত এটি কেবল একটি স্টিকিং প্লাস্টার। getText()এটি অ-স্থিতিশীল হওয়ার প্রয়োজনীয়তাগুলি কী কী ?


এটি স্থির কারণ আমি আমার প্রকল্পের বেশ কয়েকটি ফাইল থেকে কল করেছি। যখন আমি "স্থিতিশীল" সরিয়েছি ত্রুটি কোডটি চলে গেছে তবে এখন অন্য ফাইলগুলিতে আমার প্রচুর ত্রুটি রয়েছে যা এই ভেরিয়েবলটি ব্যবহার করে।
চেন এম

তবে সেটাই আমার বক্তব্য। দু'টি কখন ব্যবহার করা যায় তা আপনার বুঝতে হবে।
প্রীত সংঘ

যখন আমি আমার মূল ক্রিয়াকলাপ শ্রেণিতে "কনস্ট্যান্টস বিজ্ঞপ্তি_মূল্যগুলি = নতুন কনস্ট্যান্ট (); লাইনটি যুক্ত করি তখন এটি ঠিক করা হয় তবে এই ক্রিয়াকলাপটি চলাকালীন এমুলেটরটিতে এটি ক্র্যাশ হয়
চেন এম

11

ইতিমধ্যেই কেন অ স্ট্যাটিক সংমিশ্রণ ব্যাখ্যা সঙ্গে কিছু ভাল উত্তর Contextপদ্ধতি getText()আপনার সঙ্গে ব্যবহার করা যাবে না static final String

একটি ভাল প্রশ্ন জিজ্ঞাসা করা হয়: আপনি এটি করতে চান কেন? আপনি Stringআপনার stringsসংস্থান থেকে একটি লোড করার চেষ্টা করছেন এবং এর মানটিকে একটি public staticক্ষেত্রের মধ্যে স্থাপন করছেন। আমি ধরে নিই যে এটি এমন যে যাতে আপনার অন্যান্য ক্লাসের কিছু এটির অ্যাক্সেস করতে পারে? যদি তা হয় তবে এটি করার দরকার নেই। পরিবর্তে Contextআপনার অন্যান্য ক্লাসে পাস করুন এবং সেগুলির context.getText(R.string.TTT)মধ্যে থেকে কল করুন।

public class NonActivity {

    public static void doStuff(Context context) {
        String TTT = context.getText(R.string.TTT);
        ...
    }
}

এবং আপনার থেকে এটি কল করতে Activity:

NonActivity.doStuff(this);

এটি আপনাকে Stringকোনও public staticক্ষেত্র ব্যবহার করার প্রয়োজন ছাড়াই আপনার সংস্থান অ্যাক্সেস করার অনুমতি দেবে ।


1
আপনাকে অনেক ধন্যবাদ, আমি আপনার প্রস্তাব অনুযায়ী সমস্ত ফাইল পরিবর্তন করেছি।
চেন এম

আমি এটি করার চেষ্টা করছিলাম, তবে স্ট্রিং-অ্যারের জন্য এবং সহ String a[] = context.getTextArray(R.array.myStringArray); ; এটি যাইহোক, আমাকে একটি ত্রুটি দেয় The method getTextArray(int) is undefined for the type Context- এটি গেইটেক্সটের সাথে কাজ করার সময় কেন এটি অপরিজ্ঞাত হবে?
শুভ

1
@ শুভ 99 টি কেবলমাত্র এ কারণে যে কোনওটির Contextনামক পদ্ধতি getTextArrayনেই, তবে রয়েছে getText। সম্ভবত আপনি Resourcesযা getTextArray
ভাবেন

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

9

অন্যদের জন্য যারা অনুসন্ধানে এটি খুঁজে পান:

আমি প্রায়শই এটি পাই যখন আমি ঘটনাক্রমে অবজেক্টের নামের পরিবর্তে ক্লাসের নাম ব্যবহার করে কোনও ফাংশন কল করি। এটি সাধারণত ঘটে থাকে কারণ আমি তাদের খুব অনুরূপ নাম দিই: পি

অর্থাৎ,

MyClass myclass = new MyClass();

// then later

MyClass.someFunction();

এটি অবশ্যই একটি স্থির পদ্ধতি ic (কিছুটা হলেও ভালো) তবে আমি আসলে কী করতে চেয়েছিলাম (বেশিরভাগ ক্ষেত্রেই ছিল)

myclass.someFunction();

এটি একটি নির্বোধ ভুল, কিন্তু প্রতি কয়েক মাস পরে আমি "মাই ক্লাস" সংজ্ঞাগুলিতে ওয়ার্সের সাথে প্রায় 30 মিনিট জঞ্জাল করি যখন সত্যিই এটির একটি টাইপও ঠিক কী ভুল করছে out

মজার নোট: স্ট্যাক ওভারফ্লো ভুলটিকে এখানে প্রকৃতপক্ষে প্রকট করতে সিনট্যাক্সকে হাইলাইট করে।


আপনার আইডিই এটিও হাইলাইট করে না? আমার ধারণা আপনি এটির জন্য এটি কনফিগার করতে পারেন :)
ম্যাথিয়ায়াস মেইড

2

আপনি হয় আপনার পরিবর্তনশীল অ স্থির করতে পারেন

public final String TTT =  (String) getText(R.string.TTT);

বা "getText" পদ্ধতিটি স্থির করুন (যদি সম্ভব হয় তবে)


2

গেটটেক্সট আপনার ক্রিয়াকলাপের একজন সদস্য তাই যখন "এটি" উপস্থিত থাকে তখন অবশ্যই তা ডাকতে হবে। আপনার অ্যাক্টিভিটি তৈরি হওয়ার আগে আপনার ক্লাসটি লোড করা হলে আপনার স্ট্যাটিক ভেরিয়েবল শুরু হয় ized

যেহেতু আপনি চান যে কোনও পরিবর্তনটি কোনও রিসোর্স স্ট্রিং থেকে আরম্ভ করা হয় তবে এটি স্থির হতে পারে না। আপনি যদি এটি স্থির রাখতে চান তবে আপনি স্ট্রিং মান দিয়ে এটি আরম্ভ করতে পারেন।


2

আপনি অ স্থির পদ্ধতি থেকে স্ট্যাটিক ভেরিয়েবলের উল্লেখ করতে পারবেন না। এটি বুঝতে, আপনার স্ট্যাটিক এবং অ-স্থির মধ্যে পার্থক্য বুঝতে হবে।

স্ট্যাটিক ভেরিয়েবলগুলি বর্গ ভেরিয়েবল হয়, তারা শ্রেণীর অন্তর্ভুক্ত তাদের একমাত্র উদাহরণ সহ, প্রথমটিতে তৈরি হয়েছিল। ক্লাসের কোনও অবজেক্ট তৈরি করার সময় অ-স্থিতিশীল ভেরিয়েবলগুলি শুরু করা হয়।

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


0

এই প্রশ্নটি নতুন নয় এবং বিদ্যমান উত্তরগুলি কিছু ভাল তাত্ত্বিক পটভূমি দেয়। আমি কেবল আরও বাস্তব যুক্ত করতে চাই।

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

এটি সমাধানের বিভিন্ন উপায় রয়েছে:

  1. স্থির পরিবর্তনকারীকে সরিয়ে ক্লাসের বডির মধ্যে স্থাপন করে ক্রিয়াকলাপটিকে ক্রিয়াকলাপের বা প্রসঙ্গের অন্যান্য সাবক্লাসের সদস্য ভেরিয়েবল (ক্ষেত্র) করুন;
  2. এটি স্থির রাখুন এবং সূচনাটি পরবর্তী বিন্দুতে বিলম্ব করুন (যেমন: অনক্রিট পদ্ধতিতে);
  3. প্রকৃত ব্যবহারের জায়গায় এটিকে স্থানীয় পরিবর্তনশীল করুন।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.