Dynamic value in Custom Annotation - java

Is there a way I could pass in a dynamic value into a Custom Annotation?
For example as follows:
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface CustomAnnot {
String[] requestKeys();
}
When annotating, I want to pass in the value of the argument dynamically.
#CustomAnnot(requestKeys = {"id"}) // or maybe "#id"
public Object get(String id) {}
To note the above won't just work. Need some form of parsing for this to work.
How can I go about doing this? Trying to find online references and but unable to find anything to aid in this implementation.
#Cacheable in Spring is able to do this thus clearly this is possible. Tried to have a look over the implementation for #Cacheable and to be honest got lost. It's massive and a struggle to debug. Could I get some advice on this implementation or if anyone familiar point to the part where cacheable implements this? Thanks.
EDIT:
I need a way to get values from arguments in a method.
Example.
// maybe in this method I only want String b and c
String method1(String a, String b, String c){
return null;
}
// maybe here I want String a and c
String method2(int d, String a, String b, String c){
return null;
}
// just 1 argument here so only need String a
String method3(String a){
return null;
}
I am looking for a single way to get the values of what I need in 1 way.
I want to write this functionality once and be done with it, not have to come back again for a different method signature.
Thus I was going for a custom annotation which gives me flexibility to decide what values I want so I can pass in an array .

Related

Is it standard way to use javaargs instead of overloading in Java?

Is it a standard way to code or any other alternatives are there? I thinking this a while about the code that I've written. Finally gave up and thought to check with you guys.
Here is the scenario I had.
private String functionNameXYZ(String a,String b) {
//Logic goes here
}
private String functionNameXYZ(String a,String b,String c) {
//Same logic goes here , Nothing much difference because of String c
}
So I tho
ught to skip two functions for same purpose and I created a single function as below.
private String functionNameXYZ(String a, String b,String... c){
return performlogic(a,b,(c.lenght!=0)? c[0]:null);
}
private String performlogic(String a,String b, String c) {
//logic , return "string"
}
Which is standard way of coding? Was it to seperate logic into new method instead of repeating[Second case] or Was it other way? Kindly suggest if you find any better ways?
If your only two valid options are two String arguments and three String arguments, using varargs is a tad overkill, and worse - it's confusing, as it implies that you could also pass five or ten or a gazillion arguments. Instead, you could do something much simpler:
private String functionNameXYZ(String a, String b) {
functionNameXYZ(a, b, null);
}
private String functionNameXYZ(String a, String b, String c) {
// One place for the logic
}
Your first scenario is fine, except you want to maybe take any large bulk of common code in the functions and put it in a separate function (or more easily, have the function with less params call the one with more).
The overloading is fine, but rewriting the same code both places is not good practice.
Also, since Java doesn't have default parameters, I'm not too keen on having a public method's argument that is nullable, even if noted on the JavaDocs. Overloading is the way to go.
I think you need to ask yourself a question: what input is legal?
If your program should handle 2...n arguments, then absolutely go with the varargs. However if the legal input to your function is either exactly 2 or 3 arguments, then you should use the pattern:
private String functionNameXYZ(String a, String b) {
// logic of function
}
private String functionNameXYZ(String a, String b, String c) {
// place the logic for handling 'c' input then call
functionNameXYZ(a, b);
}
Alternatively, as the other poster mentioned:
private String functionNameXYZ(String a, String b) {
functionNameXYZ(a, b, null);
}
private String functionNameXYZ(String a, String b, String c) {
// One place for the logic
}
Personally, I prefer the first approach as it clearly separates the logic used to handle the 'c' parameter and the others. This is commonly used when you can seperate that logic, e.g. in constructors. However, when the logic can't easily be untangled go for the second approach.

Constructor with Optional<String>

I have written the following code:
void Test(A a) {
B b = new B(a.getName());
}
So, the constructor of B expects a String. It looks like the following:
protected B (String name) {
super(name, KIND);
this.name = name;
}
But a.getName() gives me a name with Optional<String> as return value and I do not want to change that. Therefore, I try to change the parameter of the constructor B (I replace String name with Optional<String>), but then Eclipse underlines super(name, KIND) and this.name = name with red and Eclipse recommends to change the parameter of the constructor again to String name.
How can I solve it?
best regards,
An Optional<String> might contain a String, so you need to check for that (and generally speaking, handle the case where it is absent). So your Test() method might look like this:
void Test(A a){
// Consider adding a a.getName().isPresent() check and handling the false
// case if you need to. Otherwise you'll get an IllegalStateException.
B b = new B (a.getName().get());
}
In general, the better practice is to leave your constructor parameter as a String, and then convert it into a n Optional<String> when you store it.
The alternative, if you really want users to pass in Optionals, which does sometimes make sense, is to fix the super() constructor to also take an Optional<String>. If you can't do that, you need to similarly call .get() and pass the resulting String into super(); again handling the absent case as needed.
You could make another constructor that takes aan Optional.

