বর্তমানে সম্পাদনকারী পদ্ধতির নাম অর্জন করা


উত্তর:


177

Thread.currentThread().getStackTrace()আপনি যে পদ্ধতি থেকে কল করছেন তার মধ্যে সাধারণত সেই পদ্ধতি থাকবে তবে এতে অসুবিধাগুলি রয়েছে ( জাভাদোক দেখুন ):

কিছু ভার্চুয়াল মেশিন, কিছু পরিস্থিতিতে স্ট্যাক ট্রেস থেকে এক বা একাধিক স্ট্যাক ফ্রেম বাদ দিতে পারে। চরম ক্ষেত্রে, এই থ্রেড সম্পর্কিত কোনও স্ট্যাক ট্রেস তথ্য নেই এমন ভার্চুয়াল মেশিনকে এই পদ্ধতি থেকে শূন্য দৈর্ঘ্যের অ্যারে ফেরত দেওয়ার অনুমতি দেওয়া হয়।


7
ব্যতিক্রম স্ট্যাক ট্রেস জন্য এই একই ক্ষতি কি সত্য?
নাট পার্সনস

8
হ্যাঁ, তাই ডকুমেন্টেশন নিক্ষেপযোগ্য । [GetStackTrace ()] ( download.oracle.com/javase/1.5.0/docs/api/java/lang/... সঠিক একই অনুচ্ছেদ রয়েছে।
Bombe

4
অন্তর্নিহিত জিনিসটি হল যে জেভিএমকে স্ট্যাকট্রেস সরবরাহ করতে সক্ষম হওয়া প্রয়োজন নয় , তবে হটস্পটকে খুব নির্ভরযোগ্য করে তোলার জন্য প্রচুর কাজ চলে গেছে। আপনার জানতে হবে, যদিও আপনি যদি চান যে আপনার কোডটি কোনও নির্দিষ্ট জেভিএমের আচরণের উপর নির্ভর না করে।
থরবজর্ন রাভন অ্যান্ডারসন

নীচে অ্যালেক্সসমেলের সংস্করণ কোনও স্ট্যাক ট্রেস তৈরি করে না এবং আপনাকে কেবল নাম নয় (যাতে আপনি রিটার্নের প্রকারটিও জানতে পারেন) প্রকৃত পদ্ধতি অবজেক্টটিতে অ্যাক্সেস দেয়। আমার বেঞ্চ চিহ্নিত করা হয়নি তবে আমি সন্দেহ করি যে তার পদ্ধতিটি খুব দ্রুততর কারণ স্ট্যাকের চিহ্নগুলি ব্যয়বহুল হয়ে থাকে।
Gus

ডেভিনের প্রতিক্রিয়া মনে হয় এই প্রশ্নের আরও একটি সুসংগত উত্তর দেয়।
রাইজিংটাইড

310

প্রযুক্তিগতভাবে এটি কাজ করবে ...

String name = new Object(){}.getClass().getEnclosingMethod().getName();

তবে সংকলনের সময় একটি নতুন বেনামি অভ্যন্তর শ্রেণি তৈরি করা হবে (উদাঃ) YourClass$1.class ) এর । সুতরাং এটি .classপ্রতিটি পদ্ধতির জন্য একটি ফাইল তৈরি করবে যা এই কৌশলটি মোতায়েন করে। অতিরিক্তভাবে রানটাইমের সময় প্রতিটি অনুরোধে একটি অন্যথায় অব্যবহৃত অবজেক্ট উদাহরণ তৈরি করা হয়। সুতরাং এটি একটি গ্রহণযোগ্য ডিবাগ ট্রিক হতে পারে, তবে এটি উল্লেখযোগ্য ওভারহেডের সাথে আসে।

এই কৌশলটির একটি সুবিধা এটি that getEncosingMethod() রিটার্নগুলি java.lang.reflect.Methodটীকাগুলি এবং প্যারামিটারের নাম সহ পদ্ধতির সমস্ত অন্যান্য তথ্য পুনরুদ্ধার করতে ব্যবহার করা যেতে পারে। এটি একই নামের (পদ্ধতি ওভারলোড) দ্বারা নির্দিষ্ট পদ্ধতির মধ্যে পার্থক্য করা সম্ভব করে।

নোট করুন জাভাডক অনুযায়ী getEnclosingMethod() এই একটি SecurityExceptionঅভ্যন্তর শ্রেণি একই শ্রেণীর লোডার ব্যবহার করে লোড করা উচিত নয় । সুতরাং কোনও সুরক্ষা ব্যবস্থাপক উপস্থিত থাকলেও অ্যাক্সেস শর্তাদি পরীক্ষা করার প্রয়োজন নেই।

