1

Simple question: How can I differentiate a default constructor. i.e:

class AClass { } // will have a default no args constructor -> public AClass() {}

from one specified like:

class AClass {
    private final int i;

    public AClass() { i = 0; }
}

Checking the options reflection libraries provide I am not able to find any that allows me to distinguish one from another...

I've tried mostly with the methods provided by Class#get*Constructor(s)

Maybe I got tunnel vision, and I am forgetting something or there is another approach to this I am missing... any help would be appreciated!

EDIT:

This is the method I'm using, there is where I need to detect if such constructor is user defined or not:

    protected void adaptAfterLoading(final Class<?> loadedClass) {
        Arrays.asList(loadedClass.getDeclaredConstructors()).forEach(System.out::println);
        System.out.println("$$$$$$$$$$$ " + loadedClass.getDeclaredConstructors());
        Arrays
                .stream(loadedClass.getDeclaredConstructors())
                .filter(
                        ((Predicate<Constructor<?>>) Constructor::isSynthetic)
                                .negate())
                .map(ConstructorRep::loadFrom)
                .forEach(this::addConstructor);
    }

So... in case you were wondering why isSynthetic does not work:

From here:

13.1. The Form of a Binary - 7. Any constructs introduced by a Java compiler that do not have a corresponding construct in the source code must be marked as synthetic, except for default constructors, the class initialization method, and the values and valueOf methods of the Enum class.

Ordiel
  • 2,442
  • 3
  • 36
  • 52
  • Why do you really want to know that? – uneq95 Jan 19 '19 at 16:50
  • Have you tried looking at the [Constructor class](https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Constructor.html) – Nikos Tzianas Jan 19 '19 at 16:52
  • 1
    I really doubt there is a way to differentiate it. The default constructor is added at compile time, since reflection is done at runtime, it has no difference. – Ricola Jan 19 '19 at 16:53
  • `Why do you really want to know that?:` Imagine the next requirement, for a given class write a method that will create the skeleton code for such class definition, constructors with their respective arguments, so with methods, must have the same declared fields and so on... but if there is no explicitly declared method/constructor/field it should not write it on the skeleton class code definition – Ordiel Jan 19 '19 at 16:59
  • That doesn't even make sense... There is always a constructor in the compiled class, even if you don't specify it explicitely. – Dorian Gray Jan 19 '19 at 17:05
  • @DorianGray exactly ... I know there is always one, I want to know if its possible in any way to differentiate the one given by the compilation process or the one defined in at the source code w/o having access to the source code, just to the compiled class – Ordiel Jan 19 '19 at 17:11
  • Ni, there isn't. – Dorian Gray Jan 19 '19 at 17:13
  • 1
    There isn't always a constructor in a class - there are some very odd synthetic classes which end up without one. [See here](https://stackoverflow.com/a/47883266/3788176). – Andy Turner Jan 19 '19 at 17:18
  • Ok, that's interesting, thanks. – Dorian Gray Jan 19 '19 at 17:26

1 Answers1

1

There is simply no way to detect that, as there is no difference in the compiled bytecode.

A class with default constructor

class AClass { } // will have a default no args constructor 

is implicitely compiled as

class AClass { 
    AClass() {}
}

The first form is merely syntactic sugar.

Also your next example

class AClass {
    private final int i;

    public AClass() { i = 0; }
}

Could be written with a default constructor in an equivalent form

class AClass {
    private final int i = 0;
}

Beside, I fail to see a use case where you would have to detect that.

Dorian Gray
  • 2,913
  • 1
  • 9
  • 25