জাভাতে ডাবল ব্রেস সূচনা কী?


305

{{ ... }}জাভাতে ডাবল ব্রেস প্রারম্ভিককরণ সিনট্যাক্স ( ) কী?




10
ডাবল ব্রেস প্রারম্ভিককরণ একটি খুব বিপজ্জনক বৈশিষ্ট্য এবং যথাযথভাবে ব্যবহার করা উচিত। এটি সমান চুক্তি ভঙ্গ করতে পারে এবং জটিল মেমরি ফাঁস প্রবর্তন করতে পারে। এই নিবন্ধটি বিশদ বর্ণনা করে।
Andrii Polunin

উত্তর:


300

ডাবল ব্রেস সূচনাটি নির্দিষ্ট শ্রেণি ( বাহ্যিক ধনুর্বন্ধনী) থেকে প্রাপ্ত একটি বেনাম শ্রেণি তৈরি করে এবং সেই শ্রেণীর ( অভ্যন্তরীণ ধনুর্বন্ধনী) মধ্যে একটি প্রাথমিক ব্লক সরবরাহ করে । যেমন

new ArrayList<Integer>() {{
   add(1);
   add(2);
}};

নোট করুন যে এই ডাবল ব্রেস সূচনাটি ব্যবহারের একটি প্রভাব হ'ল আপনি বেনামে অভ্যন্তরীণ ক্লাস তৈরি করছেন। তৈরি শ্রেণীর thisআশেপাশের বাইরের শ্রেণীর অন্তর্নিহিত পয়েন্টার রয়েছে। সাধারণত কোনও সমস্যা না হলেও এটি কিছু পরিস্থিতিতে যেমন শৃঙ্খলাবদ্ধ বা আবর্জনা সংগ্রহের সময় শোকের কারণ হতে পারে এবং এটি সম্পর্কে সচেতন হওয়াও মূল্যবান।


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

4
"ম্যাজিক সিনট্যাক্স" এর মতো অনেক ভাষায় বিদ্যমান রয়েছে, উদাহরণস্বরূপ প্রায় সমস্ত সি-এর মতো ভাষা লুপগুলির জন্য "x -> 0" এর "0%" সিনট্যাক্সকে সমর্থন করে যা অদ্ভুত সহ কেবল "x--> 0" হয় স্থান স্থাপন।
জোছিম সউর 12

16
আমরা কেবল এই সিদ্ধান্তে পৌঁছাতে পারি যে "ডাবল ব্রেস আরম্ভকরণ" এর নিজস্ব উপস্থিতি নেই, এটি কেবল একটি বেনাম শ্রেণি তৈরি করার একটি সংমিশ্রণ এবং একটি ইনিশিয়াল ব্লক , যা একবার সংযুক্ত হয়ে সিনট্যাকটিকাল নির্মাণের মতো দেখায় , কিন্তু বাস্তবে এটি 'আইসন' নয় টি।
এমসি সম্রাট

ধন্যবাদ! বেনামি অভ্যন্তরীণ শ্রেণীর ব্যবহারের কারণে আমরা ডাবল ব্রেস প্রারম্ভিককরণের সাথে কিছু সিরিয়াল করিলে জিসন নালায় ফিরে আসে।
প্রদীপ এজে- এমএসএফ্ট এমভিপি

294

প্রতিবার কেউ ডাবল ব্রেস সূচনা ব্যবহার করলে, একটি বিড়ালছানা মারা যায়।

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

1. আপনি অনেক অনেক বেনামী ক্লাস তৈরি করছেন

প্রতিবার আপনি ডাবল ব্রেস প্রারম্ভিক ব্যবহারটি ব্যবহার করে একটি নতুন ক্লাস তৈরি করা হয়। যেমন এই উদাহরণ:

Map source = new HashMap(){{
    put("firstName", "John");
    put("lastName", "Smith");
    put("organizations", new HashMap(){{
        put("0", new HashMap(){{
            put("id", "1234");
        }});
        put("abc", new HashMap(){{
            put("id", "5678");
        }});
    }});
}};

... এই ক্লাস উত্পাদন করবে:

Test$1$1$1.class
Test$1$1$2.class
Test$1$1.class
Test$1.class
Test.class

