How to get only declared members (not inherited) with Kotlin Reflection? - kotlin

Is there any way to get only the declared members of a class (not inherited) with Kotlin Reflection?
Something equivalent to getDeclaredMethods(), or ...Fields(), in Java, but for members and JVM free, which:
Returns an array containing Method objects reflecting all the declared methods of the class ... but excluding inherited methods.
Or like a binding flag, such as BindingFlags.DeclaredOnly of dotnet.

Because the reflection is based on the class, So the following is only for the kotlin/JVM, not suitable for the Kotlin/JS or Kotlin/Native.
For the Kotlin/JS it supports limit, for detail, you can see this
document
The only supported parts of the API are: (::class),KType and typeOf
Firstly, you can use the SomeClass::class.java.declaredMethods to get the
getDeclaredMethods. That is the java method. Because the Kotlin file after compiled it is still a class. so you can directly use it.
You can also add the kotlin reflect to get the KClass, then use the declaredFunctions to get. Here is the Document
Returns all functions declared in this class. If this is a Java class, it includes all non-static methods (both extensions and non-extensions) declared in the class and the superclasses, as well as static methods declared in the class
For how to get the KClass, you can use the following code
Class.forName("mypackage.MyClass").kotlin.declaredFunctions
Besides the method, the other property you can also get. such as
declaredMembers
Returns all functions and properties declared in this class. Does
not include members declared in supertypes.
allSuperclasses
functions
Returns all functions declared in this class, including all non-static methods declared in the class and the superclasses, as well as static methods declared in the class.
you can read the document using it.

Related

Is there a solution to "Cannot access '<init>': it is private in XYZ?

I included a library I'd like to use, but in accessing to one of its classes I get the error message,
"Cannot access '<init>': it is private in [class name]
Is there something I can do to rectify this on my side, or am I just stuck to not use the package?
The error means the constructor is private. Given your comment, I'm assuming you're using a library. If this is the case, you'll have to find a different way to initialize it. Some libraries have factories or builders for classes, so look up any applicable documentation (if it is a library or framework). Others also use the singleton pattern, or other forms of initialization where you, the developer, don't use the constructor directly.
If, however, it is your code, remove private from the constructor(s). If it's internal and you're trying to access it outside the module, remove internal. Remember, the default accessibility is public. Alternatively, you can use the builder pattern, factory pattern, or anything similar yourself if you want to keep the constructor private or internal.
I came across this issue when trying to extend a sealed class in another file. Without seeing the library code it is hard to know if that is also what you are attempting to do.
The sealed classes have the following unique features:
A sealed class can have subclasses, but all of them must be declared in the same file as the sealed class itself.
A sealed class is abstract by itself, it cannot be instantiated directly and can have abstract members.
Sealed classes are not allowed to have non-private constructors (their constructors are private by default).
Classes that extend subclasses of a sealed class (indirect inheritors) can be placed anywhere, not necessarily in the same file.
For more info, have a read at https://www.ericdecanini.com/2019/10/14/kotlins-sealed-class-enums-on-steroids/
Hopefully, this will help others new to Kotlin who are also encountering this issue.
Class constructors are package-private by default. Just add the public keyword before declaring the constructor.
By default constructor is public so need to remove internal keyword.

Why can this Kotlin Object Inherit from itself?

