কীভাবে @ নুলাবল এবং @ ননুল এনোটেশনগুলি আরও কার্যকরভাবে ব্যবহার করবেন?


140

আমি দেখতে পাচ্ছি @Nullableএবং @Nonnullটীকাগুলি প্রতিরোধে সহায়ক হতে পারে NullPointerExceptionতবে তারা খুব বেশি প্রচার করে না।

  • এই টীকাগুলির কার্যকারিতা ইন্ডিয়ারেশনের এক স্তরের পরে পুরোপুরি বন্ধ হয়ে যায়, তাই আপনি যদি কেবল কয়েকটি যুক্ত করেন তবে এগুলি খুব দূরে প্রচার করে না।
  • যেহেতু এই টীকাগুলি কার্যকরভাবে প্রয়োগ করা হয়নি তাই মানটি চিহ্নিত করার ঝুঁকি রয়েছে যার সাথে চিহ্নিত মানটি @Nonnullনাল নয় এবং ফলস্বরূপ নাল চেকগুলি সম্পাদন করা হচ্ছে না।

নিচের কোড একটি প্যারামিটার দিয়ে চিহ্নিত ঘটায় @Nonnullহতে nullকোনো অভিযোগ উত্থাপন ছাড়াই। এটি NullPointerExceptionচালিত হলে এটি ছুড়ে দেয় ।

public class Clazz {
    public static void main(String[] args){
        Clazz clazz = new Clazz();

        // this line raises a complaint with the IDE (IntelliJ 11)
        clazz.directPathToA(null);

        // this line does not
        clazz.indirectPathToA(null); 
    }

    public void indirectPathToA(Integer y){
        directPathToA(y);
    }

    public void directPathToA(@Nonnull Integer x){
        x.toString(); // do stuff to x        
    }
}

এই টীকাগুলি আরও কঠোরভাবে প্রয়োগ করার এবং / বা আরও প্রচার করার কোনও উপায় আছে কি?


1
আমি ধারণা মত @Nullableবা @Nonnull, কিন্তু যদি তারা মূল্য খুবই "সম্ভবত অনুরোধ করা বিতর্কে" হয়
মার্টেন Bodewes

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

1
@ থিওডোরমুরডক, হ্যাঁ, জাভা 8-তে একটি কাস্ট (@NonNull Integer) yসিন্টেক্সিকভাবে সম্ভব, তবে একটি সংকলককে টীকা অনুসারে কোনও নির্দিষ্ট বাইট কোড নির্গত করার অনুমতি নেই। রানটাইম সংবেদনের জন্য ক্ষুদ্র সহায়ক সহায়তার পদ্ধতিগুলি যেমন bugs.eclipse.org/442103 (যেমন, directPathToA(assertNonNull(y))) তে আলোচনা করা যথেষ্ট - তবে মনে রাখবেন, এটি কেবল দ্রুত ব্যর্থ হতে সহায়তা করে। একমাত্র নিরাপদ উপায় হ'ল আসল নাল চেক (প্লাস আশা করি অন্য শাখায় বিকল্প বাস্তবায়ন) performing
স্টিফান হার্ম্যান

1
একাধিক অনুরূপ বিরক্তি রয়েছে বলে আপনি @Nonnullএবং @Nullableআপনি কোন বিষয়ে কথা বলছেন তা এই প্রশ্নের পক্ষে সহায়ক হবে ( এই প্রশ্নটি দেখুন )। আপনি কি প্যাকেজে টীকা নিয়ে কথা বলছেন javax.annotation?
জেমস ডান

1
@ টিজেমসবুন এই প্রশ্নের প্রসঙ্গে যে বিষয়টি বিবেচনা করা যায় তা নয়, এটি তাদের কার্যকরভাবে কীভাবে ব্যবহার করতে হবে তা সম্পর্কে ছিল।
মাইক রাইল্যান্ডার

উত্তর:


66

সংক্ষিপ্ত উত্তর: আমি অনুমান করি যে এই টিকাগুলি কেবল আপনার আইডিইর জন্য আপনাকে সম্ভাব্য নাল পয়েন্টার ত্রুটি সম্পর্কে সতর্ক করতে কার্যকর are

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

আরেকটি ভাল টিপ কখনই নাল মানগুলি ফিরিয়ে দেয় না, তবে পরিবর্তে নাল অবজেক্ট প্যাটার্ন ব্যবহার করে।


10
প্রত্যাবর্তনের মান সম্ভবত খালি থাকার জন্য, আমি দৃ Optionalplain null
প্যাট্রিক

7
Nচ্ছিক "নাল" এর চেয়ে ভাল নয়। #চ্ছিক # পান () নুশ-এর ব্যবহার নালপয়েন্টারএক্সসেপশন নিক্ষেপ করার সময় NoSuchElementException নিক্ষেপ করে। উভয়ই অর্থবহ বর্ণনা ছাড়াই রানটাইম এক্সেকশন এর। আমি nallable পরিবর্তনশীল পছন্দ।
শে

4
@ 30 তম আপনি কেন Optional.get () সরাসরি এবং অপশনাল.আইসপ্রেসড () বা ptionচ্ছিক.ম্যাপটি প্রথমে ব্যবহার করবেন না?
গৌরভজে

7
@ গৌরভজে আপনি কেন প্রথমে নালার পরিবর্তনশীল ব্যবহার করবেন এবং চেক করবেন না, যদি এটি প্রথমে বাতিল হয়? ;-)
30

5
Optionalএই ক্ষেত্রে পার্থক্য এবং naclable পার্থক্য হ'ল Optionalভাল যোগাযোগ যে এই মান ইচ্ছাকৃতভাবে খালি হতে পারে। অবশ্যই, এটি কোনও যাদু কাঠি নয় এবং রানটাইমের সময় এটি হ্রাসযোগ্য ভেরিয়েবলের ঠিক ঠিক একইভাবে ব্যর্থ হতে পারে। তবে প্রোগ্রামার দ্বারা এপিআই অভ্যর্থনা Optionalআমার মতে আরও ভাল ।
ব্যবহারকারী 1053510

31

আপনার আইডিই ছাড়া আপনি ইঙ্গিতগুলি দেওয়ার সময় আপনি nullএমন পদ্ধতিগুলি পাস করেন যেগুলি আর্গুমেন্টটি বাতিল নয় বলে আশা করে, আরও আরও সুবিধা রয়েছে:

  • স্ট্যাটিক কোড বিশ্লেষণ সরঞ্জামগুলি আপনার আইডিই (যেমন ফাইন্ডব্যাগ) এর মতো পরীক্ষা করতে পারে
  • আপনি এই দাবিগুলি পরীক্ষা করতে AOP ব্যবহার করতে পারেন

এটি আপনার কোডটিকে আরও রক্ষণাবেক্ষণে সহায়তা করতে পারে (যেহেতু আপনার nullচেকের দরকার নেই ) এবং ত্রুটি-প্রবণতা কম।


9
আমি এখানে ওপিটির প্রতি সহানুভূতি জানাই, কারণ আপনি এই দুটি সুবিধা উল্লেখ করলেও, উভয় ক্ষেত্রেই আপনি "ক্যান" শব্দটি ব্যবহার করেছেন। তার মানে এই যে চেকগুলি আসলে ঘটবে এমন কোনও গ্যারান্টি নেই। এখন, যে আচরণগত পার্থক্য হল যে আপনি উৎপাদন মোড, যার জন্য আছে আমরা চলমান এড়াতে চাই কর্মক্ষমতা সংবেদনশীল পরীক্ষার জন্য উপযোগী হতে পারে assert। আমি দরকারী ধারণা পেয়েছি @Nullableএবং @Nonnullহতে পেরেছি, তবে তাদের সাথে কেউ কী করতে পারে সে সম্পর্কে আমাদের হাইপোটাইসেশন করা না করে তাদের পিছনে আরও জোর চাই , যা এখনও তাদের সাথে কিছুই না করার সম্ভাবনা উন্মুক্ত করে।
সেহ