এটি আপনার ক্লাসলোডারের পক্ষে বেশ কিছুটা ওভারহেড - কিছুই নয়! অবশ্যই একবার ব্যবহার করলে অবশ্যই খুব বেশি আদিতে সময় লাগবে না। তবে আপনি যদি আপনার এন্টারপ্রাইজ অ্যাপ্লিকেশন জুড়ে এই 20'000 বার করেন ... কেবলমাত্র "সিনট্যাক্স চিনির" জন্য এই সমস্ত গাদা স্মৃতি?

২. আপনি সম্ভবত একটি মেমরি ফাঁস তৈরি করছেন!

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

public class ReallyHeavyObject {

    // Just to illustrate...
    private int[] tonsOfValues;
    private Resource[] tonsOfResources;

    // This method almost does nothing
    public Map quickHarmlessMethod() {
        Map source = new HashMap(){{
            put("firstName", "John");
            put("lastName", "Smith");
            put("organizations", new HashMap(){{
                put("0", new HashMap(){{
                    put("id", "1234");
                }});
                put("abc", new HashMap(){{
                    put("id", "5678");
                }});
            }});
        }};

        return source;
    }
}

প্রত্যাবর্তিতগুলিতে Mapএখন সংলগ্ন দৃষ্টান্তের একটি রেফারেন্স থাকবে ReallyHeavyObject। আপনি সম্ভবত এটি ঝুঁকি নিতে চান না:

মেমরি ফুটো এখানে

Http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/ থেকে চিত্র

৩. আপনি ভান করতে পারেন যে জাভাতে মানচিত্রের অক্ষর রয়েছে

আপনার আসল প্রশ্নের উত্তর দেওয়ার জন্য, লোকেরা এই সিনট্যাক্সটি ব্যবহার করে ব্যবহার করছে যে জাভাতে মানচিত্রের আক্ষরিক মতো কিছু রয়েছে, বিদ্যমান অ্যারে লিটারেলের মতো:

String[] array = { "John", "Doe" };
Map map = new HashMap() {{ put("John", "Doe"); }};

কিছু লোকেরা এটিকে সিন্ট্যাক্টিক্যালি উদ্দীপক বলে মনে করতে পারেন।


11
"আপনি অনেকগুলি বেনামী ক্লাস তৈরি করছেন" - স্কলা কীভাবে বেনামে ক্লাস তৈরি করে তা দেখে, আমি খুব বেশি নিশ্চিত নই যে এটি একটি বড় সমস্যা
ব্রায়ান অ্যাগনিউ

2
স্থির মানচিত্র ঘোষণার জন্য এটি কী কার্যকর এবং দুর্দান্ত উপায় নয়? যদি কোনও হ্যাশম্যাপটি শুরু করে {{...}}এবং staticক্ষেত্র হিসাবে ঘোষণা করা হয় , কোনও সম্ভাব্য মেমরি ফাঁস হওয়া উচিত নয়, কেবল একটি বেনাম শ্রেণি এবং কোনও বদ্ধ দৃষ্টান্তের রেফারেন্স নেই, তাই না?
lorenzo-s

8
@ লরেঞ্জো-এস: হ্যাঁ, 2) এবং 3) তখন প্রয়োগ করবেন না, কেবল 1)। ভাগ্যক্রমে, জাভা 9 এর সাথে অবশেষে Map.of()সে উদ্দেশ্যে রয়েছে, তাই
লুকাশ এদার

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

41
  • প্রথম ধনুর্বন্ধনী একটি নতুন বেনামি অভ্যন্তর শ্রেণি তৈরি করে।
  • ব্রেসের দ্বিতীয় সেট ক্লাসে স্ট্যাটিক ব্লকের মতো একটি ইনস্ট্যান্সিয়ালাইজার তৈরি করে।

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

   public class TestHashMap {
    public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<String,String>(){
        {
            put("1", "ONE");
        }{
            put("2", "TWO");
        }{
            put("3", "THREE");
        }
        };
        Set<String> keySet = map.keySet();
        for (String string : keySet) {
            System.out.println(string+" ->"+map.get(string));
        }
    }

}

কিভাবে এটা কাজ করে

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

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

অধিক