I am trying to interface with TeamCity using Kotlin.
When you convert a project to Kotlin (from .xml) you will have a file called Project.kt which is where you can set all your configurations.
With no editing mine looks like this:
object Project : Project(/* Some Function Literal with Receiver */)
This looks like circular inheritance? There are imports that I am omitting, but surely that wouldn't make that big of a difference? Could the name be interpreted in different ways depending on where it appears in the file?
My mind is interpreting the object signature like this:
object = Object declaration for singleton.
Project (first occurrence) = Name of object.
: = Inheritance marker.
Project (second occurrence) = Base class to inherit from.
() = Constructor call to the base class.
Is this circular inheritance or have I missed something big about Kotlin? I have looked here and here and can't seem to find my answer.
Assuming qualified classes other.Project and my.Project, you'd have two different classes defined with the same name, in different packages.
Since my.Project is defined as a Singleton, you cannot extend from it and the actual base class is other.Project. Kotlin is clever enough to differentiate. If you would try to do the same with a class declaration, you'd get a circular inheritance.
You could even try to force extending from the Singleton explicitly, but then you'll have the error Cannot inherit from a Singleton. So basically this only works well if you imported the right classes.

Static method (which isn't class method) in objective C

While reading THIS question and accepted answer for the question, I was unable to get the difference between these two types of methods. Actually got the point by reading the example, but then, I was not able to write my own static method.
I tried googling create static method in objective c static methods
Which returned me links to THIS and THIS question. But, the example here are CLASS methods as per the first link in the question. Which is confusing me.
Can anyone here show me how do I create a static method which is not a class method ?
Any light on this would be appreciated.
The problem you are having is the following - there are no static methods in Obj-C, that's why you cannot create them.
The difference between static and class methods is a difference between language concepts. You can find static methods in languages like Java or C++, you will find class methods in languages like Obj-C and Ruby.
The principal difference is that
Static methods are shared between all instances (this doesn't exist in Obj-C). They are dispatched statically (at compile time) depending on the type of the variable.
Class method is a method on a class. In languages like Obj-C and Ruby a class itself is an instance of another class (metaclass). Using + before a method declaration means the method will be defined on the class. Technically, it's just an instance method, just on a different object.
Don't worry if you don't understand the concept of class method perfectly, it takes time. To simplify, you can consider it as a method shared between instances, but it can be overriden in subclasses.

Proper use of private constructors

I was reading about private constructor and found a few points that I couldn't understand. It said, if you declare a constructor as private:
That class cannot be explicitly instantiated from another class
That class cannot be inherited
Should be used in classes containing only static utility methods
My first question: Point 2 says the class cannot be inherited. Well, if you declare a class private then it would still satisfy this property. Is it because, if a class is private, it can still be explicitly instantiated from outside by another class?
My second question: I don't understand point 3. If I have a helper class which is full of static methods, I would never have to instantiate that class to use the methods. So, what is the purpose of a constructor in that class which you are never going to instantiate?
Answer for Java
Question 1 You're confusing a private class, with a class that has a private constructor. Private constructors are used mainly for static classes that are not meant to be instatiated (i.e. they just have a bunch of static methods on them).
Question 2 Exactly there is no need for a constructor so you have to explicitly create a private constructor so that it does not get a default constructer that the JVM will provide if none is defined
An empty class with no methods defined will always be given a no argument constructor by the JVM by default
I take java and c++ as an examples (not the best OO languages known, but very popular) - since you are not defining which languge do you mean.
Ad.2. In these languages you must either call superclass constructor explicitly or it is implicitly called for you. From a subclass you cannot call private methods (only public and protected) - this rule applies to constructors as well. This means if the class has only private constructors, there is no way to call one in subclass constructor. So you cannot subclass such class.
Ad. 3. It is just to avoid confusion - since this class is only a container for utility methods, there is no point in instantiating it. This way you can enforce this rule at compile time.

Getting list of class methods

I'm looking for a way to get a static methods list for a certain class. I only get a list of instance methods with the runtime function class_copyMethodList().
Is there a way to list static methods?
Each Class is itself an Objective-C object, and in turn has an object which is (sort of) its class. You need to get this metaclass object (see also: "[objc explain]: Classes and Metaclasses"), and then ask that for its methods (which will be the class methods* you are after).
From the class_copyMethodList docs:
###Discussion
To get the class methods of a class, use class_copyMethodList(object_getClass(cls), &count)
*There's no such thing as static methods in Obj-C.