2
প্রশ্নটি কোথায় শুরু হবে। এই মুহুর্তে তার অ্যান্টেশনগুলি alচ্ছিক। সোমটাইমস আমি এটি চাই যদি তারা না হয় কারণ কিছু পরিস্থিতিতে তাদের প্রয়োগ করা সহায়ক হবে ...
উয়ে প্লোনাস

আপনি জিজ্ঞাসা করতে পারেন যে আপনি এখানে কীভাবে উল্লেখ করছেন?
ক্রিস.জু

@ ক্রিস.জু এওপি অর্থ দিক ভিত্তিক প্রোগ্রামিং, উদাহরণস্বরূপ AspectJ
উও প্লোনাস

13

আমি মনে করি এই আসল প্রশ্নটি অপ্রত্যক্ষভাবে একটি সাধারণ সুপারিশকে নির্দেশ করে যে রান-টাইম নাল-পয়েন্টার চেকটি এখনও প্রয়োজন, যদিও @ নননুল ব্যবহৃত হয়। নিম্নলিখিত লিঙ্কটি দেখুন:

জাভা 8 এর নতুন প্রকারের টীকাগুলি

উপরের ব্লগে, এটি প্রস্তাবিত যে:

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


1
বোঝা গেছে, কিন্তু ডিফল্ট লিন্ট চেকগুলি সতর্ক করে দেয় যে রানটাইম নাল চেকগুলি অপ্রয়োজনীয়, যা প্রথমে মনে হয় এই প্রস্তাবনাটিকে নিরুৎসাহিত করবে।
18:30

1
@ সুইবুबी সাধারণত আমার কোডটি সঠিক কিনা তা আমি লিন্টের সতর্কতাগুলিকে অগ্রাহ্য করি। এই সতর্কতাগুলি ত্রুটি নয়।
জোনাথনজ

12

অনুগ্রহ করে 1.8 অনুসারে অ্যালিপসে আসল উদাহরণটি সংকলন করুন এবং টীকাগুলি ভিত্তিক নাল বিশ্লেষণ সক্ষম করে, আমরা এই সতর্কতাটি পাই:

    directPathToA(y);
                  ^
Null type safety (type annotations): The expression of type 'Integer' needs unchecked conversion to conform to '@NonNull Integer'

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

এবং একটি চালাক ব্যবহার করার সময় @NonNullByDefault করার সময় আমাদের এমনকি এটি প্রতিবার বলতে হবে না।

অন্য কথায়: নাল টীকাগুলি "খুব দূরে প্রচার করা" আপনি যে সরঞ্জামটি ব্যবহার করছেন তার উপর এবং সেই সরঞ্জাম দ্বারা জারি করা সমস্ত সতর্কবাণীগুলিতে আপনি কতটা কঠোরভাবে উপস্থিত হন তার উপর নির্ভর করে। সঙ্গে TYPE_USE নাল টীকা আপনি পরিশেষে টুল সম্পর্কে আপনাকে সতর্ক দিন বিকল্প আছে যে আপনার প্রোগ্রাম সম্ভব NPE, কারণ nullness টাইপ পদ্ধতির একটি intrisic সম্পত্তি পরিণত হয়েছে।


8

আমি সম্মত হই যে টীকাগুলি "খুব বেশি প্রচার করে না"। যাইহোক, আমি প্রোগ্রামারটির পক্ষে ভুলটি দেখছি।

