প্রয়োজনীয় পদ্ধতির পরামিতিগুলির জন্য দৃ ?়তা বা অবৈধআর্গুমেন্ট এক্সেকশন ব্যবহার করা কি ভাল?


87

জাভাতে, কোনটি আরও বেশি প্রস্তাবিত, এবং কেন? উভয় প্রকারেরই ব্যতিক্রম ছুঁড়ে ফেলবে, তাই সে ক্ষেত্রে তাদের পরিচালনা করা সমান। assertসামান্য খাটো, তবে আমি নিশ্চিত না যে এটি কতটা গুরুত্বপূর্ণ।

public void doStuff(Object obj) {
    assert obj != null;
    ...
}

বনাম

public void doStuff(Object obj) {
    if (obj == null) {
        throw new IllegalArgumentException("object was null");
    }
    ...
}

obj.hashCode()পরিবর্তে আমি একটি সহজ পছন্দ করি ;-)
মার্কো

উত্তর:


117

হুঁশিয়ার!

রান কোডে জোরগুলি সরিয়ে ফেলা হয় যদি না আপনি আপনার কোডটি সংকলনের সময় স্পষ্টতই " দৃ as়তা সক্ষম করুন" নির্দিষ্ট করে থাকেন। জাভা অ্যাসারেন্সগুলি উত্পাদন কোডে ব্যবহার করা হবে না এবং এটি ব্যক্তিগত পদ্ধতিতে সীমাবদ্ধ করা উচিত ( ব্যতিক্রম প্রতিবেদন দেখুন ), যেহেতু ব্যক্তিগত পদ্ধতিগুলি কেবল বিকাশকারীদের দ্বারা জানা এবং ব্যবহৃত হবে বলে আশা করা হচ্ছে। এছাড়াও AssertionErrorassert নিক্ষেপ করবে যা প্রসারিত হয় না এবং যা সাধারণত নির্দেশ করে যে আপনার খুব অস্বাভাবিক ত্রুটি রয়েছে (যেমন "আউটআফমিউরিওর" যা পুনরুদ্ধার করা শক্ত, তাই না?) আপনি চিকিত্সা করতে সক্ষম হবেন বলে আশা করা যায় না।ErrorException

"দৃ enable়তাগুলি সক্ষম করুন" পতাকাটি সরান, এবং একটি ডিবাগারের সাথে পরীক্ষা করুন এবং আপনি দেখতে পাবেন যে আপনি অবৈধআর্গুমেন্টএক্সেপশন থ্রো কলটিতে পদক্ষেপ নেবেন না ... যেহেতু এই কোডটি সংকলিত হয়নি (আবার "যখন" এ "সরানো হবে)

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

Assert.notNull(obj, "object was null");

... যা আপনার দ্বিতীয় উদাহরণে লিখেছিলেন ঠিক একই কোডটি কার্যকর করবে। যেমন কয়েক অন্যান্য দরকারী পদ্ধতি আছে hasText, hasLengthসেখানে।

আমি প্রয়োজনের চেয়ে বেশি কোড লেখা পছন্দ করি না, তাই আমি যখন খুশি লিখি যখন আমি লিখিত লাইনের সংখ্যা 2 (2 লাইন> 1 লাইন) দ্বারা হ্রাস করি :-)


আহ, আমি দৃser়তাগুলি মুছে ফেলা সম্পর্কে ভুলে গেছি! দুর্দান্ত উত্তর। অন্য কিছু আসে কিনা তা দেখার জন্য আমি কিছুটা অপেক্ষা করব, তবে তা গ্রহণ করুন :)
ডেইনিথ

