জাভাতে টিক চিহ্ন হিসাবে কিছু আছে কি?


119

আমি টীকাগুলি অন্বেষণ করছি এবং এমন একটি জায়গায় এসে পৌঁছেছি যেখানে কিছু টীকাগুলির মধ্যে তাদের মধ্যে একটি শ্রেণিবিন্যাস রয়েছে বলে মনে হচ্ছে।

আমি কার্ডগুলির জন্য পটভূমিতে কোড উত্পন্ন করতে টীকাগুলি ব্যবহার করছি। কার্ডের বিভিন্ন প্রকার রয়েছে (এইভাবে আলাদা কোড এবং টীকাগুলি) তবে এমন কিছু উপাদান রয়েছে যা তাদের মধ্যে একটি নামের মতো সাধারণ।

@Target(value = {ElementType.TYPE})
public @interface Move extends Page{
 String method1();
 String method2();
}

এবং এটি হবে সাধারণ টিকা:

@Target(value = {ElementType.TYPE})
public @interface Page{
 String method3();
}

উপরের উদাহরণে আমি পদ্ধতি 3 উত্তরাধিকার সূত্রে স্থানান্তরিত হওয়ার প্রত্যাশা করব তবে আমি একটি সতর্কতা পেয়েছি যা বর্ধনের সাথে টীকাগুলির সাথে বৈধ নয়। আমি চেষ্টা করছিলাম একটি টীকাগুলি একটি সাধারণ বেসকে বাড়িয়ে দেয় তবে এটি কার্যকর হয় না। এটি কি সম্ভব বা কেবল একটি ডিজাইনের সমস্যা?


3
টীকাগুলির উপর ভিত্তি করে ডিএসএল তৈরি করার জন্য টীকা নোটের উত্তরাধিকার অবশ্যই মনে হয় seems এমন করুণা যে টীকা উত্তরাধিকার সমর্থন করা হয় না।
Ceci

2
আমি সম্মত, করণীয় স্বাভাবিক জিনিস বলে মনে হচ্ছে। বিশেষত জাভাতে উত্তরাধিকার বোঝার পরে, আপনি সমস্ত ধরণের ক্ষেত্রে এটি প্রয়োগ করার আশা করছেন kind
javydreamercsw

উত্তর:


76

দুর্ভাগ্যক্রমে না. স্পষ্টতই এর সাথে এমন কিছু প্রোগ্রাম রয়েছে যা কোনও ক্লাসে টীকাগুলি পুরোপুরি লোড না করে পড়ে read দেখুন জাভাতে টীকাগুলি বাড়ানো কেন সম্ভব নয়?

যাইহোক, প্রকারগুলি তাদের সুপারক্লাসের টীকাগুলি উত্তরাধিকার সূত্রে প্রাপ্ত হয় যদি সেই টিকাগুলি থাকে @Inherited

এছাড়াও, ইন্টারঅ্যাক্ট করার জন্য আপনার যদি এই পদ্ধতিগুলির প্রয়োজন না হয় তবে আপনি কেবল আপনার ক্লাসে টীকাগুলি স্ট্যাক করতে পারেন:

@Move
@Page
public class myAwesomeClass {}

এমন কোনও কারণ আছে যা আপনার পক্ষে কাজ করবে না?


1
এটাই আমি ভেবেছিলাম তবে আমি জিনিসগুলি সরল করার চেষ্টা করছি। কোনও
সাধারণটিকে

1
হ্যাঁ, খুব চতুর লাগছিল। শুভকামনা!
অ্যান্ড্রোনিকাস

67

আপনি উত্তরাধিকারের পরিবর্তে বেস টীকা দিয়ে আপনার টিকাটি টিকিয়ে দিতে পারেন। এটি স্প্রিং ফ্রেমওয়ার্কে ব্যবহৃত হয়

একটি উদাহরণ দিতে

@Target(value = {ElementType.ANNOTATION_TYPE})
public @interface Vehicle {
}

@Target(value = {ElementType.TYPE})
@Vehicle
public @interface Car {
}

@Car
class Foo {
}

তারপরে আপনি পরীক্ষা করতে পারেন যে কোনও ক্লাসটি স্প্রিংয়ের টীকাগুলিVehicle ব্যবহার করে টিকা দেওয়া হয়েছে :

Vehicle vehicleAnnotation = AnnotationUtils.findAnnotation (Foo.class, Vehicle.class);
boolean isAnnotated = vehicleAnnotation != null;

এই পদ্ধতিটি হিসাবে প্রয়োগ করা হয়:

public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType) {
    return findAnnotation(clazz, annotationType, new HashSet<Annotation>());
}

@SuppressWarnings("unchecked")
private static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType, Set<Annotation> visited) {
    try {
        Annotation[] anns = clazz.getDeclaredAnnotations();
        for (Annotation ann : anns) {
            if (ann.annotationType() == annotationType) {
                return (A) ann;
            }
        }
        for (Annotation ann : anns) {
            if (!isInJavaLangAnnotationPackage(ann) && visited.add(ann)) {
                A annotation = findAnnotation(ann.annotationType(), annotationType, visited);
                if (annotation != null) {
                    return annotation;
                }
            }
        }
    }
    catch (Exception ex) {
        handleIntrospectionFailure(clazz, ex);
        return null;
    }

    for (Class<?> ifc : clazz.getInterfaces()) {
        A annotation = findAnnotation(ifc, annotationType, visited);
        if (annotation != null) {
            return annotation;
        }
    }

    Class<?> superclass = clazz.getSuperclass();
    if (superclass == null || Object.class == superclass) {
        return null;
    }
    return findAnnotation(superclass, annotationType, visited);
}