এটি getEnclosingConstructor()নির্মাণকারীদের জন্য ব্যবহার করা প্রয়োজন । (নামযুক্ত) পদ্ধতির বাইরে থাকা ব্লকগুলির সময়, getEnclosingMethod()ফিরে আসে null


9
এটি আপনাকে বর্তমানে সম্পাদন পদ্ধতি দেয় না। এটি আপনাকে সেই পদ্ধতিটি দেবে যাতে কোনও বেনামে / স্থানীয় শ্রেণি সংজ্ঞায়িত করা হয়। - docs.oracle.com/javase/6/docs/api/java/lang/…
shrini1000

7
স্থানীয় ক্লাস}}; স্ট্রিংয়ের নাম = স্থানীয়.class.getEnclosingMethod ()। GetName ();
অ্যালেক্সমেল

21
@ shrini1000 ধারণাটি হ'ল এই স্নিপেটটি যেখানে তথ্য প্রয়োজন সেখানে ব্যবহার করা এবং এটি কোনও লাইব্রেরির রুটিনে না রেখে।
থরবজর্ন রাভন অ্যান্ডারসন

4
টিপস জন্য ধন্যবাদ! একটি নতুন অবজেক্ট তৈরির পরিবর্তে, কেবল এই.টিজক্লাস () ব্যবহার করুন। GetEnclosingMethod ()। GetName ();
লিলো

3
@ লিলো ভুল getEnclosingMethodশ্রেণীর সংজ্ঞায়িত পদ্ধতিটির নাম পাওয়া যায়। this.getClass()আপনাকে কিছুটা সাহায্য করবে না @ Wutzebaer- এর জন্য আপনার এমনকি কেন প্রয়োজন হবে? আপনি ইতিমধ্যে তাদের অ্যাক্সেস আছে।
হ্যাজেল ট্রস্ট 20'17

134

জানুয়ারী ২০০৯:
একটি সম্পূর্ণ কোড হবে ( @ বোম্বের সতর্কতা অবলম্বন করে ব্যবহার করার জন্য):

/**
 * Get the method name for a depth in call stack. <br />
 * Utility function
 * @param depth depth in the call stack (0 means current method, 1 means call method, ...)
 * @return method name
 */
public static String getMethodName(final int depth)
{
  final StackTraceElement[] ste = Thread.currentThread().getStackTrace();

  //System. out.println(ste[ste.length-depth].getClassName()+"#"+ste[ste.length-depth].getMethodName());
  // return ste[ste.length - depth].getMethodName();  //Wrong, fails for depth = 0
  return ste[ste.length - 1 - depth].getMethodName(); //Thank you Tom Tresansky
}

আরো এই প্রশ্নের

ডিসেম্বর ২০১১ আপডেট করুন:

নীল মন্তব্য:

আমি জেআরই 6 ব্যবহার করি এবং আমাকে ভুল পদ্ধতির নাম দেয়।
আমি যদি লিখি তবে এটি কাজ করেste[2 + depth].getMethodName().

  • 0হয় getStackTrace(),
  • 1হয় getMethodName(int depth)এবং
  • 2 প্রার্থনা পদ্ধতি।

কুমারী 47 এর উত্তর ( upvated ) আসলে পদ্ধতির নাম ফিরে পেতে প্রয়োগ করতে সঠিক সূচককে গণনা করে।


2
এটি কেবল আমার জন্য "প্রধান" বলে। : - /
অধ্যাপক ফ্যালকেন চুক্তি

@ অভিবাসী: আপনি কি StackTraceElementডিবাগিংয়ের উদ্দেশ্যে সমস্ত অ্যারে প্রিন্ট করার চেষ্টা করেছিলেন এবং 'মেন' আসলে সঠিক পদ্ধতি কিনা তা দেখার জন্য?
ভোনসি

7
আমি জেআরই 6 ব্যবহার করি এবং আমাকে ভুল পদ্ধতির নাম দেয়। আমি যদি লিখি তবে এটি কাজ করে ste[2 + depth].getMethodName()। 0 হ'ল getStackTrace(), 1 হ'ল getMethodName(int depth)এবং 2 হ'ল উদ্দীপনা পদ্ধতি। আরও দেখুন @ virgo47 এর উত্তর
blurish

2
@ ব্লুশ: ভালো কথা আমি আপনার মন্তব্য এবং আমার মধ্যে কুমারী 47 এর উত্তর একটি রেফারেন্স অন্তর্ভুক্ত করেছি।
ভোনসি