2
মনে রাখবেন যে এমন কোনও পতাকা নেই যা সংকলন সময়ে দৃser়তাগুলি সরিয়ে দেয় (যদিও শর্তসাপেক্ষ প্রশংসার মাধ্যমে সেগুলি সরানো যেতে পারে )। দাবিগুলি রানটাইম এ ডিফল্টরূপে অক্ষম থাকে (আমার মনে হয় জেভিএম এগুলি NOOP হিসাবে বিবেচনা করে) তবে java -eaপ্রোগ্রামের মাধ্যমে এবং সক্ষম করা যায় । @ জালেন আমার কাছে মনে হয় প্রোডাকশন কোডে দৃser় বিশ্বাস থাকা পুরোপুরি বৈধ, কারণ তারা ক্ষেত্রটি ডিবাগিংয়ের
জাস্টিন মুলার

@ জালেন, -১। সংকলক আসক্তি কোড সরিয়ে দেয় না । যদিও আপনি সিএমডি না করলে এগুলি চালিত হবে না java -ea
পেসারিয়ার

5
আপনি যখন ব্যবহার করতে পারেন তখন বসন্ত কাঠামোর দরকার নেইObjects.requreNonNull
camunctious

46

আপনার একটি ব্যতিক্রম ব্যবহার করা দরকার। একটি দৃser়তা ব্যবহার করা বৈশিষ্ট্যটির অপব্যবহার হবে।

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

উদাহরণস্বরূপ, একটি জোর

assert myConnection.isConnected();

এর অর্থ "আমি জানি যে এই কোডের দিকে পরিচালিত প্রতিটি কোড পাথ নিশ্চিত করে যে myConnectionএটি সংযুক্ত রয়েছে; যদি উপরের কোডটি কোনও বৈধ সংযোগ পেতে ব্যর্থ হয় তবে এটি একটি ব্যতিক্রম ছুঁড়ে ফেলা উচিত ছিল বা এই বিন্দুতে পৌঁছানোর আগে ফিরে আসতে হবে।"

অন্যদিকে, একটি চেক

if (!myConnection.isConnected()) {
    throw new IllegalArgumentException("connection is not established");
}

এর অর্থ "সংযোগ স্থাপন না করেই আমার লাইব্রেরি কল করা একটি প্রোগ্রামিং ত্রুটি" "


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

4
চমৎকার পয়েন্ট "চেক করা ব্যতিক্রমগুলি আপনার লাইব্রেরির ব্যবহারকারীদের প্রোগ্রামিং ত্রুটিগুলি সনাক্ত করার জন্য ডিজাইন করা হয়েছে, যখন দৃser়তাগুলি আপনার নিজস্ব যুক্তিতে ত্রুটিগুলি সনাক্ত করার জন্য ডিজাইন করা হয়েছে These এগুলি পৃথক সমস্যা যা মিশ্রিত হওয়া উচিত নয়" "
অসীম গাফফার

সত্য, তবে এটি ধরে নেয় ওপি একটি লাইব্রেরি লিখছে। যদি তাদের কোডটি কেবল অভ্যন্তরীণ ব্যবহারের জন্য থাকে তবে একটি প্রতিস্থাপন গ্রহণযোগ্য।
ব্যবহারকারী 949300

11

আপনি যদি এমন কোনও ফাংশন লিখছেন যা nullবৈধ প্যারামিটার মান হিসাবে অনুমতি দেয় না , আপনার @Nonnullস্বাক্ষরে টীকাগুলি যুক্ত করা উচিত এবং Objects.requireNonNullযুক্তিটি কিনা তা যাচাই করতে ব্যবহার করুন nullএবং NullPointerExceptionযদি এটি হয় তবে একটি নিক্ষেপ করুন । @Nonnullটীকা ডকুমেন্টেশন জন্য এবং কিছু ক্ষেত্রে কম্পাইল সময়ে সহায়ক সতর্কবার্তা প্রদান করবে। এটি nullরানটাইমে পাস হতে বাধা দেয় না ।

void doStuff(@Nonnull Object obj) {
    Objects.requireNonNull(obj, "obj must not be null");

    // do stuff...
}

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


নির্দেশ করার জন্য ধন্যবাদ Objects.requireNonNull(), যা আমার কাছে নতুন ছিল। আপনি কি জানেন যে কোথাও অনুরূপ "রিকুয়েস্টট্রু ()" বা "প্রয়োজনীয় একুয়াল ()" পদ্ধতি আছে কিনা? স্প্রিংয়ের দাবির বিরুদ্ধে কিছুই নয় তবে সকলেই এটি ব্যবহার করছে না।
user949300