24

ডাবল ব্রেস প্রারম্ভিককরণের একটি মজাদার অ্যাপ্লিকেশনটির জন্য, জাভাতে ডেমথির অ্যারে দেখুন

একটি অংশ

private static class IndustrialRaverMonkey
  extends Creature.Base {{
    life = 46;
    strength = 35;
    charisma = 91;
    weapon = 2;
  }}

private static class DwarvenAngel
  extends Creature.Base {{
    life = 540;
    strength = 6;
    charisma = 144;
    weapon = 50;
  }}

এবং এখন, BattleOfGrottoOfSausageSmellsএবং চঙ্কু বেকন জন্য প্রস্তুত থাকুন !


16

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

উদাহরণস্বরূপ ভেরিয়েবলের জন্য ইনিশিয়ালার ব্লকগুলি দেখতে স্থির ইনিশিয়ালাইজার ব্লকের মতো দেখতে, তবে স্ট্যাটিক কীওয়ার্ড ছাড়াই:

{
    // whatever code is needed for initialization goes here
}

11

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

2- এটি কেবল বেনামে ক্লাস সম্পর্কে নয় তবে সমস্ত শ্রেণীর:
প্রায় সব উত্তরই বেনামে বেনামে অভ্যন্তরীণ ক্লাস তৈরি করার সময় এটি ব্যবহৃত জিনিস talk আমি মনে করি যে উত্তরগুলি পড়া লোকেরা এই ধারণাটি পেয়ে যাবে যে বেনামি অন্তর্গত শ্রেণি তৈরি করার সময় এটি কেবল ব্যবহৃত হয়। তবে এটি সকল শ্রেণিতে ব্যবহৃত হয়। এই উত্তরগুলি দেখে মনে হচ্ছে এটি বেনাম শ্রেণীর জন্য উত্সর্গ করা কিছু ব্র্যান্ড নতুন বিশেষ বৈশিষ্ট্য এবং আমি মনে করি এটি বিভ্রান্তিকর।

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

4- নেস্টেড বেনামে ক্লাস তৈরি করা দুটি ধনুর্বন্ধনী সঙ্গে কিছুই করার নেই:
আমি একটি যুক্তি সঙ্গে একমত নই যে আপনি অনেক বেনামী ক্লাস তৈরি করেন। আপনি এগুলি তৈরি করছেন না কারণ একটি সূচনাটি ব্লক করেছে, কেবল কারণ আপনি এগুলি তৈরি করেছেন। এমনকি যদি আপনি দুটি ধনুর্বন্ধনী প্রারম্ভিক ব্যবহার না করেন তবে এগুলি তৈরি করা হবে যাতে সমস্যাগুলি আরম্ভ না করেও দেখা দেয় ... সূচনাটি প্রাথমিক উপাদানটি তৈরি করে না এমন উপাদানটি নয়।

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


9

ডাবল ব্রেস প্রারম্ভিককরণের সমস্ত নেতিবাচক প্রভাব এড়াতে যেমন:

  1. ভাঙা "সমান" সামঞ্জস্য।
  2. সরাসরি অ্যাসাইনমেন্ট ব্যবহার করার সময় কোনও চেক সম্পন্ন হয় না।
  3. সম্ভাব্য স্মৃতি ফাঁস।

পরবর্তী জিনিসগুলি করুন:

  1. বিশেষত ডাবল ব্রেস প্রারম্ভিককরণের জন্য পৃথক "বিল্ডার" শ্রেণি তৈরি করুন।
  2. ডিফল্ট মান সহ ক্ষেত্রগুলি ঘোষণা করুন।
  3. ক্লাসে অবজেক্ট তৈরির পদ্ধতি রাখুন।

উদাহরণ:

public class MyClass {
    public static class Builder {
        public int    first  = -1        ;
        public double second = Double.NaN;
        public String third  = null      ;

        public MyClass create() {
            return new MyClass(first, second, third);
        }
    }

    protected final int    first ;
    protected final double second;
    protected final String third ;

    protected MyClass(
        int    first ,
        double second,
        String third
    ) {
        this.first = first ;
        this.second= second;
        this.third = third ;
    }

    public int    first () { return first ; }
    public double second() { return second; }
    public String third () { return third ; }
}