@ ভনসি এই বাস্তবায়ন কি সত্যিই সঠিক? বর্তমান পদ্ধতিটি দেওয়ার জন্য এখানে গভীরতা অবশ্যই স্টেইলথ দৈর্ঘ্য +১ হতে হবে। আমরা যদি গভীরতা = 0 রাখার অনুমতি দিই তবে এটি স্টে [গভীরতা + 1] হওয়া উচিত নয়?
মিমি

85

স্ট্যাক ট্রেস সূচীতে সম্ভাব্য পরিবর্তনশীলতা হ্রাস করতে আমরা এই কোডটি ব্যবহার করেছি - এখন কেবল মেথডনেম ইউজে কল করুন:

public class MethodNameTest {
    private static final int CLIENT_CODE_STACK_INDEX;

    static {
        // Finds out the index of "this code" in the returned stack trace - funny but it differs in JDK 1.5 and 1.6
        int i = 0;
        for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
            i++;
            if (ste.getClassName().equals(MethodNameTest.class.getName())) {
                break;
            }
        }
        CLIENT_CODE_STACK_INDEX = i;
    }

    public static void main(String[] args) {
        System.out.println("methodName() = " + methodName());
        System.out.println("CLIENT_CODE_STACK_INDEX = " + CLIENT_CODE_STACK_INDEX);
    }

    public static String methodName() {
        return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX].getMethodName();
    }
}

ওভাররেঞ্জিনারেড মনে হচ্ছে, তবে জেডিকে 1.5 এর জন্য আমাদের কিছু নির্দিষ্ট নম্বর ছিল এবং আমরা জেডিকে 1.6 এ চলে যাওয়ার পরে কিছুটা অবাক হয়েছিলাম changed এখন এটি জাভা 6/7 তে একই, তবে আপনি কখনই জানেন না। রানটাইম চলাকালীন সেই সূচকে পরিবর্তিত হওয়ার প্রমাণ নয় - তবে আশা করি হটস্পট এতটা খারাপ করবে না। :-)


1
এটি এখনও সূক্ষ্মভাবে বিক্রেতা নির্ভর। JVM এই কোডের জন্য নির্ভরযোগ্য ডেটা সরবরাহ করার প্রয়োজন নেই।
থরবজর্ন রাভন অ্যান্ডারসন

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

1
এটি এখানে উপস্থাপিত সমস্ত বিকল্পগুলির মধ্যে সবচেয়ে শক্তিশালী বলে মনে হচ্ছে, তবুও নির্ভরতা।
ইয়ান

46
 public class SomeClass {
   public void foo(){
      class Local {};
      String name = Local.class.getEnclosingMethod().getName();
   }
 }

নামের মান foo হবে।


5
স্থানীয়.class.getEnclosingMethod () শূন্য ছিল।
jdk1.6.0_31

@ আইগিল এটি আকর্ষণীয় তবে আরও তথ্য ব্যতীত "ভুল" কী হয়েছে বা কখন আমাদের প্রত্যাশা করা উচিত তা বলা null
মুশকিল

এটি এই উত্তর হিসাবে একই কৌশল । এটির সুবিধাটি রয়েছে যে এটি কোনও উদ্দীপনাযুক্ত বস্তু তৈরি করে না, এর অসুবিধাও রয়েছে যে এটির জন্য একটি শ্রেণির ঘোষণার প্রয়োজন যা বিবৃতিতে inোকানো যায় না (যেমন সাধারণত এটির জন্য কোডের একটি অতিরিক্ত লাইন প্রয়োজন)।
মার্টেন বোদেউয়েস

@ আইগিল আপনি কি ক্লাসের মধ্যে ক্লাসটি সংজ্ঞায়িত করেছেন (উদাহরণস্বরূপ কিছু ক্লাস), বা কোনও পদ্ধতির মধ্যে (উদাহরণস্বরূপ ফু)? আমি দেখেছি যে কোনও পদ্ধতিতে আবদ্ধ না করে বা কোনও কনস্ট্রাক্টরে সাবক্লাসটি সংজ্ঞায়িত করার ফলে getEnclosingMethod () বাতিল হয়ে যাবে।
ডিএন

খুব নিশ্চিত যে আমি এই উত্তরে বর্ণিত হিসাবে ঠিক করেছি। আমি মনে করি এটি প্লেফ্রেমওয়ার্ক সহ কিছু অদ্ভুত। কোনও সমস্যা ছাড়াই 'নরমাল' জাভাতে পরীক্ষিত।
eigil

36

এই দুটি বিকল্পই জাভা নিয়ে আমার জন্য কাজ করে:

new Object(){}.getClass().getEnclosingMethod().getName()

বা:

Thread.currentThread().getStackTrace()[1].getMethodName()

1
স্ট্যাটিক পদ্ধতি ব্যবহারের জন্য: <ক্লাস> .ক্লাস.জেটএক্লোজিং ম্যাথোড ()। getName ()
জেলোবার্ড

বোম্বের উত্তর এবং জাভাডোক ইঙ্গিত অনুসারে খালি অ্যারে সম্পর্কে যত্নবান হন। কিছু জেভিএম স্ট্যাকট্রেস অ্যারে পূরণ করতে পারে না?
এল-তেডি

34

আমি যে দ্রুততম উপায়টি পেয়েছি তা হ'ল:

import java.lang.reflect.Method;

public class TraceHelper {
    // save it static to have it available on every call
    private static Method m;

    static {
        try {
            m = Throwable.class.getDeclaredMethod("getStackTraceElement",
                    int.class);
            m.setAccessible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String getMethodName(final int depth) {
        try {
            StackTraceElement element = (StackTraceElement) m.invoke(
                    new Throwable(), depth + 1);
            return element.getMethodName();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

এটি নেটিভ পদ্ধতিটি সরাসরি স্ট্যাকট্রেসএলমেন্ট (ইন গভীরতা) অ্যাক্সেস করে। এবং অ্যাক্সেসযোগ্য পদ্ধতিটি একটি স্ট্যাটিক ভেরিয়েবলে সঞ্চয় করে।


3
পারফরম্যান্স অনুযায়ী দ্রুততম? দাবি সমর্থন করার জন্য কোনও মাইক্রো-বেঞ্চমার্ক?
ইব্রাহিম সংক্ষিপ্তকাল

10
+1 টি। 1.6 এ একটি সাধারণ টাইম লুপ ব্যবহার করে, 1,000,000 পুনরুক্তি এই পদ্ধতিটি ব্যবহার করে 1219ms সময় new Throwable().getStackTrace()নিয়েছিল , যখন ব্যবহার করেছেন 5614ms।
আছ

1
m.setAccessible (সত্য); অ্যাক্সেসকন্ট্রোল.আর.ডি.প্রাইভিলিজড দ্বারা বেষ্টিত হওয়া উচিত। কিছু বিবেচনা করতে, একটি হার্ড নিয়ম না আমি বলতে হবে
avanderw

6
২০১ in সালে পরীক্ষা করা হয়েছে এবং এটি এখনও দ্রুততম হতে চলেছে। @Ach এর মতো আমি 1M পুনরাবৃত্তি ব্যবহার করেছি। 1.7_79: 1.6s বনাম 15.2 এস 1.8_74: 1.8 এস বনাম 16.0 এস। FWIW আমার বেনমার্ক স্টে অ্যারের দৈর্ঘ্য == 23 তবে স্ট্যাকের গভীরতা নির্বিশেষে এই পদ্ধতিটি দ্রুত থাকে।
রায়ান

25

নিম্নলিখিত কোড ব্যবহার করুন:

    StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
    StackTraceElement e = stacktrace[1];//coz 0th will be getStackTrace so 1st
    String methodName = e.getMethodName();
    System.out.println(methodName);

2
এটি আমার জন্য "গেটস্ট্যাকট্রেস" ছাপিয়েছে - আমি জাভা 1.5 ব্যবহার করছি
জ্যাক ম্যাকম্বার

বোম্বের উত্তর এবং জাভাডোক ইঙ্গিত অনুসারে খালি অ্যারে সম্পর্কে যত্নবান হন। কিছু জেভিএম স্ট্যাকট্রেস অ্যারে পূরণ করতে পারে না?
এল-তেডি

16
public static String getCurrentMethodName() {
        return Thread.currentThread().getStackTrace()[2].getClassName() + "." + Thread.currentThread().getStackTrace()[2].getMethodName();
    }

হ্যাঁ, এখন পর্যন্ত সর্বোত্তম ... এটি একটি পদ্ধতিতে পরিণত করুন এবং ট্রেসের মধ্যে তৃতীয় ([2]) ফ্রেম (বা যা বলা হোক না কেন) পান।
মাইকে রডেন্ট

14

এটি ভার্জো 47 এর উত্তরের উপরের (উপরে)।

এটি বর্তমান এবং আমন্ত্রণমূলক শ্রেণি / পদ্ধতির নামগুলি পেতে কিছু স্থিতিশীল পদ্ধতি সরবরাহ করে।

/* Utility class: Getting the name of the current executing method 
 * /programming/442747/getting-the-name-of-the-current-executing-method
 * 
 * Provides: 
 * 
 *      getCurrentClassName()
 *      getCurrentMethodName()
 *      getCurrentFileName()
 * 
 *      getInvokingClassName()
 *      getInvokingMethodName()
 *      getInvokingFileName()
 *
 * Nb. Using StackTrace's to get this info is expensive. There are more optimised ways to obtain
 * method names. See other stackoverflow posts eg. /programming/421280/in-java-how-do-i-find-the-caller-of-a-method-using-stacktrace-or-reflection/2924426#2924426
 *
 * 29/09/2012 (lem) - added methods to return (1) fully qualified names and (2) invoking class/method names
 */
package com.stackoverflow.util;

public class StackTraceInfo
{
    /* (Lifted from virgo47's stackoverflow answer) */
    private static final int CLIENT_CODE_STACK_INDEX;

    static {
        // Finds out the index of "this code" in the returned stack trace - funny but it differs in JDK 1.5 and 1.6
        int i = 0;
        for (StackTraceElement ste: Thread.currentThread().getStackTrace())
        {
            i++;
            if (ste.getClassName().equals(StackTraceInfo.class.getName()))
            {
                break;
            }
        }
        CLIENT_CODE_STACK_INDEX = i;
    }

    public static String getCurrentMethodName()
    {
        return getCurrentMethodName(1);     // making additional overloaded method call requires +1 offset
    }

    private static String getCurrentMethodName(int offset)
    {
        return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getMethodName();
    }

    public static String getCurrentClassName()
    {
        return getCurrentClassName(1);      // making additional overloaded method call requires +1 offset
    }

    private static String getCurrentClassName(int offset)
    {
    return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getClassName();
    }

    public static String getCurrentFileName()
    {
        return getCurrentFileName(1);     // making additional overloaded method call requires +1 offset
    }

    private static String getCurrentFileName(int offset)
    {
        String filename = Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getFileName();
        int lineNumber = Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getLineNumber();

        return filename + ":" + lineNumber;
    }

    public static String getInvokingMethodName()
    {
        return getInvokingMethodName(2); 
    }

    private static String getInvokingMethodName(int offset)
    {
        return getCurrentMethodName(offset + 1);    // re-uses getCurrentMethodName() with desired index
    }

    public static String getInvokingClassName()
    {
        return getInvokingClassName(2); 
    }

    private static String getInvokingClassName(int offset)
    {
        return getCurrentClassName(offset + 1);     // re-uses getCurrentClassName() with desired index
    }

    public static String getInvokingFileName()
    {
        return getInvokingFileName(2); 
    }

    private static String getInvokingFileName(int offset)
    {
        return getCurrentFileName(offset + 1);     // re-uses getCurrentFileName() with desired index
    }

    public static String getCurrentMethodNameFqn()
    {
        return getCurrentMethodNameFqn(1);
    }

    private static String getCurrentMethodNameFqn(int offset)
    {
        String currentClassName = getCurrentClassName(offset + 1);
        String currentMethodName = getCurrentMethodName(offset + 1);

        return currentClassName + "." + currentMethodName ;
    }

    public static String getCurrentFileNameFqn()
    {
        String CurrentMethodNameFqn = getCurrentMethodNameFqn(1);
        String currentFileName = getCurrentFileName(1);

        return CurrentMethodNameFqn + "(" + currentFileName + ")";
    }

    public static String getInvokingMethodNameFqn()
    {
        return getInvokingMethodNameFqn(2);
    }

    private static String getInvokingMethodNameFqn(int offset)
    {
        String invokingClassName = getInvokingClassName(offset + 1);
        String invokingMethodName = getInvokingMethodName(offset + 1);

        return invokingClassName + "." + invokingMethodName;
    }

    public static String getInvokingFileNameFqn()
    {
        String invokingMethodNameFqn = getInvokingMethodNameFqn(2);
        String invokingFileName = getInvokingFileName(2);

        return invokingMethodNameFqn + "(" + invokingFileName + ")";
    }
}

3
@ এমক্লেমেঞ্জ এর উত্তরের সাথে এটি স্ট্যাক তথ্য অ্যাক্সেস করার খুব দ্রুত এবং পরিষ্কার উপায়।
অক্টোবিয়া টোগামি

12

যে পদ্ধতিটি বর্তমান পদ্ধতি বলে তার নাম পেতে আপনি ব্যবহার করতে পারেন:

new Exception("is not thrown").getStackTrace()[1].getMethodName()

এটি আমার ম্যাকবুকের পাশাপাশি আমার অ্যান্ড্রয়েড ফোনেও কাজ করে

আমি চেষ্টাও করেছি:

Thread.currentThread().getStackTrace()[1]

তবে অ্যান্ড্রয়েড "গেটস্ট্যাকট্রেস" ফিরিয়ে দেবে আমি এটিকে অ্যান্ড্রয়েডের সাথে এটি ঠিক করতে পারি

Thread.currentThread().getStackTrace()[2]

তবে তারপরে আমি আমার ম্যাকবুকটিতে ভুল উত্তর পেয়েছি


অ্যান্ড্রয়েডে সাম্প্রতিক পরীক্ষায়, এটি আমার getStackTrace()[0]চেয়ে বরং ব্যবহার করার জন্য আরও ভাল কাজ করেছে getStackTrace()[1]। YMMV।
mbm29414

অ্যান্ড্রয়েডের জন্য আপ আপThread.currentThread().getStackTrace()[2]
নিনজা

11

Util.java:

public static String getCurrentClassAndMethodNames() {
    final StackTraceElement e = Thread.currentThread().getStackTrace()[2];
    final String s = e.getClassName();
    return s.substring(s.lastIndexOf('.') + 1, s.length()) + "." + e.getMethodName();
}

SomeClass.java:

public class SomeClass {
    public static void main(String[] args) {
        System.out.println(Util.getCurrentClassAndMethodNames()); // output: SomeClass.main
    }
}

final StackTraceElement e = Thread.currentThread().getStackTrace()[2]; কাজ করে; e.getClassName();পুরো শ্রেণীর নাম এবং e.getMethodName()মেথনের নামটি ফিরিয়ে দিন।
মার্কস

1
getStackTrace()[2]ভুল, এটি getStackTrace()[3]কারণ হতে হবে : [0] dalvik.s systemm.VMStack.getThreadStackTrace [1] java.lang.Thread.getStackTrace [2] Utils.getCurrentClassAndMethodNames [3] ফাংশন a () এটিকে ডাকে
ফিলল্যাব

11

এটি StackWalkerজাভা 9 থেকে ব্যবহার করে করা যেতে পারে ।

public static String getCurrentMethodName() {
    return StackWalker.getInstance()
                      .walk(s -> s.skip(1).findFirst())
                      .get()
                      .getMethodName();
}

public static String getCallerMethodName() {
    return StackWalker.getInstance()
                      .walk(s -> s.skip(2).findFirst())
                      .get()
                      .getMethodName();
}

StackWalkerঅলস হওয়ার জন্য ডিজাইন করা হয়েছে, সুতরাং এটি বলার চেয়ে আরও দক্ষ হওয়ার সম্ভাবনা রয়েছে Thread.getStackTraceযা পুরো কলস্ট্যাকের জন্য আগ্রহের সাথে একটি অ্যারে তৈরি করে। আরও তথ্যের জন্য জেপ দেখুন।


5

একটি বিকল্প পদ্ধতি হ'ল একটি ব্যাতিক্রম তৈরি করা, তবে নিক্ষেপ করা নয়, এবং স্ট্যাক ট্রেস ডেটা পেতে যে বস্তুটি ব্যবহার করা উচিত তা যেহেতু ঘেরের পদ্ধতি সাধারণত সূচক 0-এ থাকবে - যতক্ষণ না জেভিএম সেই তথ্য সংরক্ষণ করে, অন্যদের মতো উপরোল্লিখিত. তবে এটি সস্তারতম পদ্ধতি নয়।

থ্রোয়েবল.জেটস্ট্যাকট্রেস () থেকে ( কমপক্ষে জাভা ৫ এর পর থেকে এটি একই রকম হয়েছে):

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

নীচের স্নিপেটটি অনুমান করে শ্রেণিটি স্থির নয় (কারণ getClass ()), তবে এটি একপাশে।

System.out.printf("Class %s.%s\n", getClass().getName(), new Exception("is not thrown").getStackTrace()[0].getMethodName());

4
String methodName =Thread.currentThread().getStackTrace()[1].getMethodName();
System.out.println("methodName = " + methodName);

1
উপরে mvanle কুমারী 47 এর উত্তর দেখুন এবং thorbjorn-ravn-andersen এর মন্তব্য। পুনরাবৃত্তি, অ-নির্ভুল এবং অবিশ্বস্ত কোড।
অ্যালেক্সসমেইল

@ শিভাকমুরাভ্যালি হ্যাঁ, তবে কোনও অবস্থাতেই এটি মনে হচ্ছে না, তাই আমার কাছ থেকেও -1।
মার্টেন বোদেউয়েস

3

আমি এটি ব্যবহার করে সমাধান পেয়েছি (অ্যান্ড্রয়েডে)

/**
 * @param className       fully qualified className
 *                        <br/>
 *                        <code>YourClassName.class.getName();</code>
 *                        <br/><br/>
 * @param classSimpleName simpleClassName
 *                        <br/>
 *                        <code>YourClassName.class.getSimpleName();</code>
 *                        <br/><br/>
 */
public static void getStackTrace(final String className, final String classSimpleName) {
    final StackTraceElement[] steArray = Thread.currentThread().getStackTrace();
    int index = 0;
    for (StackTraceElement ste : steArray) {
        if (ste.getClassName().equals(className)) {
            break;
        }
        index++;
    }
    if (index >= steArray.length) {
        // Little Hacky
        Log.w(classSimpleName, Arrays.toString(new String[]{steArray[3].getMethodName(), String.valueOf(steArray[3].getLineNumber())}));
    } else {
        // Legitimate
        Log.w(classSimpleName, Arrays.toString(new String[]{steArray[index].getMethodName(), String.valueOf(steArray[index].getLineNumber())}));
    }
}

3

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


2

আপনি যদি কোন নামটি জানতে চান এমন পদ্ধতিটি যদি একটি জুনিট পরীক্ষা পদ্ধতি হয় তবে আপনি জুনিট টেস্টনামের নিয়মটি ব্যবহার করতে পারেন: https://stackoverflow.com/a/1426730/3076107


1
@ আন্দ্রেইকনস্টান্টিনোভ আমি ভাবি না যে এটি কেবল লিঙ্কযুক্ত। এমনকি আপনি লিঙ্কটি সরিয়ে ফেলেন, এখনও কমপক্ষে কিছু তথ্য এখনও চলছে।
যোশুয়াস - মনিকা

1

এখানে বেশিরভাগ উত্তর ভুল বলে মনে হচ্ছে।

    public static String getCurrentMethod() {
            return getCurrentMethod(1);
    }
    public static String getCurrentMethod(int skip) {
            return Thread.currentThread().getStackTrace()[1 + 1 + skip].getMethodName();
    }

উদাহরণ:

    public static void main(String[] args) {
            aaa();
    }

    public static void aaa() {
            System.out.println("aaa  -> "  + getCurrentMethod( ) );
            System.out.println("aaa  -> "  + getCurrentMethod(0) );
            System.out.println("main -> "  + getCurrentMethod(1) );
    }

আউটপুট:

aaa  -> aaa
aaa  -> aaa
main -> main

আপনার দরকারী উত্তরের জন্য ধন্যবাদ।
আমেরেলিকাএ

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

@ ম্মম দুঃখিত, তবে আমি দৃ strongly়ভাবে একমত নই। আমি এখানে শিখতে এসেছি এবং আরও অনেকের মতো আমি বিশ্বাস করি। আমি কেবল বুঝতে পারি না কেন আপনি কেন মনে করেন যে আমি এই বিষয় সম্পর্কে আরও জানার যোগ্য নই। আমি আমার কোডে কম ভুল করতে এবং অন্যকে সতর্ক করতে চাই, কার্গো-কাল্ট অনুসরণ না করে। আপনি কমপক্ষে জাভা সংস্করণটি এই কোডটি সঠিক হওয়া উচিত তা স্পষ্ট করে বলতে পারতেন। :( নীচে একটি উত্তর বলছে যে 1.5 থেকে 1.6 এর মধ্যে স্ট্যাকট্র্যাসে একটি পরিবর্তন হয়েছে Maybe সম্ভবত আপনি বোঝাচ্ছেন আসন্ন জাভা ১৪-তে এরকম কিছু রয়েছে, আমি কীভাবে জানতে পারি different বা বিভিন্ন বিক্রেতার কাছে থাকতে পারে Sorry দুঃখিত, আমি যদি আপনার উত্তরটি অভদ্র হিসাবে ভুল ব্যাখ্যা করি তবে এক।
Xobotun

0

আমি ম্যাকলেমেঞ্জের উত্তরটি আবার লিখেছিলাম :

private static Method m;

static {
    try {
        m = Throwable.class.getDeclaredMethod(
            "getStackTraceElement",
            int.class
        );
    }
    catch (final NoSuchMethodException e) {
        throw new NoSuchMethodUncheckedException(e);
    }
    catch (final SecurityException e) {
        throw new SecurityUncheckedException(e);
    }
}


public static String getMethodName(int depth) {
    StackTraceElement element;

    final boolean accessible = m.isAccessible();
    m.setAccessible(true);

    try {
        element = (StackTraceElement) m.invoke(new Throwable(), 1 + depth);
    }
    catch (final IllegalAccessException e) {
        throw new IllegalAccessUncheckedException(e);
    }
    catch (final InvocationTargetException e) {
        throw new InvocationTargetUncheckedException(e);
    }
    finally {
        m.setAccessible(accessible);
    }

    return element.getMethodName();
}

public static String getMethodName() {
    return getMethodName(1);
}

-2
MethodHandles.lookup().lookupClass().getEnclosingMethod().getName();

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

1
যদিও এই কোডটি সমস্যা সমাধানে সহায়তা করতে পারে তবে এটি কেন এবং / বা কীভাবে প্রশ্নের উত্তর দেয় তা ব্যাখ্যা করে না । এই অতিরিক্ত প্রসঙ্গ সরবরাহ করা তার দীর্ঘমেয়াদী শিক্ষাগত মানকে উল্লেখযোগ্যভাবে উন্নতি করবে। দয়া করে সম্পাদনা ব্যাখ্যা যোগ করার জন্য সহ সীমাবদ্ধতা এবং অনুমানের কি প্রয়োগ আপনার উত্তর।
টবির গতি

1
কেবল জাভা 7+ এর জন্য, তবে পদ্ধতির নাম পাওয়ার সংক্ষিপ্ত উপায়। এখনও, যেমন একটি কল কর্মক্ষমতা বিবেচনা।
বেনজ

6
getEnclosingMethod()NullPointerExceptionজাভা
মার্কাস এল

2
Java.lang.Class.getEnclosingMethod () অন্তর্নিহিত শ্রেণীর অবিলম্বে ঘেরানো পদ্ধতির প্রতিনিধিত্ব করে এমন একটি মেথড অবজেক্ট ফেরত দেয়, যদি এই শ্রেণীর অবজেক্ট কোনও পদ্ধতির মধ্যে স্থানীয় বা বেনাম শ্রেণীর প্রতিনিধিত্ব করে তবে অন্যথায় শূন্য হয়।
চুলা

-5

এই পদ্ধতির সাথে কী দোষ রয়েছে:

class Example {
    FileOutputStream fileOutputStream;

    public Example() {
        //System.out.println("Example.Example()");

        debug("Example.Example()",false); // toggle

        try {
            fileOutputStream = new FileOutputStream("debug.txt");
        } catch (Exception exception) {
             debug(exception + Calendar.getInstance().getTime());
        }
    }

    private boolean was911AnInsideJob() {
        System.out.println("Example.was911AnInsideJob()");
        return true;
    }

    public boolean shouldGWBushBeImpeached(){
        System.out.println("Example.shouldGWBushBeImpeached()");
        return true;
    }

    public void setPunishment(int yearsInJail){
        debug("Server.setPunishment(int yearsInJail=" + yearsInJail + ")",true);
    }
}

এবং লোকেরা System.out.println(...)আপনাকে সর্বদা ব্যবহার করার জন্য উন্মাদ হওয়ার আগে , এবং এমন একটি পদ্ধতি তৈরি করতে পারে যাতে আউটপুট পুনর্নির্দেশ করা যায়, যেমন:

    private void debug (Object object) {
        debug(object,true);
    }

    private void dedub(Object object, boolean debug) {
        if (debug) {
            System.out.println(object);

            // you can also write to a file but make sure the output stream
            // ISN'T opened every time debug(Object object) is called

            fileOutputStream.write(object.toString().getBytes());
        }
    }

4
@ শ্যাশাম আমার কাছে এমন মনে হচ্ছে আসলে প্রশ্নের উত্তর দেওয়ার চেষ্টা ছিল। দুর্দান্ত চেষ্টা নয়, তবে চেষ্টাও কম নয়।
ivarni

@ivarni "ভাল চেষ্টা না"? এতে কি দোষ? আপনি কি "চুম্বন নীতি" সাথে পরিচিত?
জননী

@ সাক্ষম এটি বাজে বক্তব্য ছিল।
জননী

5
@ জোহনি কোডবেসে আমার সামনে এখনই 271 ক্লাস রয়েছে। এমনকি একটি (স্বল্প অনুমান) এবং 5 ক্লাস প্রতি 5 টি পদ্ধতি যা 1300 পদ্ধতিরও বেশি। এবং এটি একটি বড় কোডবেসও নয়। আপনার দৃষ্টিভঙ্গিটি বাড়ানোর সমস্যাটি আপনি দেখতে পাচ্ছেন না? আমি দ্বিমত পোষণ করতে রাজি হয়ে বেশ খুশি, তবে সে কারণেই আমি বলেছিলাম যে এটি একটি ভাল প্রচেষ্টা নয়। এটি কোনও অ-তুচ্ছ কোডবেসে প্রচুর পরিমাণে ওভারহেড প্রবর্তন করে।
ivarni

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