Java String predefine

I'm sure this question has allready been answered somewhere, but I' ve searched for half an hour now and I'm running out of keywords, because I have absolutly no idea how to do this.
I have a constructor for a class like this
public MyClass (String name)
{}
what I want is to define Strings so that only those Strings can be entered.
I assume it has something to do with static final strings, but there is quite a lot to be found to those and I dont know how to narrow down the search. Please tell me how that thing I want to do is called, so that I can search for it.
Edit:
Example to what I want:
I want to somehow define a number of Strings. (Or do somethig else that has the same effect, as I said I dont know how to do it)
String one = "ExampleOne";
String two = "ExampleTwo";
so that when I call the constuctor
MyClass myClass = new MyClass("somethingElse");
the constructor wont take it. Or even better eclipse allready showing my what options I have like it does whit "Color. "
Yes you have right you can not override String class because it is final so simply you can create your own StringWrapper class that wraps string.
public class StringWrapper{
private String content;
public StringWrapper(String c){
content = c;
}
//all your methods and fields there, for example delegated methods
public String toString(){
return content.toString();
}
}
But Enum could be also used in your case then you define your Enum values
public enum Color {
WHITE, BLACK, RED, YELLOW, BLUE; //; is required here.
#Override public String toString() {
//only capitalize the first letter
String s = super.toString();
return s.substring(0, 1) + s.substring(1).toLowerCase();
}
}
public myClass (Color color)
{}
There are two ways you can acheive this, either use a enum as constructor parameter. The enum itself contains only the allowed values, which is what I would do, keep everythign nice an oop and you can add logic to enums at a later date.
Or alternatively you can just check if the constuctor paramters value is valid, by performing a comparison and throwing an exception if not in allowed values. Have a predfined list and then, myList.contains(myString) - throw exception if false.
What I want is to define String so that only those Strings can be entered
I think that what you are after are Enums.
Enums will allow you to define a range of values which you can then use. In the example I have linked, the developer can restrict the type of input that he/she will receive to the days of the week.
You can check it in constructor's body at runtime, or if you want to compile-time checks, then you can use enum type argument (enum is a predefined set of constants).
From what I understand it seems like you want to limit what the String can be.
You would do this by putting conditional statements inside the constructor to weed out any Strings you don't want to be entered that would either notify the user that it is an invalid string or throw an exception, and the remainder of the constructor would only be executed in an else statement once it has passed all the tests making sure it is a valid String

Set custom variables from method

I have some String variables:
private String cur, last, avg, vol, shop;
I have method which accept String and gives me some result:
public void SomeMethod(String somestring)
{
//Here some action with `string`
System.out.print(result)
}
So i want to put result into one of String variables, but this variable must be named as value of somestring in my method. Some method which compare somestring with existent variables names. Is such a thing even possible?
You're talking about variable variable name. They're a native feature in PHP, but not in Java, however you can achieve similar functionality using a HashMap, or using Reflection. I'm going to show you the HashMap option, because frankly Reflection is the work of Satan.
Example
Now the way to implement this is like this:
public void someMethod(String name, String value)
{
values.put(name, value);
}
And you can retrieve them with
public void getValue(String name)
{
return values.get(name);
}
I won't write the code for you, because it's a simple transformation to get this to work in your use case.
A hint because I'm feeling nice
You can replace all of your String variables with a Map implementation. Then simply add the values to the Map, as and when the need arises.

Output Parameters in Java

