I'm attempting to create a method called "runExperiments()
the first step in the loop is to decrement a variable called "powerLevel" by a random number between 1 and 3 which is I have created a second method for which works.
the next step which is where I am having problem is if the "powerLevel" can be reduced then I need a message containing the experiment number (starting at 1) should displayed, if not then a different message should be displayed and the remaining experiments should not be attempted.
Then finally when all expierements have finished I need to display "Experiment run stopped" But I know how to do this section.
I have posted all the code below. The method is at the bottom. I have made a first attempt but I cannot seem to figure out the part in the bold. Any help or guidance would be fantastic. I'm not sure if I have used the correct type of loop either so that may be wrong as well.
public class SpaceRocket
{
private String name;
private int maxPowerLevel;
private int numberOfExperiments;
private int powerLevel;
private int decreasePowerLevel;
/**
* returns maxPowerLevel
*/
public int getMaxPowerLevel()
{
return this.maxPowerLevel;
}
/**
* returns numberOfExperiments
*/
public int getNumberofExperiments()
{
return this.numberOfExperiments;
}
/**
* returns powerLevel
*/
public int getPowerLevel()
{
return this.powerLevel;
}
/**
*
* Causes execution to pause by time number of milliseconds
*
*/
public void delay(int time)
{
try
{
Thread.sleep(time);
}
catch (Exception e)
{
System.out.println(e);
}
}
/**
*
* return a random integer between 1 and 3 inclusive
*/
public int randomInteger()
{
java.util.Random r = new java.util.Random();
return r.nextInt(3) + 1;
}
public SpaceRocket(String aName, int aNumberOfExperiments)
{
this.name = aName;
this.numberOfExperiments = aNumberOfExperiments;
this.powerLevel = 0;
this.maxPowerLevel = 15;
}
public boolean decrementPower(int adecreasePowerLevel)
{
this.decreasePowerLevel = adecreasePowerLevel;
if(decreasePowerLevel > this.powerLevel)
{
this.powerLevel = 0;
return true;
}
else
{
this.powerLevel =(this.powerLevel - this.decreasePowerLevel);
return false;
}
}
public runExperiments()
{
for(this.powerLevel =(this.powerLevel - randomIntegar())
{
if(this.powerLevel
}
}
If I understand your question correctly, every time the loop runs, you want to decrease "powerlevel" by a random value, then display a message depending on whether powerlevel can be reduced.
Here are two approaches.
1) use an if statement in your for loop
for (conditions){
if(powerlevel cannot be decremented){
//display a messsage
break;
}
// display a message
}
conditions could be iterating through all the experiments
2) use a while loop which checks whether powerlevel can be reduced in every loop
while(powerlevel can be decreased){
//display a message containing the experiment number (starting at 1)
}
//display a different message
I have some java code I'm attempting to translate into vb.net. It uses 'predicates', a feature I did not know existed until now, but which exists in vb.net too.
So I read documentation on it, but none of it explains the java code I have, specifically, if you have a variable 'p' declared as a predicate, what does p.arity do, and what does p.arg(0) and p.arg(1) return?
My general impression was that a predicate takes a set of objects and returns a subset that meets a particular criteria, (for instance, given the set of all basketball players, return only those that are over 6 feet tall). But the following code doesn't seem to have anything to do with that:
// st is assumed to be a list of ECHO predicates
//
private void parseInput(StreamTokenizer st) throws IOException
{
while (st.nextToken() != StreamTokenizer.TT_EOF) {
st.pushBack();
Predicate p = new Predicate(st);
parsePredicate(p);
} // while
}
// PRE: p is non-null
// POST: performs the additions to the ECHO graph required by the
// ECHO predicate; if p is not a legal ECHO predicate, an
// IOException is thrown
//
private void parsePredicate(Predicate p) throws IOException
{
Assert.notNull(p);
String name = p.name();
if (name.equalsIgnoreCase(explainPred)) {
parseExplain(p);
} else if (name.equalsIgnoreCase(dataPred)) {
parseData(p);
} else if (name.equalsIgnoreCase(contradictPred)) {
parseContradict(p);
} else if (name.equalsIgnoreCase(analogyPred)) {
parseAnalogy(p);
} else if (name.equalsIgnoreCase(propositionPred)) {
parseProposition(p);
} else {
throw new IOException("ECHO: "+name+" is not a legal predicate name. "+
"Must be one of "+explainPred+", "+dataPred+", "+
contradictPred+", or "+analogyPred);
} // if
}
//
// PRE: p's name is explainPred
// POST: adds the given explanation predicate to ECHO, adding all necessary
// links; throws an exception if p is not a legal explains predicate
//
private void parseExplain(Predicate p) throws IOException
{
//msg("in parseExplain...");
int arity = p.arity();
float weight;
List propList;
String explainee;
if (arity == 2) {
//msg("arity == 2");
propList = (List)p.arg(0);
explainee = (String)p.arg(1);
weight = (float)explainWeight(propList.length());
} else if (arity == 3) {
//msg("arity == 3");
propList = (List)p.arg(0);
explainee = (String)p.arg(1);
float strength = Float.valueOf((String)p.arg(2)).floatValue();
weight = (float)(strength*explainWeight(propList.length()));
} else {
throw new IOException("ECHO: an explains predicate must have 2 or 3 "+
"arguments: "+p);
} // if
In this case I assume the following:
arity is the amount of parameters the function takes. You can see that after checking if arity is equals to 2, it reads two arguments (arg(0) and arg(1)). So arg is just the method to get the parameter/argument at the given index.
Then when arity is 3, you can get three args; 0, 1, 2
I am trying to learn to work with error handling/throwing exceptions in Java.
I have a class, UserDatabase, holding a collection of students, and it should also save the collection to a file.
What I'm fairly sure that I haven't done correctly, is the methods for file handling. Method public boolean saveDatabase should not throw exceptions and be handled in a try-catch, and use the encode method from the student class on Student objects, to write every object as a line in the file. This one is compiling, but it looks off to me. In the book it says write the method public boolean saveDatabase(); and as you can see I changed the header for it to make sense to me. This, mainly because I don't know how to write a method with the header ending with ();
Method public boolean loadDatabase should also handle possible IO errors and return false if one occurs. For every line in the field it should create a student object by the constructor public Student(String encodedStudent) from the sudent class. If a line in the file cannot be decoded as a student it should throw a new exception, DatabaseFormatException (this is a seperate class). This one is also listed as public boolean loadDatabase(); in the book. Let's face it, this one is completely off. I have no idea what to do and I have been working with it for hours and hours, reading books, reading online, I am lost.
Here's my code:
/**
* This method should not throw exceptions.
* By using a try/catch block, we anticipate possible failures.
* We recognize that these actions might fail and throw errors.
*/
public boolean saveDatabase() throws IOException {
//This method is using the encode method on student objects and should
//write each object as a line in the file.
String encode = null;
boolean saved;
try {
encode = null;
userdatabase.saveDatabase();
saved = false;
}
catch (IOException e) {
System.out.println("Error");
saved = false;
}
finally {
if(encode.equals(students)) {
//System.out.println("Students" + students)?;
saved = true;
}
}
return saved;
}
/**
* Method loadDatabase should handle possible IO errors, and return false
* if one occurs. Otherwise, it should return true and create a new
Student object
* by using the constructor public Student(String encodedStudent).
* If a line cannot be decoded as a student, the method should throw a
new
* exception "DatabaseFormatException".
*
*/
public boolean loadDatabase() throws IOException,DatabaseFormatException {
//Attempting to use the String encodedStudent constructor from Student class
String encodedStudent = null;
boolean loaded;
try {
//Attempting to create possible IO errors returning false if they occur
enco dedStudent = null;
//UserDatabase.loadDatabase(encodedStudent);
loaded = false;
}
catch(IOException e) {
if (encodedStudent == null) {
System.out.println("Error");
loaded = false;
}
}
//Trying a for each loop to throw a DatabaseFormatException
for(Student student : students) {
//This is supposed to throw a DatabaseFormatException if a
//line in the file cannot be decoded as a student!
if(student.getName.isEmpty() && this.course.isEmpty()) {
throw new DatabaseFormatException(
"No student found");
}
}
Your code should be
public boolean saveDatabase() {
try {
// maybe do some more work...
userdatabase.saveDatabase();
return true;
} catch (IOException e) {
return false;
}
}
Simply return true/false depending on wether an exception occurred or not. Drop the saved since you no longer need it. And drop the encode since you did not need it in the first place and never assigned a value to it.
I've written seven test cases for understanding the behavior of the finally block. What is the logic behind how finally works?
package core;
public class Test {
public static void main(String[] args) {
new Test().testFinally();
}
public void testFinally() {
System.out.println("One = " + tryOne());
System.out.println("Two = " + tryTwo());
System.out.println("Three = " + tryThree());
System.out.println("Four = " + tryFour());
System.out.println("Five = " + tryFive());
System.out.println("Six = " + trySix());
System.out.println("Seven = " + trySeven());
}
protected StringBuilder tryOne() {
StringBuilder builder = new StringBuilder();
try {
builder.append("Cool");
return builder.append("Return");
}
finally {
builder = null;
}
}
protected String tryTwo() {
String builder = "Cool";
try {
return builder += "Return";
}
finally {
builder = null;
}
}
protected int tryThree() {
int builder = 99;
try {
return builder += 1;
}
finally {
builder = 0;
}
}
protected StringBuilder tryFour() {
StringBuilder builder = new StringBuilder();
try {
builder.append("Cool");
return builder.append("Return");
}
finally {
builder.append("+1");
}
}
protected int tryFive() {
int count = 0;
try {
count = 99;
}
finally {
count++;
}
return count;
}
protected int trySix() {
int count = 0;
try {
count = 99;
}
finally {
count = 1;
}
return count;
}
protected int trySeven() {
int count = 0;
try {
count = 99;
return count;
}
finally {
count++;
}
}
}
Why builder = null is not working?
Why does builder.append("+1") work whereas count++( in trySeven()) does not work?
Once you do the return, the only way to override that is to do another return (as discussed at Returning from a finally block in Java, this is almost always a bad idea), or otherwise complete abruptly. Your tests don't ever return from a finally.
JLS §14.1 defines abrupt completion. One of the abrupt completion types is a return. The try blocks in 1,2,3,4, and 7 abruptly complete due to returns. As explained by §14.20.2, if the try block completes abruptly for a reason R besides a throw, the finally block is immediately executed.
If the finally block completes normally (which implies no return, among other things), "the try statement completes abruptly for reason R.". In other words, the return initiated by the try is left intact; this applies to all your tests. If you return from the finally, "the try statement completes abruptly for reason S (and reason R is discarded)." (S here being the new overriding return).
So in tryOne, if you did:
finally {
builder = null;
return builder;
}
this new return S would override the original return R.
For builder.append("+1") in tryFour, keep in mind StringBuilder is mutable, so you're still returning a reference to the same object specified in the try. You're just doing a last minute mutation.
tryFive and trySix are straight-forward. Since there is no return in the try, the try and finally both complete normally, and it executes the same as if there was no try-finally.
Let's start with use case you'll see more often - you have a resource that you must close to avoid a leak.
public void deleteRows(Connection conn) throws SQLException {
Statement statement = conn.createStatement();
try {
statement.execute("DELETE * FROM foo");
} finally {
statement.close();
}
}
In this case, we have to close the statement when we're done, so we don't leak database resources. This will ensure that in the case of an Exception being thrown, we will always close our Statement before the function exits.
try { ... } finally { ... } blocks are meant for ensuring that something will always execute when the method terminates. It's most useful for Exception cases. If you find yourself doing something like this:
public String thisShouldBeRefactored(List<String> foo) {
try {
if(foo == null) {
return null;
} else if(foo.length == 1) {
return foo.get(0);
} else {
return foo.get(1);
}
} finally {
System.out.println("Exiting function!");
}
}
You're not really using finally properly. There is a performance penalty to this. Stick to using it when you have Exception cases that you must clean up from. Try refactoring the above to this:
public String thisShouldBeRefactored(List<String> foo) {
final String result;
if(foo == null) {
result = null;
} else if(foo.length == 1) {
result = foo.get(0);
} else {
result = foo.get(1);
}
System.out.println("Exiting function!");
return result;
}
The finally block is executed when you leave the try block. The "return" statement does two things, one it sets the return value of the function and two it exits the function. Normally this would look like an atomic operation but within a try block it will cause the finally block to execute after the return value was set and before the function exits.
Return execution:
Assign return value
run finally blocks
exit function
Example one (primitive):
int count = 1;//Assign local primitive count to 1
try{
return count; //Assign primitive return value to count (1)
}finally{
count++ //Updates count but not return value
}
Example two(reference):
StringBuilder sb = new StringBuilder();//Assign sb a new StringBuilder
try{
return sb;//return a reference to StringBuilder
}finally{
sb.append("hello");//modifies the returned StringBuilder
}
Example three (reference):
StringBuilder sb = new StringBuilder();//Assign sb a new StringBuilder
try{
return sb;//return a reference to StringBuilder
}finally{
sb = null;//Update local reference sb not return value
}
Example four (return):
int count = 1; //assign count
try{
return count; //return current value of count (1)
}finally{
count++; //update count to two but not return value
return count; //return current value of count (2)
//replaces old return value and exits the finally block
}
builder = null and builder.append("+1") are working. It's just that they're not affecting what you're returning. The function returns what the return statement has, regardless of what happens afterward.
The reason there is a difference is because builder is passed by reference. builder=null changes the local copy of builder. builder.append("+1") affects the copy held by the parent.
Why builder = null is not working?Because you are setting the local reference to null which will not change the content of the memory. So it is working, if you try to access the builder after finally block then you'll get null.Why builder.append("+1") work? Because you are modifying the content of the memory using the reference,that's why it should work.Why count++ does not work in testFive()? It is working fine with me. It outputs 100 as expected.
Consider what the compiler is actually doing for the return statement, for instance in tryOne(): it copies a reference to builder back to the calling function's environment. After it's done this, but before control goes back to the calling function, the finally block executes. So you have something more like this, in practice:
protected StringBuilder tryOne() {
StringBuilder builder = new StringBuilder();
try {
builder.append("Cool");
builder.append("Return");
StringBuilder temp = builder;
return temp;
} finally {
builder = null;
}
}
Or, in terms of the order that statements actually get executed (ignoring possible exceptions, of course), it looks more like this:
protected StringBuilder tryOne() {
StringBuilder builder = new StringBuilder();
builder.append("Cool");
builder.append("Return");
StringBuilder temp = builder;
builder = null;
return temp;
}
So setting builder = null does run, it just doesn't do anything useful. However, running builder.append("something") will have a visible effect, since both temp and builder refer to the same (mutable) object.
Likewise, what's really happening in trySeven() is something more like this:
protected int trySeven() {
int count = 0;
count = 99;
int temp = count;
count++;
return temp;
}
In this case, since we're dealing with an int, the copies are independent, so incrementing one doesn't affect the other.
All that said, the fact remains that putting return statements in a try-finally block is quite clearly confusing, so if you've got any kind of choice in the matter, you'd be better off rewriting things so that all your return statements are outside any try-finally blocks.
Is there a way to get the name of the currently executing method in Java?
Technically this will work...
String name = new Object(){}.getClass().getEnclosingMethod().getName();
However, a new anonymous inner class will be created during compile time (e.g. YourClass$1.class). So this will create a .class file for each method that deploys this trick. Additionally, an otherwise unused object instance is created on each invocation during runtime. So this may be an acceptable debug trick, but it does come with significant overhead.
An advantage of this trick is that getEnclosingMethod() returns java.lang.reflect.Method which can be used to retrieve all other information of the method including annotations and parameter names. This makes it possible to distinguish between specific methods with the same name (method overload).
Note that according to the JavaDoc of getEnclosingMethod() this trick should not throw a SecurityException as inner classes should be loaded using the same class loader. So there is no need to check the access conditions even if a security manager is present.
Please be aware: It is required to use getEnclosingConstructor() for constructors. During blocks outside of (named) methods, getEnclosingMethod() returns null.
Thread.currentThread().getStackTrace() will usually contain the method you’re calling it from but there are pitfalls (see Javadoc):
Some virtual machines may, under some circumstances, omit one or more stack frames from the stack trace. In the extreme case, a virtual machine that has no stack trace information concerning this thread is permitted to return a zero-length array from this method.
January 2009:
A full code would be (to use with #Bombe's caveat in mind):
/**
* 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
}
More in this question.
Update December 2011:
bluish comments:
I use JRE 6 and gives me incorrect method name.
It works if I write ste[2 + depth].getMethodName().
0 is getStackTrace(),
1 is getMethodName(int depth) and
2 is invoking method.
virgo47's answer (upvoted) actually computes the right index to apply in order to get back the method name.
We used this code to mitigate potential variability in stack trace index - now just call methodName util:
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();
}
}
Seems overengineered, but we had some fixed number for JDK 1.5 and were a bit surprised it changed when we moved to JDK 1.6. Now it's the same in Java 6/7, but you just never know. It is not proof to changes in that index during runtime - but hopefully HotSpot doesn't do that bad. :-)
Both of these options work for me with Java:
new Object(){}.getClass().getEnclosingMethod().getName()
Or:
Thread.currentThread().getStackTrace()[1].getMethodName()
public class SomeClass {
public void foo(){
class Local {};
String name = Local.class.getEnclosingMethod().getName();
}
}
name will have value foo.
The fastest way I found is that:
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;
}
}
}
It accesses the native method getStackTraceElement(int depth) directly. And stores the accessible Method in a static variable.
This can be done using StackWalker since Java 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 is designed to be lazy, so it's likely to be more efficient than, say, Thread.getStackTrace which eagerly creates an array for the entire callstack. Also see the JEP for more information.
Use the following Code :
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
StackTraceElement e = stacktrace[1];//coz 0th will be getStackTrace so 1st
String methodName = e.getMethodName();
System.out.println(methodName);
public static String getCurrentMethodName() {
return Thread.currentThread().getStackTrace()[2].getClassName() + "." + Thread.currentThread().getStackTrace()[2].getMethodName();
}
This is an expansion on virgo47's answer (above).
It provides some static methods to get the current and invoking class / method names.
/* Utility class: Getting the name of the current executing method
* https://stackoverflow.com/questions/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. https://stackoverflow.com/questions/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 + ")";
}
}
To get the name of the method that called the current method you can use:
new Exception("is not thrown").getStackTrace()[1].getMethodName()
This works on my MacBook as well as on my Android phone
I also tried:
Thread.currentThread().getStackTrace()[1]
but Android will return "getStackTrace"
I could fix this for Android with
Thread.currentThread().getStackTrace()[2]
but then I get the wrong answer on my MacBook
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
}
}
An alternative method is to create, but not throw, an Exception, and use that object from which to get the stack trace data, since the enclosing method will typically be at index 0 - as long as the JVM stores that information, as others have mentioned above. This not the cheapest method, however.
From Throwable.getStackTrace() (this has been the same since Java 5 at least):
The zeroth element of the array (assuming the array's length is non-zero) represents the top of the stack, which is the last method invocation in the sequence. Typically, this is the point at which this throwable was created and thrown.
The snippet below assumes the class is non-static (because of getClass()), but that's an aside.
System.out.printf("Class %s.%s\n", getClass().getName(), new Exception("is not thrown").getStackTrace()[0].getMethodName());
String methodName =Thread.currentThread().getStackTrace()[1].getMethodName();
System.out.println("methodName = " + methodName);
I've got solution using this (In Android)
/**
* #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())}));
}
}
I don't know what is the intention behind getting the currently executed method's name, but if that's just for debugging purpose, then logging frameworks like "logback" can help here. For example, in logback, all you need to do is to use the pattern "%M" in your logging configuration. However, this should be used with caution as this may degrade performance.
Just in case the method which name you want to know is a junit test method, then you can use junit TestName rule: https://stackoverflow.com/a/1426730/3076107
I use this code snippet with the latest Android Studio with the latest Java update. It can be called from any Activity, Fragment, etc.
public static void logPoint() {
String[] splitPath = Thread.currentThread().getStackTrace()[3]
.toString().split("\\.");
Log.d("my-log", MessageFormat.format("{0} {1}.{2}",
splitPath[splitPath.length - 3],
splitPath[splitPath.length - 2],
splitPath[splitPath.length - 1]
));
}
call it like this
logPoint();
output
... D/my-log: MainActivity onCreate[(MainActivity.java:44)]
Most answers here seems wrong.
public static String getCurrentMethod() {
return getCurrentMethod(1);
}
public static String getCurrentMethod(int skip) {
return Thread.currentThread().getStackTrace()[1 + 1 + skip].getMethodName();
}
Example:
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) );
}
Outputs:
aaa -> aaa
aaa -> aaa
main -> main
I rewritten a little the maklemenz's answer:
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);
}
MethodHandles.lookup().lookupClass().getEnclosingMethod().getName();
What's wrong with this approach:
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);
}
}
And before people go crazy about using System.out.println(...) you could always, and should, create some method so that output can be redirected, e.g:
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());
}
}