@ ব্যবহারকারী949300 Objects.requireNonNull()আর্গুমেন্ট বৈধতার জন্য। যদি কোনও যুক্তির কোনও trueকিছুর সমান বা সমান হতে হয় তবে তর্কটি অর্থহীন। অবৈধ আর্গুমেন্ট ছাড়া অন্য ত্রুটি ক্ষেত্রে, যদি আপনি উচিত throwএকটি Exceptionআরো নিখুঁতভাবে ত্রুটি বর্ণনা করে। JUnit এছাড়াও আছে Assertকিন্তু এটি পরীক্ষার জন্য।
অস্পষ্ট

আমি আরও মত ভাবছিলাম, স্কোয়ার রুট ফাংশন Objects.requireTrue(x >= 0.0);, বা কিছু হ্যাশের জন্য Objects.requireEquals(hash.length == 256)
বলুন

আমাকে কোন @ ননল ব্যবহার করতে হবে? জাভাক্স.অডিয়ালিটি.কন্ট্রেন্টস.নোট নল?
Aguid

আমি Eclipse JDT টীকাটি ব্যবহার করব , কারণ সেগুলি চালাক ছেলেরা তৈরি করেছে :)। ডকুমেন্টেশন: help.eclipse.org/neon/… - এগুলি ব্যবহারের জন্য আপনি ইন্টেলিজকে কনফিগারও করতে পারেন।
কোপ্পর

2

আমি সবসময় দৃser়তার চেয়ে অবৈধআর্গুমেন্ট এক্সেকশনটি পছন্দ করি।

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

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


5
জুনিতের প্রায় 40 বছর পূর্বে জোর দাবি ছিল - এসিআরটি ম্যাক্রো সম্পর্কে কোনও সি প্রোগ্রামারকে জিজ্ঞাসা করুন।
জেবিআরওয়িলকিনসন

3
এই প্রশ্নটি গ সম্পর্কে নয়; এটি জাভা সম্পর্কে। তাই আমি জাভা প্রসঙ্গে জবাব দিয়েছি।
rai.skumar

আস্রেট (সংরক্ষিত কীওয়ার্ড) বনাম আসর্ট (জুনিত শ্রেণি) গুলিয়ে ফেলবেন না তারা উভয়ই একটি ভেরিয়েবলের উপর একটি চেক সঞ্চালনের জন্য ব্যবহৃত হয় তবে এর বাইরে তারা দুটি খুব আলাদা জিনিস এবং খুব আলাদাভাবে আচরণ করে।
নিউটোপিয়ান

1

আইএমও দ্বিতীয়টি কিছুটা ভাল কারণ এটি আরও তথ্য নিয়ে আসে এবং আরও বর্ধিত হতে পারে (যেমন ব্যতিক্রম শ্রেণির প্রসারিত করে) আরও তথ্যবহুল হতে পারে, এটি নেতিবাচক তুলনাও ব্যবহার করে না যা বোঝা সহজ।


1

আমি প্রচুর এজেন্ট ব্যবহার করি না, তবে লম্বক @ নননুলের সাথে সাধারণ পদ্ধতির: https://projectlombok.org/features/NonNull

লম্বোক বাস্তবায়ন: আমদানি lombok.NonNull;

public class NonNullExample extends Something {
  private String name;

  public NonNullExample(@NonNull Person person) {
    super("Hello");
    this.name = person.getName();
  }
}

জাভা সংস্করণ:

 import lombok.NonNull;

public class NonNullExample extends Something {
  private String name;

  public NonNullExample(@NonNull Person person) {
    super("Hello");
    if (person == null) {
      throw new NullPointerException("person");
    }
    this.name = person.getName();
  }
}

লম্পোক সত্যিই বেশ সুন্দর লাইব্রেরি যা আমি সর্বত্র ব্যবহার করি

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