আমি Nonnullডকুমেন্টেশন হিসাবে টীকাটি বুঝতে পারি । নিম্নলিখিত পদ্ধতিটি প্রকাশ করে যা প্রয়োজন (পূর্বশর্ত হিসাবে) একটি নন-নাল আর্গুমেন্ট x

    public void directPathToA(@Nonnull Integer x){
        x.toString(); // do stuff to x        
    }

নীচের কোড স্নিপেটে একটি বাগ রয়েছে। পদ্ধতিটি directPathToA()প্রয়োগ না করে কল করে yযা অ-শূন্য (এটি, এটি বলা পদ্ধতির পূর্বশর্তের নিশ্চয়তা দেয় না)। একটি সম্ভাবনা হ'ল (পূর্ব শর্ত প্রচার) এর Nonnullসাথে একটি টীকা যুক্ত করা indirectPathToA()। সম্ভাবনা দুই অকার্যকরতা জন্য চেক করতে হয় yমধ্যে indirectPathToA()এবং থেকে কল এড়াতে directPathToA()যখন yনাল হয়।

    public void indirectPathToA(Integer y){
        directPathToA(y);
    }

1
প্রচারের @Nonnull আছে indirectPathToA(@Nonnull Integer y)এই প্রোগ্রামটিতে একটি খারাপ অভ্যাস: আপনি পূর্ণ কল স্ট্যাক (যাতে আপনি আপনার যোগ যদি উপর প্রসারণ mainain করতে হবে nullচেক directPathToA(), আপনি প্রতিস্থাপন করতে হবে @Nonnullদ্বারা @Nullableপূর্ণ কল স্ট্যাকের মধ্যে)। এটি বৃহত অ্যাপ্লিকেশনগুলির জন্য রক্ষণাবেক্ষণের বিশাল প্রচেষ্টা হবে।
জুলিয়েন ক্রোনেগ

@ ননল টীকাগুলি কেবলমাত্র জোর দেয় যে আর্গুমেন্টের নাল-যাচাই আপনার পক্ষে রয়েছে (আপনাকে গ্যারান্টি দিতে হবে যে আপনি নাল-মানটি পাস করেছেন)। এটি পদ্ধতির দায়িত্ব নয়।
আলেকজান্ডার দ্রোবিশেভস্কি

@ নননুলও বোধগম্য জিনিস যখন নাল-মানটি এই পদ্ধতির জন্য কোনও অর্থ বোধ করে না
আলেকজান্ডার দ্রোবিশেভস্কি

5

আমি আমার প্রকল্পগুলিতে যা করি তা হ'ল "কনস্ট্যান্ট শর্তাদি এবং ব্যতিক্রমগুলি" কোড নিরীক্ষণে নিম্নলিখিত বিকল্পটি সক্রিয় করা:
এমন পদ্ধতিগুলির জন্য @ নোটযোগ্য টিকাটি প্রস্তাব করুন যা সম্ভবত শূন্য ফিরে আসতে পারে এবং অ-টিকা-পরামিতিগুলিতে পাস হওয়া অযোগ্য মানগুলি প্রতিবেদন করতে পারে পরিদর্শন

যখন সক্রিয় করা হয়, সমস্ত অ-টিকা পরামিতিগুলি নন-নাল হিসাবে বিবেচিত হবে এবং এইভাবে আপনি আপনার পরোক্ষ কলটিতে একটি সতর্কতাও দেখতে পাবেন:

clazz.indirectPathToA(null); 