AnnotationUtilsএছাড়াও পদ্ধতিতে এবং অন্যান্য টীকাযুক্ত উপাদানগুলিতে টীকা অনুসন্ধানের জন্য অতিরিক্ত পদ্ধতি রয়েছে। ব্রিজড ক্লাসটি ব্রিজযুক্ত পদ্ধতি, প্রক্সি এবং অন্যান্য কোণার ক্ষেত্রগুলি বিশেষত বসন্তের মুখোমুখি হয়ে অনুসন্ধান করার জন্য যথেষ্ট শক্তিশালী।


13
দয়া করে এ জাতীয় টীকা কীভাবে প্রসেস করবেন তার একটি ব্যাখ্যা অন্তর্ভুক্ত করুন।
আলেকসান্দ্র ডাবিনস্কি

1
আপনি স্প্রিংয়ের টীকাগুলি.ফাইন্ডঅনোটেশন (..) ব্যবহার করতে পারেন, দেখুন: ডকস.স্প্রিং.ইও
স্প্রিং

2
যখন টীকাগুলি A অন্য একটি টীকা বি দিয়ে টীকায়িত করা হয়, এবং আমরা A এর সাথে ক্লাস সি টিকা দিয়ে থাকি তখন শ্রেণি সিটিকে এমনভাবে বিবেচনা করা হয় যা এটি A এবং B উভয় দিয়েই টীকাযুক্ত করা হয় - এটি স্প্রিং ফ্রেমওয়ার্কের নির্দিষ্ট আচরণ - AnnotationUtils.findAnnotation যাদু করে এখানে এবং একটি টীকাটির টীকাগুলি সন্ধান করতে ব্যবহার করতে ব্যবহৃত হয়। সুতরাং ভুল বোঝবেন না যে এটি টীকা হ্যান্ডলিং সম্পর্কিত জাভার ডিফল্ট আচরণ।
কুর্তাল

এটি কেবল তখনই সম্ভব যখন আপনি রচনাগুলি রচনা করতে চান এমন এনটোটেশনগুলির লক্ষ্য TYPEবা থাকে ANNOTATION_TYPE
অরেঞ্জডগ

7

টীকা টিকা দেওয়ার জন্য গ্রিগরিয়াসের উত্তর ছাড়াও।

আপনি এই লুপটি দ্বারা কোনও @Qualifierটীকাগুলি (বা এর সাথে টীকাযুক্ত @Qualifier) রাখার জন্য উদাহরণগুলি পরীক্ষা করতে পারেন :

for (Annotation a : method.getAnnotations()) {
    if (a.annotationType().isAnnotationPresent(Qualifier.class)) {
        System.out.println("found @Qualifier annotation");//found annotation having Qualifier annotation itself
    }
}

আপনি মূলত যা করছেন তা হ'ল পদ্ধতিতে এবং যে টীকাগুলি আপনি তাদের ধরণের পেয়েছেন সেগুলিতে সমস্ত টীকাগুলি পাওয়া এবং সেগুলিকে @ কোয়ালিফায়ার দিয়ে টিকা দেওয়া আছে কিনা সেগুলি পরীক্ষা করুন check আপনার টীকাটি লক্ষ্য হওয়া দরকার thisএটি কাজ করার জন্য টীকাগুলি_ও টাইপ সক্ষম করা হবে।


গ্রেগরির উত্তর থেকে এটি কীভাবে আলাদা?
আলেকসান্দ্র ডাবিনস্কি

@ আলেকসান্ডারডুবিনস্কি: স্প্রিং ব্যবহার না করে এটি কেবল একটি সহজ বাস্তবায়ন। এটি পুনরাবৃত্তভাবে টীকায়িত টীকাযুক্ত টীকাগুলি খুঁজে পায় না, তবে আমার ধারণা এটি সাধারণত প্রয়োজন হয় না। আমি এই সমাধানটির সরলতা পছন্দ করি।
স্টিফান স্টিইনগার

1

পরীক্ষা করে দেখুন https://github.com/blindpirate/annotation-magic , যা একটি গ্রন্থাগার উন্নত যখন আমি একই প্রশ্ন ছিল আমি নেই।

@interface Animal {
    boolean fluffy() default false;

    String name() default "";
}

@Extends(Animal.class)
@Animal(fluffy = true)
@interface Pet {
    String name();
}

@Extends(Pet.class)
@interface Cat {
    @AliasFor("name")
    String value();
}

@Extends(Pet.class)
@interface Dog {
    String name();
}

@interface Rat {
    @AliasFor(target = Animal.class, value = "name")
    String value();
}

@Cat("Tom")
class MyClass {
    @Dog(name = "Spike")
    @Rat("Jerry")
    public void foo() {
    }
}

        Pet petAnnotation = AnnotationMagic.getOneAnnotationOnClassOrNull(MyClass.class, Pet.class);
        assertEquals("Tom", petAnnotation.name());
        assertTrue(AnnotationMagic.instanceOf(petAnnotation, Animal.class));

        Animal animalAnnotation = AnnotationMagic.getOneAnnotationOnClassOrNull(MyClass.class, Animal.class);
        assertTrue(animalAnnotation.fluffy());

        Method fooMethod = MyClass.class.getMethod("foo");
        List<Animal> animalAnnotations = AnnotationMagic.getAnnotationsOnMethod(fooMethod, Animal.class);
        assertEquals(Arrays.asList("Spike", "Jerry"), animalAnnotations.stream().map(Animal::name).collect(toList()));
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.