ব্যবহার:

MyClass my = new MyClass.Builder(){{ first = 1; third = "3"; }}.create();

সুবিধাদি:

  1. সহজভাবে ব্যবহার করা।
  2. "সমান" সামঞ্জস্যতা ভাঙবেন না।
  3. আপনি নির্মাণ পদ্ধতিতে চেক সম্পাদন করতে পারেন।
  4. কোনও স্মৃতি ফাঁস হয় না।

অসুবিধা:

  • কোনটিই নয়।

এবং, ফলস্বরূপ, আমাদের কাছে সর্বদা সহজ জাভা বিল্ডার প্যাটার্ন রয়েছে।

গিথুবে সমস্ত নমুনা দেখুন: জাভা-এসএফ-বিল্ডার-সাধারণ-উদাহরণ


4

এটি - অন্যান্য ব্যবহারগুলির মধ্যে - সংগ্রহগুলি আরম্ভ করার জন্য একটি শর্টকাট। আরও জানুন ...


2
ঠিক আছে, এটির জন্য এটিই একটি অ্যাপ্লিকেশন, তবে কোনওভাবেই কেবল এটি এক নয়।
স্কেফম্যান 15

4

তুমি এরকম কিছু বোঝাতে চাও?

List<String> blah = new ArrayList<String>(){{add("asdfa");add("bbb");}};

এটি তৈরির সময় একটি অ্যারে তালিকা সূচনা (হ্যাক)


4

সংগ্রহটি আরম্ভ করার জন্য আপনি কিছু জাভা বিবৃতি লুপ হিসাবে রাখতে পারেন:

List<Character> characters = new ArrayList<Character>() {
    {
        for (char c = 'A'; c <= 'E'; c++) add(c);
    }
};

Random rnd = new Random();

List<Integer> integers = new ArrayList<Integer>() {
    {
         while (size() < 10) add(rnd.nextInt(1_000_000));
    }
};

তবে এই ক্ষেত্রে কর্মক্ষমতা প্রভাবিত করে, এই আলোচনাটি দেখুন


4

@ লুকাস ইডার দ্বারা নির্দেশিত হিসাবে সংগ্রহের দ্বৈত ধনুর্বন্ধনী শুরু করা এড়াতে হবে।

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

জাভা 9 সুবিধার পদ্ধতি চালু করেছে List.of, Set.ofএবং Map.of, যা পরিবর্তে ব্যবহার করা উচিত। তারা ডাবল-ব্রেস প্রারম্ভকালের চেয়ে দ্রুত এবং আরও দক্ষ।


0

প্রথম ধনুর্বন্ধনী একটি নতুন বেনাম শ্রেণি তৈরি করে এবং দ্বিতীয় ধনুর্বন্ধনী স্ট্যাটিক ব্লকের মতো একটি সূচনা আরম্ভকারী তৈরি করে।

অন্যরা যেমন উল্লেখ করেছে, এটি ব্যবহার করা নিরাপদ নয়।

তবে সংগ্রহ শুরু করার জন্য আপনি এই বিকল্পটি সর্বদা ব্যবহার করতে পারেন।

  • জাভা 8
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
  • জাভা 9
List<String> list = List.of("A", "B", "C");

-1

এটি ফ্ল্যাশ এবং ভিবিএসক্রিপ্টে কী-ওয়ার্ডের সাথে জনপ্রিয় তাই কার্যকর হবে। এটি কী thisএবং কী কিছুই পরিবর্তন করার একটি পদ্ধতি ।


আসলে তা না. এটি একটি নতুন ক্লাস তৈরি করা যা পরিবর্তিত করার জন্য একটি পদ্ধতি বলে মত হবে this। সিনট্যাক্সটি কেবল একটি বেনাম শ্রেণি তৈরি করে (যাতে কোনও নতুন রেফারেন্স শ্রেণীর thisঅবজেক্টের সাথে সম্পর্কিত কোনও রেফারেন্স ), এবং তারপরে {...}নতুন তৈরি হওয়া উদাহরণটি আরম্ভ করার জন্য একটি ইনিশিয়াল ব্লক ব্যবহার করে ।
গ্রিচ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.