এমনকি শক্তিশালী চেক জন্য যাচাইকারী ফ্রেমওয়ার্ক হতে পারে একটি ভাল পছন্দ (এই চমৎকার দেখতে টিউটোরিয়াল
নোট : আমি যা এখনও ব্যবহার করেন নি এবং সেখানে জ্যাক কম্পাইলার সঙ্গে সমস্যা হতে পারে: দেখুন এই বার্জপোর্ট


4

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


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

আপনি যদি জেডিকে 8 বা ততোধিক নতুনকে টার্গেট করছেন তবে java.util.Optionalপেয়ারা ক্লাসের পরিবর্তে ব্যবহার করতে পছন্দ করুন । পার্থক্য সম্পর্কে বিশদ জন্য পেয়ারা নোট / তুলনা দেখুন
অ্যান্ড্রুএফ

1
আপনি সম্প্রসারিত করতে পারেন, তারপর, কি বিন্দুতে "নাল চেক উপস্থিতি যা বিন্দু ব্যার্থ জন্য চেক দিয়ে প্রতিস্থাপিত" হয় ? এটি আমার মতে বিকল্পগুলির একমাত্র কারণ নয় , তবে এটি অবশ্যই সবচেয়ে বড় এবং সেরা একটি one
স্কাব্বো

4

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

জাভা ক্লাস ব্যবহার করে @NotNullটীকা

public class MyJavaClazz {
    public void foo(@NotNull String myString) {
        // will result in an NPE if myString is null
        myString.hashCode();
    }
}

কোটলিন ক্লাস জাভা ক্লাসে কল করছে এবং @ নটনুল দিয়ে টীকাযুক্ত আর্গুমেন্টের জন্য নাল পাস করছে

class MyKotlinClazz {
    fun foo() {
        MyJavaClazz().foo(null)
    }
}  

কোটলিন সংকলক ত্রুটিটি প্রয়োগ করে @NotNull টীকা ।

Error:(5, 27) Kotlin: Null can not be a value of a non-null type String

দেখুন: http://kotlinlang.org/docs/references/java-interop.html#nullability-Anotations


3
প্রশ্নটি তার প্রথম ট্যাগ অনুযায়ী জাভা, এবং কোটলিনকে নয় addresses
Seh

1
@ এই উত্তরটি এই প্রশ্নের সাথে কেন প্রাসঙ্গিক, তার আপডেট দেখুন।
মাইক রাইল্যান্ডার

2
যথেষ্ট ফর্সা। এটি কোটলিনের একটি দুর্দান্ত বৈশিষ্ট্য। আমি কেবল মনে করি না যে এটি জাভা সম্পর্কে শিখতে এখানে আসা লোকদের সন্তুষ্ট করবে।
Seh

প্যারামিটারে যোগ না করা myString.hashCode()থাকলেও অ্যাক্সেস করা এখনও এনপিই নিক্ষেপ করবে @NotNull। সুতরাং এটি যুক্ত সম্পর্কে আরও নির্দিষ্ট কি?
kAmol

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

-4

যেহেতু জাভা 8 নতুন বৈশিষ্ট্য ঐচ্ছিক আপনি আর আপনার নিজের কোডে @Nullable বা @Notnull ব্যবহার করা উচিত নয় । নীচের উদাহরণটি ধরুন:

public void printValue(@Nullable myValue) {
    if (myValue != null) {
        System.out.print(myValue);
    } else {
        System.out.print("I dont have a value");
}

এটি দিয়ে আবার লেখা যেতে পারে:

public void printValue(Optional<String> myValue) {
    if (myValue.ifPresent) {
        System.out.print(myValue.get());
    } else {
        System.out.print("I dont have a value");
}

একটি option চ্ছিক ব্যবহার আপনাকে নাল মান পরীক্ষা করতে বাধ্য করে । উপরের কোডে আপনি কেবলমাত্র কল করে মানটি অ্যাক্সেস করতে পারবেনget পদ্ধতিতে ।

আরেকটি সুবিধা হ'ল কোডটি আরও পঠনযোগ্য । জাভা 9 ইফপ্রেসট্রঅরলিজ যোগ করার সাথে , ফাংশনটি এমনও লেখা যেতে পারে:

public void printValue(Optional<String> myValue) {
    myValue.ifPresentOrElse(
        v -> System.out.print(v),
        () -> System.out.print("I dont have a value"),
    )
}

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