Consider the following annotation class
#Target(AnnotationTarget.TYPE)
annotation class ML(val size: Int)
By default, the retention policy is RUNTIME, thus this annotation must be accessible through reflection.
Now I have
val a: #ML(2) List<Int> = listOf(1)
which does compile, but, if examined in the debugger, one gets
a::class.annotations.size = 0
What am I doing incorrectly and what is the correct way to annotate types without wrapping things into classes and annotating properties?
The expression you used:
b::class.annotations
Can be used to obtain the annotations on the class returned by b. List is not annotated with anything, so you get no annotations. Given the location where you put the annotation, you actually want to get the annotations for the return type of property b:
::b.returnType.annotations
EDIT: I thought b was a property. What you want to do is impossible, because annotation information isn't stored for local variables on the JVM. See this question: Can I get information about the local variables using Java reflection? (about Java but it's all the same). If b had been a class property or a top-level property, then what I showed would have applied.
The other day I noticed that I sometimes put data in front of objects and other times not:
object A
data object B
What's the difference between an object and a data object?
The fact that data is allowed on an object declaration is in fact a bug (KT-6486) which should be fixed.
data is an annotation which causes the compiler to generate equals, hashCode, toString, copy and componentN functions. It doesn't make much sense when applied to an object declaration for two reasons:
An object declaration cannot have a constructor, and all these functions work based on properties defined in the primary constructor.
There's only one instance of any object at runtime.
So no componentN functions would be generated, copy can't work, and the generated equals/hashCode/toString implementations will be equivalent to the default ones from Any which are based on identity.
I need to expose the "is mapped?" state of an instance of a class. The outcome is determined by a basic check. It is not simply exposing the value of a field. I am unsure as to whether I should use a read-only property or a method.
Read-only property:
public bool IsMapped
{
get
{
return MappedField != null;
}
}
Method:
public bool IsMapped()
{
return MappedField != null;
}
I have read MSDN's Choosing Between Properties and Methods but I am still unsure.
The C# standard says
§ 8.7.4
A property is a member that provides access to a characteristic of an object or a class. Examples of properties include the length of a string, the size of a font, the caption of a window, the name of a customer, and so on. Properties are a natural extension of fields. Both are named members with associated types, and the syntax for accessing fields and properties is the same. However, unlike fields, properties do not denote storage locations. Instead, properties have accessors that specify the statements to be executed when their values are read or written.
while as methods are defined as
§ 8.7.3
A method is a member that implements a computation or action that can be performed by an object or class. Methods have a (possibly empty) list of formal parameters, a return value (unless the method’s return-type is void ), and are either static or non-static.
Properties and methods are used to realize encapsulation. Properties encapsulate data, methods encapsulate logic. And this is why you should prefer a read-only property if you are exposing data. In your case there is no logic that modifies the internal state of your object. You want to provide access to a characteristic of an object.
Whether an instance of your object IsMapped or not is a characteristic of your object. It contains a check, but that's why you have properties to access it. Properties can be defined using logic, but they should not expose logic. Just like the example mentioned in the first quote: Imagine the String.Length property. Depending on the implementation, it may be that this property loops through the string and counts the characters. It also does perform an operation, but "from the outside" it just give's an statement over the internal state/characteristics of the object.
I would use the property, because there is no real "doing" (action), no side effects and it's not too complex.
I personally believe that a method should do something or perform some action. You are not performing anything inside IsMapped so it should be a property
I'd go for a property. Mostly because the first senctence on the referenced MSDN-article:
In general, methods represent actions and properties represent data.
In this case it seems pretty clear to me that it should be a property. It's a simple check, no logic, no side effects, no performance impact. It doesn't get much simpler than that check.
Edit:
Please note that if there was any of the above mentioned and you would put it into a method, that method should include a strong verb, not an auxiliary verb like is or has. A method does something. You could name it VerifyMapping or DetermineMappingExistance or something else as long as it starts with a verb.
I think this line in your link is the answer
methods represent actions and properties represent data.
There is no action here, just a piece of data. So it's a Property.
In situations/languages where you have access to both of these constructs, the general divide is as follows:
If the request is for something the object has, use a property (or a field).
If the request is for the result of something the object does, use a method.
A little more specifically, a property is to be used to access, in read and/or write fashion, a data member that is (for consuming purposes) owned by the object exposing the property. Properties are better than fields because the data doesn't have to exist in persistent form all the time (they allow you to be "lazy" about calculation or retrieval of this data value), and they're better than methods for this purpose because you can still use them in code as if they were public fields.
Properties should not, however, result in side effects (with the possible, understandable exception of setting a variable meant to persist the value being returned, avoiding expensive recalculation of a value needed many times); they should, all other things being equal, return a deterministic result (so NextRandomNumber is a bad conceptual choice for a property) and the calculation should not result in the alteration of any state data that would affect other calculations (for instance, getting PropertyA and PropertyB in that order should not return any different result than getting PropertyB and then PropertyA).
A method, OTOH, is conceptually understood as performing some operation and returning the result; in short, it does something, which may extend beyond the scope of computing a return value. Methods, therefore, are to be used when an operation that returns a value has additional side effects. The return value may still be the result of some calculation, but the method may have computed it non-deterministically (GetNextRandomNumber()), or the returned data is in the form of a unique instance of an object, and calling the method again produces a different instance even if it may have the same data (GetCurrentStatus()), or the method may alter state data such that doing exactly the same thing twice in a row produces different results (EncryptDataBlock(); many encryption ciphers work this way by design to ensure encrypting the same data twice in a row produces different ciphertexts).
If at any point you'll need to add parameters in order to get the value, then you need a method. Otherwise you need a property
IMHO , the first read-only property is correct because IsMapped as a Attribute of your object, and you're not performing an action (only an evaluation), but at the end of the day consistancy with your existing codebase probably counts for more than semantics.... unless this is a uni assignment
I'll agree with people here in saying that because it is obtaining data, and has no side-effects, it should be a property.
To expand on that, I'd also accept some side-effects with a setter (but not a getter) if the side-effects made sense to someone "looking at it from the outside".
One way to think about it is that methods are verbs, and properties are adjectives (meanwhile, the objects themselves are nouns, and static objects are abstract nouns).
The only exception to the verb/adjective guideline is that it can make sense to use a method rather than a property when obtaining (or setting) the information in question can be very expensive: Logically, such a feature should probably still be a property, but people are used to thinking of properties as low-impact performance-wise and while there's no real reason why that should always be the case, it could be useful to highlight that GetIsMapped() is relatively heavy perform-wise if it in fact was.
At the level of the running code, there's absolutely no difference between calling a property and calling an equivalent method to get or set; it's all about making life easier for the person writing code that uses it.
I would expect property as it only is returning the detail of a field. On the other hand I would expect
MappedFields[] mf;
public bool IsMapped()
{
mf.All(x => x != null);
}
you should use the property because c# has properties for this reason
Using Jackson 2.5+, what JsonSerializer methods must be overridden by a wrapping JsonSerializer returned from:
BeanSerializerModifier.modifySerializer(SerializationConfig sc, BeanDescription bd, JsonSerializer<?> js)
I'm definitely overriding serialize(...), because I'm filtering out some objects from being serialized based on the values of their properties in that override. Otherwise, if the object isn't filtered out by its property values, I serialize normally by calling js.serialize(...), where js is the JsonSerializer that was passed as an argument to modifySerializer.
But I'm not sure if I should also override any of the following other JsonSerializer methods:
getDelegatee()
replaceDelegatee(...)
isUnwrappingSerializer()
unwrappingSerializer(...)
handledType()
usesObjectId()
isEmpty(T)
isEmpty(SerializerProvider, T)
acceptJsonFormatVisitor(...)
serializeWithType(...)
e.g., Should getDelegatee() return js?
Why would I want to allow replaceDelegatee(...) to replace js as the delegatee? If I should allow this, then I'd have to save js to a field so I could replace it.
As per my other answer, some of those you do want to (re)define, others not. (1), (8), (9) and (10) do make sense; (7) is deprecated and not needed any more. (5) should be defined by base class (at least if extending StdSerailizer), if not defined, should be defined mostly because it is used by some error reporting.
(3) and (4) are things you may want to support, if you want #JsonUnwrapped to be implemented for the type. If you are delegating to a standard POJO serializer, this is probably true. If not implemented, #JsonUnwrapped will basically have no effect on properties with your custom serializer.
(6) applies similarly for #JsonIdentityInfo; but note that object identity may be tricky to handle with delegation model.
As to delegatee replacement... I would not worry about that one. I think it was added speculatively, and is not actually used by the framework.
I am learning from Stanford's CS193P course. In the class, Paul has a demo project, "Calculator", where he uses id as the type of a property. He intends to not use a specific class, because he does not want to create a new class and then he does not need to write documentation, and even when it is updated, he does not need to redesign the class. id can solve all these problems.
Is this a really a good way? id is the return type of the property, and used as the parameter type of another method. How does the caller know what id is, and how to provide the correct object? By reading code comments?
In general, is there any good reason to use id as a return type or parameter type in public API? (Except init and factory method, though even for those, instancetype is recommended.)
If your method returns a class that is a member of a class cluster, you should return id.
If you're returning an object whose class is opaque, isn't declared in a public header, you should return id. (Cocoa occasionally uses such objects as tokens or context data.)
Container classes should always accept and return their constituents as ids.