I used the following code to identify the number of functions in a class. Similar way can any one help me to identify the number of functions in a java program. In my program i gave input file as a class. Guide me with the code to give input as a java program and to find the number of declared functions in it.
import java.lang.reflect.*;
import java.io.*;
import java.lang.String.*;
public class Method1 {
private int f1(
Object p, int x) throws NullPointerException
{
if (p == null)
throw new NullPointerException();
return x;
}
public static void main(String args[])throws Exception
{
int Mcount=0,MthdLen=0;
try {
Class cls = Class.forName("Madhu");
int a;
Method methlist[]= cls.getDeclaredMethods();
for (int i = 0; i < methlist.length;i++)
{
Method m = methlist[i];
Mcount = Mcount + 1;
MthdLen=MthdLen+(m.getName().length());
}
}
catch (Throwable e) {
System.err.println(e);
}
System.out.println("Length = " + MthdLen);
System.out.println("Mcount = " + Mcount);
}
}
First of all,
Class cls = Class.forName("Madhu");
Requires the fully qualified name of the desired class. e.g Class.forName("java.lang.Thread")'.
Secondly,
Method methlist[]= cls.getDeclaredMethods();
returns public, protected, private and default method of that specific class only (it excludes inherited methods).
Thirdly,
MthdLen=MthdLen+(m.getName().length());
Sums up the string length of the method name. What do you need this for? You could simply do a count as follows:
int MCount = cls.getDeclaredMethods().length; //If the "getDeclaredMethods()` doesn't return a null.
Finally, if you need to get all inherited public & protected methods of that class, you would do
Class<?> class2 = cls.getSuperClass();
//Get all methods using
Method[] methods2 = class2.getDeclaredMethods();
//Iterate through methods2 and retrieve all public, protected methods and add it to MCount.
Hope this helps.
Java doesn't have any functions so the answer is 0. ;)
If you are looking for the number of methods, you have to ask yourself, do you want to
include inherited methods.
count overriden methods once ore multiple times.
include all the methods in Object or not.
e.g.
public class Main {
static class A {
public String toString() {
return super.toString();
}
}
static class B extends A {
public String toString() {
return super.toString();
}
}
public static void main(String args[]) {
for(Class clazz = B.class;clazz != null;clazz = clazz.getSuperclass()) {
for(Method m: clazz.getDeclaredMethods())
System.out.println(m);
}
}
}
prints
public java.lang.String Main$B.toString()
public java.lang.String Main$A.toString()
protected void java.lang.Object.finalize() throws java.lang.Throwable
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
private static native void java.lang.Object.registerNatives()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
In JDK6+, you could compile the file at runtime using JavaCompiler, and use your old code to find the number of methods.
EDIT:
Bonus: Replace your code with
System.out.println("Total number of methods: " +
java.beans.Introspector.getBeanInfo( //your class name here
).getMethodDescriptors().length);
i use this code to find out count of method in a class inside of another class.
public class test1 {
public static void main(String[] args)
//if use in class
//Method[] s = getClass.getDeclaredMethods();
Method[] s = SmokeTestTests.class.getDeclaredMethods();
int methodCounter = 0;
for (Method method :
s) {
++methodCounter;
}
System.out.println(methodCounter);
}
Related
I have got the following problem (I simplified it).
I programmed an abstract class, like this:
public abstract class Calculation{
abstract public int multiply(int x);
public final static void main(String[] args){
for(int i=0; i<args.length; i++){
int x = Integer.parseInt(args[i]);
// I want to call the Method multiply here.
// Therefore I need an object here!
}
}
}
My abstract class has a main-Method which should evaulate my args and then call the method multiply. Now I want to make some other classes like
public class MOne extends Calculation{
public int multiply(int x){
return x;
}
}
public class MTwo extends Calculation{
public int multiply(int x){
return 2*x;
}
}
public class MThree extends Calculation{
public int multiply(int x){
return 3*x;
}
}
If I call on the console:
java MOne 5
java MTwo 5
java MThree 5
I want java to print 5,10 and 15.
Sadly I don't know how to instanciate the MOne-class respectivly MTwo and MThree in the Calculation-class. Does anyone know, how to make it?
It's possible but expensive because you have to search all classes on the classpath to find those that extend Calculation. A good tool for this is ClassGraph.
Try this code:
List<Class<Calculation>> calculations;
try (ScanResult scanResult = new ClassGraph().enableClassInfo().scan()) {
calculations = scanResult
.getSubclasses(Calculation.class.getName())
.loadClasses(Calculation.class);
}
for(Class<Calculation> calculation : calculations) {
Calculation calculationInstance = calculation.newInstance(); // needs null constructor
System.out.println("Java " + calculation.getName() + " " + calculationInstance.multiply(5));
}
Try this. You may need to find the equivalent to sun.java.command for non-Oracle JVM.
public abstract class Calculation {
abstract public int multiply(int x);
public final static void main(String[] args)
throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
InstantiationException, NoSuchMethodException, SecurityException {
String className = System.getProperty("sun.java.command").split(" ")[0]; // Oracle JVM only
Class<?> loadedClass = Class.forName(className);
Method multiplyMethod = loadedClass.getMethod("multiply", int.class);
Object newInstance = loadedClass.newInstance();
for(int i=0; i<args.length; i++){
int x = Integer.parseInt(args[i]);
System.out.println("java " + "className " +multiplyMethod.invoke(newInstance, x));
}
}
Run it with the name of the inheriting class as the first argument and inheriting and base class on classpath:
java -cp path/to/jar;path/to/mine_class MOne 5
I'm trying to access a private method, but it doesn't let me to, and throws the exception. How can I avoid the exception? I've tried a lot of other questions, but they all just point to using setAccessible(true), which I'm already using right now.
import java.lang.reflect.*;
class Reflection {
public static void main (String[] args) {
try {
//Get class instance
ReflectionExamples re = new ReflectionExamples();
Class<?> c = re.getClass();
System.out.println("Class name is " + c.getName());
//Get constructor of class
Constructor<?> cons = c.getConstructor();
System.out.println("Constructor name is " + cons.getName());
System.out.println("List of methods are:");
//Iterate all methods
Method[] methods = c.getMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
//Desired method to call
Method call = c.getDeclaredMethod("e");
//Unlock the private Method
call.setAccessible(true);
//Invoke the Method
call.invoke(re);
//Desired method to call
Method call2 = c.getDeclaredMethod("a");
//Invoke the method
call2.invoke(c);
} catch(Throwable e) {
System.err.println(e);
}
}
}
class ReflectionExamples {
private String string = "String222222";
public int i = 0;
public ReflectionExamples() {
string = "String";
}
private void e() {
System.out.println("Char entered is not valid.");
}
public void f(char a) {
System.out.println("awojiewfihuerhkuah");
}
public void a() {
System.out.println(string);
}
}
And I get:
java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
Suppose I have the following methods and their invocations:
public static void main(String[] args) {zoo();}
public static void zoo() {zoo(0);}
public static void zoo(int i) {too(i);}
public static void too(int i) {...}
Thread.currentThread().getStackTrace() will return me with something like:
A.too(A.java:56)
A.zoo(A.java:65)
A.zoo(A.java:60)
A.main(A.java:80)
With this output, I cannot distinguish the 2 zoos I defined in my example, one without any parameter (zoo()) and one with an integer parameter (zoo(int i)). The reason is because only method names rather than their signatures are outputted. Is there a way to get a stack of method signatures?
The documentation of the StackTraceElement in Java 13 clearly shows that there is no way to do that. You can identify the overloaded method by its line number with your human brain. Automatizing this task would be overkill if even possible (would require using hard reflection), although I do not close out that some lib can do that.
Remark: the binary file format of the .class files actually has the method signature information (at least the parameter list), thus it is not impossible, only no one developed it until now.
You can not get the method signature from a StackTraceElement, but since you’re interested in getting the stack trace of the currentThread, you can use StackWalker instead. Since Java 10, it supports getting the method type from a StackFrame.
For example
public class StackWalkerExample {
public static void main(String[] args) {
zoo();
System.out.println();
Arrays.asList("foo", "bar").sort((a, b) -> { getMethods(); return 0; });
}
public static void zoo() {zoo(0);}
public static void zoo(int i) {too(i);}
public static void too(int i) { getMethods(); }
static void getMethods() {
var sw = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
var methods = sw.walk(frames ->
frames.skip(1).map(StackWalkerExample::toMethod).toArray(Method[]::new));
for(var m: methods) System.out.println(m);
}
static Method toMethod(StackWalker.StackFrame f) {
try {
return f.getDeclaringClass().getDeclaredMethod(
f.getMethodName(), f.getMethodType().parameterArray());
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
}
}
will print
public static void StackWalkerExample.too(int)
public static void StackWalkerExample.zoo(int)
public static void StackWalkerExample.zoo()
public static void StackWalkerExample.main(java.lang.String[])
private static int StackWalkerExample.lambda$0(java.lang.String,java.lang.String)
private static int java.util.TimSort.countRunAndMakeAscending(java.lang.Object[],int,int,java.util.Comparator)
static void java.util.TimSort.sort(java.lang.Object[],int,int,java.util.Comparator,java.lang.Object[],int,int)
public static void java.util.Arrays.sort(java.lang.Object[],java.util.Comparator)
public void java.util.Arrays$ArrayList.sort(java.util.Comparator)
public static void StackWalkerExample.main(java.lang.String[])
Details of the sorting implementation may vary
Put simply, I have an abstract class containing several variables and methods. Other classes extend this abstract class, yet when I try to read the private variable in the abstract class by calling getter methods inside the abstract class, it returns null as the value of the variable.
public class JavaApplication {
public static void main(String[] args) {
NewClass1 n1 = new NewClass1();
NewClass2 n2 = new NewClass2();
n1.setVar("hello");
n2.print();
}
}
public class NewClass1 {
public String firstWord;
public void setVar(String var) {
firstWord = var;
}
public String getVar () {
return firstWord;
}
}
public class NewClass2 extends NewClass1{
public void print() {
System.out.println(makeCall());
}
public String makeCall() {
return getVar();
}
}
Still prints out null.
Until the String is initialized, it will be null. You should probably have a constructor in the abstract class to set it.
public abstract class Command
{
String firstWord; // = null
protected Command(){}
protected Command( String w )
{
firstWord = w;
}
//...
}
public class Open extends Command
{
public Open()
{
this( "your text" );
}
public Open( String w )
{
super( w );
}
// ...
}
If you need to modify the firstWord string everytime execute() is called then it may not be necessary to use a constructor with a String parameter (I added a default constructor above). However, if you do it this way then either
You must make sure setFirstWord() is called before getFirstWord(), or,
Handle the case when getFirstWord() returns null. This could be by simply using a default value (maybe determined by each subclass) or something else, like failing to execute.
As I do not know all the details of your implementation I cannot tell you further information.
Consider the following code in Python:
class A(object):
CLASS_ATTRIBUTE = 42
def f(self):
return "CLASS_ATTRIBUTE: %d" % self.CLASS_ATTRIBUTE
class B(A):
CLASS_ATTRIBUTE = 44
Now A().f() and B().f() return "CLASS_ATTRIBUTE: 42" and "CLASS_ATTRIBUTE: 44" respectively.
How can I achieve a similar effect in Java? I want a CLASS_ATTRIBUTE field to be initialized statically and redefined in the inherited class but the f method should be only defined in the base class.
Is there a particular reason you want the attribute to be static? In Java the typical way you'd do this is to have A contain a protected variable that you then set in the constructors of the 2 classes:
public class A
{
protected int CLASS_ATTRIBUTE;
public A()
{
CLASS_ATTRIBUTE = 42;
}
public String f()
{
return "CLASS_ATTRIBUTE: " + CLASS_ATTRIBUTE;
}
}
public class B extends A
{
public B()
{
CLASS_ATTRIBUTE = 44;
}
}
Alternatively (and probably more consistent with Java design patterns) you'd declare a function that you can override to return the value instead of using a member variable.
Short answer: you cant solve it like this in Java. You'll have to solve it in another way.
In Java you can't override or "redeclare" fields in subclasses, and you can't override static methods.
It can be solved using an ugly reflection-hack (should be avoided though):
public class Main {
public static void main(String... args) {
A a = new A();
B b = new B();
System.out.println(a.f()); // Prints 42.
System.out.println(a.fReflection()); // Prints 42.
System.out.println(b.f()); // Prints 42.
System.out.println(b.fReflection()); // Prints 44.
}
}
class A {
static int CLASS_ATTRIBUTE = 42;
public int f() {
return CLASS_ATTRIBUTE;
}
public int fReflection() {
try {
return getClass().getDeclaredField("CLASS_ATTRIBUTE").getInt(null);
} catch (Exception wontHappen) {
return -1;
}
}
}
class B extends A {
// Compiles, but will not "override" A.CLASS_ATTRIBUTE.
static int CLASS_ATTRIBUTE = 44;
}
You can't do this directly with only a variable, because in Java variables cannot override (they only shadow the super classes variables).
You need to use a protected "getter" method, which can then be overridden by the subclass:
class A
{
private int attribute=42;
...
protected int getAttribute() {
return attribute;
}
}
class B
extends A
{
private int attribute=44;
...
protected int getAttribute() {
return attribute;
}
}
But note there's a special consideration to calling methods from an object's constructor, in that it allows object code to run before object construction is complete.
I'm not sure if you meant "statically" literally or not, but here's a brief example of how inheritance at it's most basic form looks in Java. Note that using a getter method to access the variable is a better idea for several reasons -- this is just an example.
public class Dog {
protected String whatISay = "Woof!";
public void speak(){
System.out.println(whatISay);
}
}
public class Poodle extends Dog {
public Poodle(){
whatISay = "Yap!";
}
}
public class Main {
public static void main(String[] args){
Poodle fluffy = new Poodle();
fluffy.speak();
Dog dog = new Dog();
dog.speak();
}
}
Yap!
Woof!
This way of doing it introduces as little intrusion as I could think of. setAttribute() could be named something like setDefaultValue() if that's clearer.
public class A
{
protected int attribute;
public A()
{
setAttribute();
}
public String f()
{
return "CLASS_ATTRIBUTE: " + attribute;
}
protected void setAttribute()
{
attribute = 42;
}
}
public class B extends A
{
#Override
protected void setAttribute()
{
attribute = 44;
}
}
public class Main
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
System.out.println("A: " + a.f());
System.out.println("B: " + b.f());
}
}