With a third party API I observed the following.
Instead of using,
public static string getString(){
return "Hello World";
}
it uses something like
public static void getString(String output){
}
and I am getting the "output" string assigned.
I am curious about the reason of implementing such functionality. What are the advantages of using such output parameters?
Something isn't right in your example.
class Foo {
public static void main(String[] args) {
String x = "foo";
getString(x);
System.out.println(x);
}
public static void getString(String output){
output = "Hello World"
}
}
In the above program, the string "foo" will be output, not "Hello World".
Some types are mutable, in which case you can modify an object passed into a function. For immutable types (such as String), you would have to build some sort of wrapper class that you can pass around instead:
class Holder<T> {
public Holder(T value) {
this.value = value;
}
public T value;
}
Then you can instead pass around the holder:
public static void main(String[] args) {
String x = "foo";
Holder<String> h = new Holder(x);
getString(h);
System.out.println(h.value);
}
public static void getString(Holder<String> output){
output.value = "Hello World"
}
That example is wrong, Java does not have output parameters.
One thing you could do to emulate this behaviour is:
public void doSomething(String[] output) {
output[0] = "Hello World!";
}
But IMHO this sucks on multiple levels. :)
If you want a method to return something, make it return it. If you need to return multiple objects, create a container class to put these objects into and return that.
I disagree with Jasper: "In my opinion, this is a really ugly and bad way to return more than one result".
In .NET there is a interesting construct that utilize the output parameters:
bool IDictionary.TryGet(key, out value);
I find it very usefull and elegant. And it is the most convenient way to aks if an item is in collection and return it at the same time. With it you may write:
object obj;
if (myList.TryGet(theKey, out obj))
{
... work with the obj;
}
I constantly scold my developers if I see old-style code like:
if (myList.Contains(theKey))
{
obj = myList.Get(theKey);
}
You see, it cuts the performance in half. In Java there is no way to differentiate null value of an existing item from non-existance of an item in a Map in one call. Sometimes this is necessary.
This functionality has one big disadvantage - it doesn't work. Function parameters are local to function and assigning to them doesn't have any impact outside the function.
On the other hand
void getString(StringBuilder builder) {
builder.delete(0, builder.length());
builder.append("hello world");
}
will work, but I see no advantages of doing this (except when you need to return more than one value).
Sometimes this mechanism can avoid creation of a new object.
Example:
If an appropriate object exists anyhow, it is faster to pass it to the method and get some field changed.
This is more efficient than creating a new object inside the called method, and returning and assigning its reference (producing garbage that needs to be collected sometime).
String are immutable, you cannot use Java's pseudo output parameters with immutable objects.
Also, the scope of output is limited to the getString method. If you change the output variable, the caller won't see a thing.
What you can do, however, is change the state of the parameter. Consider the following example:
void handle(Request r) {
doStuff(r.getContent());
r.changeState("foobar");
r.setHandled();
}
If you have a manager calling multiple handles with a single Request, you can change the state of the Request to allow further processing (by other handlers) on a modified content. The manager could also decide to stop processing.
Advantages:
You don't need to return a special object containing the new content and whether the processing should stop. That object would only be used once and creating the object waste memory and processing power.
You don't have to create another Request object and let the garbage collector get rid of the now obsolete old reference.
In some cases, you can't create a new object. For example, because that object was created using a factory, and you don't have access to it, or because the object had listeners and you don't know how to tell the objects that were listening to the old Request that they should instead listen to the new Request.
Actually, it is impossible to have out parameters in java but you can make a work around making the method take on a de-reference for the immutable String and primitives by either writing a generic class where the immutable is the generic with the value and setter and getter or by using an array where element 0 (1 in length) is the value provided it is instantiate first because there are situations where you need to return more than one value where having to write a class just to return them where the class is only used there is just a waste of text and not really re-usable.
Now being a C/C++ and also .Net (mono or MS), it urges me that java does not support at least a de-reference for primitives; so, I resort to the array instead.
Here is an example. Let's say you need to create a function (method) to check whether the index is valid in the array but you also want to return the remainding length after the index is validated. Let's call it in c as 'bool validate_index(int index, int arr_len, int&rem)'. A way to do this in java would be 'Boolean validate_index(int index, int arr_len, int[] rem1)'. rem1 just means the array hold 1 element.
public static Boolean validate_index(int index, int arr_len, int[] rem1)
{
if (index < 0 || arr_len <= 0) return false;
Boolean retVal = (index >= 0 && index < arr_len);
if (retVal && rem1 != null) rem1[0] = (arr_len - (index + 1));
return retVal;
}
Now if we use this we can get both the Boolean return and the remainder.
public static void main(String[] args)
{
int[] ints = int[]{1, 2, 3, 4, 5, 6};
int[] aRem = int[]{-1};
//because we can only scapegoat the de-ref we need to instantiate it first.
Boolean result = validate_index(3, ints.length, aRem);
System.out.println("Validation = " + result.toString());
System.out.println("Remainding elements equals " + aRem[0].toString());
}
puts: Validation = True
puts: Remainding elements equals 2
Array elements always either point to the object on the stack or the address of the object on the heap. So using it as a de-references is absolutely possible even for arrays by making it a double array instantiating it as myArrayPointer = new Class[1][] then passing it in because sometimes you don't know what the length of the array will until the call going through an algorithm like 'Boolean tryToGetArray(SomeObject o, T[][] ppArray)' which would be the same as in c/c++ as 'template bool tryToGetArray (SomeObject* p, T** ppArray)' or C# 'bool tryToGetArray(SomeObject o, ref T[] array)'.
It works and it works well as long as the [][] or [] is instantiate in memory first with at least one element.
in my opinion, this is useful when you have more than one result in a function.

Categories

Resources