{"id":19563141,"url":"https://github.com/fasterxml/java-classmate","last_synced_at":"2025-05-14T03:04:43.447Z","repository":{"id":46112526,"uuid":"935336","full_name":"FasterXML/java-classmate","owner":"FasterXML","description":"Library for introspecting generic type information of types, member/static methods, fields. Especially useful for POJO/Bean introspection.","archived":false,"fork":false,"pushed_at":"2025-03-02T03:15:55.000Z","size":957,"stargazers_count":260,"open_issues_count":13,"forks_count":44,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-03T16:32:29.754Z","etag":null,"topics":["hacktoberfest","java-reflection","tidelift"],"latest_commit_sha":null,"homepage":"http://fasterxml.com","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FasterXML.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"tidelift":"maven/com.fasterxml:classmate","github":"cowtowncoder"}},"created_at":"2010-09-24T05:10:56.000Z","updated_at":"2025-03-18T12:41:09.000Z","dependencies_parsed_at":"2024-01-30T02:31:13.976Z","dependency_job_id":"f2aee080-3fb4-4cf2-a8e0-597111e9808c","html_url":"https://github.com/FasterXML/java-classmate","commit_stats":{"total_commits":276,"total_committers":17,"mean_commits":"16.235294117647058","dds":0.3623188405797102,"last_synced_commit":"6508f89a7233f4699f3a69f47b027b287eb25cc1"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FasterXML%2Fjava-classmate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FasterXML%2Fjava-classmate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FasterXML%2Fjava-classmate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FasterXML%2Fjava-classmate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FasterXML","download_url":"https://codeload.github.com/FasterXML/java-classmate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248288036,"owners_count":21078831,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","java-reflection","tidelift"],"created_at":"2024-11-11T05:16:42.734Z","updated_at":"2025-04-10T20:04:59.441Z","avatar_url":"https://github.com/FasterXML.png","language":"Java","funding_links":["https://tidelift.com/funding/github/maven/com.fasterxml:classmate","https://github.com/sponsors/cowtowncoder","https://tidelift.com/badges/package/maven/com.fasterxml:classmate","https://tidelift.com/subscription/pkg/maven-com-fasterxml-classmate?utm_source=maven-com-fasterxml-classmate\u0026utm_medium=referral\u0026utm_campaign=readme","https://tidelift.com/subscription/pkg/maven-com-fasterxml-classmate?utm_source=maven-com-fasterxml-classmate\u0026utm_medium=referral\u0026utm_campaign=enterprise\u0026utm_term=repo","https://tidelift.com/security"],"categories":[],"sub_categories":[],"readme":"## Overview\n\nClassMate is a zero-dependency Java library for accurately introspecting type information, including reliable resolution of generic type declarations for both classes (\"types\") and members (fields, methods and constructors).\n\nProject is licensed under [Apache 2](http://www.apache.org/licenses/LICENSE-2.0.txt).\n\n## Status\n\n| Type | Status |\n| ---- | ------ |\n| Build (CI) |  [![Build (github)](https://github.com/FasterXML/java-classmate/actions/workflows/main.yml/badge.svg)](https://github.com/FasterXML/java-classmate/actions/workflows/main.yml) |\n| Artifact | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.fasterxml/classmate/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.fasterxml/classmate/) |\n| OSS Sponsorship |  [![Tidelift](https://tidelift.com/badges/package/maven/com.fasterxml:classmate)](https://tidelift.com/subscription/pkg/maven-com-fasterxml-classmate?utm_source=maven-com-fasterxml-classmate\u0026utm_medium=referral\u0026utm_campaign=readme) |\n| JavaDocs | [![Javadoc](https://javadoc.io/badge/com.fasterxml/classmate.svg)](http://www.javadoc.io/doc/com.fasterxml/classmate) |\n| Code coverage (master) | [![codecov.io](https://codecov.io/github/FasterXML/java-classmate/coverage.svg?branch=master)](https://codecov.io/github/FasterXML/java-classmate?branch=master) |\n| OpenSSF Score | [![OpenSSF  Scorecard](https://api.securityscorecards.dev/projects/github.com/FasterXML/java-classmate/badge)](https://securityscorecards.dev/viewer/?uri=github.com/FasterXML/java-classmate) |\n\n## Support\n\n### Community support\n\nClassmate is supported by the community via the mailing list: [java-classmate-user](https://groups.google.com/forum/#!forum/java-classmate-users)\n\n### Enterprise support\n\nAvailable as part of the Tidelift Subscription.\n\nThe maintainers of `classmate` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/maven-com-fasterxml-classmate?utm_source=maven-com-fasterxml-classmate\u0026utm_medium=referral\u0026utm_campaign=enterprise\u0026utm_term=repo)\n\n## Contributing\n\nContributions are welcome (of course!); we require a simple one-page CLA to help simplify distribution\n(corporate users want to know how contributions are handled), one per contributor. Feel free to submit\nPull Requests and we will get you through this formality.\n\nOne special case is that for reporting possible security issues (\"vulnerabilities\"), we recommend filing a\n[Tidelift security contact](https://tidelift.com/security) (NOTE: you do NOT have to be a subscriber to do this).\n\n## Documentation\n\n[Project wiki](/../../wiki) has Javadocs.\n\nExternal links that may help include:\n\n* [Resolving Generic Types with Classmate](http://www.cowtowncoder.com/blog/archives/2012/04/entry_471.html) (some simple usage examples)\n* [Problem with java.lang.reflect.Type](http://www.cowtowncoder.com/blog/archives/2010/12/entry_436.html) (explanation of issues ClassMate was written to solve)\n\n-----\n\n## Compatibility\n\n#### JDK baseline\n\nClassMate versions up to 1.6 require Java 6 to run.\n\nClassMate versions 1.7 and above require Java 8 to run\n\n#### JPMS compatibility\n\nClassMate versions 1.5 and above contain `module-info.class` information to work with JPMS.\nModule name to use is `com.fasterxml.classmate`.\n\n## Usage\n\n### Maven dependency\n\nTo use ClassMate via Maven, include following dependency:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.fasterxml\u003c/groupId\u003e\n  \u003cartifactId\u003eclassmate\u003c/artifactId\u003e\n  \u003cversion\u003e1.7.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Non-Maven\n\nDownloads available from [Project wiki](../../wiki).\n\n### Resolving Class type information\n\nMain class used for fully resolving type information for classes is `com.fasterxml.classmate.TypeResolver`.\nTypeResolver does simple caching for resolved supertypes (since many subtypes resolve to smaller set of supertypes, typically). Since all access to shared data is synchronized, a single `TypeResolver` instance is typically shared for a single system (as a plain old static singleton): there are no benefits to instantiating more instances.\n\nIts main resolution methods are:\n\n* `resolve(Class cls)`: given a plain old class, will use generic type information that super type declarations (extends, implements) may have.\n* `resolve(GenericType\u003cT\u003e)`: given a subtype of `GenericType` (which uses [\"Super-type Token\" pattern](http://gafter.blogspot.com/2006/12/super-type-tokens.html)), fully resolve type information\n* `resolve(Class\u003c?\u003e baseType, Class\u003c?\u003e typeParameter1, ... , Class\u003c?\u003e typeParameter2)`: given base type (like `List.class`) and zero or more type parameters (either as `Class` es to resolve, or as `ResolvedType` s), resolves type information\n\nResult in all these cases is an instance of `ResolvedType`, which you can think of as generic type information containing replacement for `java.lang.Class`. It is also the starting point for resolving member (constructor, field, method) information.\n\n### Resolving Type parameters for a class\n\nWhile finding type parameters for specific class is relatively easy (using `getTypeParameters`), what you more commonly need to know is type parameters for a type implemented or extended.\nSpecifically, consider case of:\n\n    public class StringIntMap extends HashMap\u003cString,Integer\u003e { }\n\nwhere you would want to know `key` and `value` types of your Map sub-type.\nThe first step is the same:\n\n    ResolvedType type = typeResolver.resolve(StringIntMap.class);\n\nand to find parameter bindings for `java.util.Map`, you will use:\n\n    List\u003cResolvedType\u003e mapParams = type.typeParametersFor(Map.class);\n    ResolvedType keyType = mapParams.get(0);\n    ResolvedType valueType = mapParams.get(1);\n\nNote: if types were left unspecified (like, say, `public class MyMap\u003cK,V\u003e extends Map\u003cK,V\u003e`), you will always get resolved types based on bounds: in this case, it would be equivalent to parameterization of `Map\u003cObject,Object`).\n\n### Resolving Member information\n\nMember information resolution is done by `com.fasterxml.classmate.MemberResolver`, which takes a `ResolvedType` and produces `ResolvedTypeWithMembers`. As with `TypeResolver`, a single instance is typically shared by all code; but since no reuse of information is done, creating new instances is cheap and need not be avoided.\n\nThere are a few configuration options that can be used to determine things like:\n\n* Whether to include information from `java.lang.Object` (default: ignore and do not include)\n* Which members to filter out before aggregation (default: no filtering, include all members)\n* Which annotations to include in resolved members (default: include nothing)\n* For method annotations included, whether annotations from overridden methods are be inherited by overriding methods.\n* Which annotation overrides (aka \"mix-ins\") to use for which classes (default: no overrides)\n\n`ResolvedTypeWithMembers` has simple accessors for:\n\n* Constructors: only constructors of the resolved type itself included (no constructors of superclasses)\n* Fields: all fields from resolved type and its superclasses are included; expect in cases where fields are masked, in which case masked fields (super-class field with same name as a field on its sub-class) are not included.\n* Static methods: only methods declared by resolved type itself\n* Member methods: all methods from resolved type and its supertypes are included; except for overriding in which case only overriding method is included (which also means that methods from interfaces are typically not included, when implementing class has overriding method intance)\n\nAnnotations of all member types can be overridden by annotation overrides; annotation value defaulting only works for members that use inheritance, meaning just member methods.\n\nMember information is lazily constructed. Access to member information is synchronized such that it is safe to share `ResolvedTypeWithMembers` instances.\n\n## Examples\n\nThe following examples are all backed by an accompanying _junit_ [test](java-classmate/blob/master/src/test/java/com/fasterxml/classmate/TestReadme.java)\n\n### Resolving Classes\n\n##### Resolve `List.class`\n\n```java\nTypeResolver typeResolver = new TypeResolver();\n// listType =\u003e List\u003cObject\u003e\nResolvedType listType = typeResolver.resolve(List.class);\n```\n\n##### Resolve `List\u003cString\u003e.class`\n\n```java\n// listType =\u003e List\u003cString\u003e\nResolvedType listType = typeResolver.resolve(List.class, String.class);\n```\n\n##### Resolve `List\u003cString\u003e.class` (leveraging already ResolvedType object)\n\n```java\nResolvedType stringType = typeResolver.resolve(String.class);\n// listType =\u003e List\u003cString\u003e\nResolvedType listType = typeResolver.resolve(List.class, stringType);\n```\n\n##### Resolve `List\u003cString\u003e.class` using [\"super type token\"](http://gafter.blogspot.com/2006/12/super-type-tokens.html)\n\n```java\n// listType =\u003e List\u003cString\u003e\nResolvedType listType = typeResolver.resolve(new GenericType\u003cList\u003cString\u003e\u003e() {});\n```\n\n### Resolving Members (i.e., Field/Method/Constructor)\n\n#### Resolving All Members\n\n##### Resolve `ArrayList\u003cString\u003e` static/instance Methods\n\n```java\nResolvedType arrayListType = typeResolver.resolve(ArrayList.class, String.class);\nMemberResolver memberResolver = new MemberResolver(typeResolver);\nResolvedTypeWithMembers arrayListTypeWithMembers = memberResolver.resolve(arrayListType, null, null);\n// get static methods\nResolvedMethod[] staticArrayListMethods = arrayListTypeWithMembers.getStaticMethods();\n// get instance methods\nResolvedMethod[] arrayListMethods = arrayListTypeWithMembers.getMemberMethods();\n```\n\n##### Resolve `ArrayList\u003cString\u003e` Fields\n\n```java\nResolvedType arrayListType = typeResolver.resolve(ArrayList.class, String.class);\nMemberResolver memberResolver = new MemberResolver(typeResolver);\nResolvedTypeWithMembers arrayListTypeWithMembers = memberResolver.resolve(arrayListType, null, null);\n// get static/instance fields\nResolvedField[] arrayListFields = arrayListTypeWithMembers.getMemberFields();\n```\n\n##### Resolve `ArrayList\u003cString\u003e` Constructors\n\n```java\nResolvedType arrayListType = typeResolver.resolve(ArrayList.class, String.class);\nMemberResolver memberResolver = new MemberResolver(typeResolver);\nResolvedTypeWithMembers arrayListTypeWithMembers = memberResolver.resolve(arrayListType, null, null);\n// get static/instance fields\nResolvedConstructor[] arrayListConstructors = arrayListTypeWithMembers.getConstructors();\n```\n\n#### Resolving Particular Members (i.e., Filtering)\n\n##### Resolve `ArrayList\u003cString\u003e#size()` Method\n\n```java\nResolvedType arrayListType = typeResolver.resolve(ArrayList.class, String.class);\nMemberResolver memberResolver = new MemberResolver(typeResolver);\nmemberResolver.setMethodFilter(new Filter\u003cRawMethod\u003e() {\n    @Override public boolean include(RawMethod element) {\n        return \"size\".equals(element.getName());\n    }\n});\nResolvedTypeWithMembers arrayListTypeWithMembers = memberResolver.resolve(arrayListType, null, null);\nResolvedMethod sizeMethod = arrayListTypeWithMembers.getMemberMethods()[0];\n```\n\n##### Resolve `ArrayList\u003cString\u003e.size` Field\n\n```java\nResolvedType arrayListType = typeResolver.resolve(ArrayList.class, String.class);\nMemberResolver memberResolver = new MemberResolver(typeResolver);\nmemberResolver.setFieldFilter(new Filter\u003cRawField\u003e() {\n    @Override public boolean include(RawField element) {\n        return \"size\".equals(element.getName());\n    }\n});\nResolvedTypeWithMembers arrayListTypeWithMembers = memberResolver.resolve(arrayListType, null, null);\nResolvedField sizeField = arrayListTypeWithMembers.getMemberFields()[0];\n```\n\n#### Resolving Members and their Annotations\n\nClasses for reference in the examples below:\n```java\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Marker { }\n\n@Retention(RetentionPolicy.RUNTIME)\n@Inherited\npublic @interface MarkerA { }\n\npublic class SomeClass {\n    @Marker @MarkerA\n    public void someMethod() { }\n}\npublic class SomeSubclass extends SomeClass {\n    @Override\n    public void someMethod() { }\n}\n```\n\n##### Resolve `SomeClass#someMethod()`'s Annotations\n\n```java\nResolvedType someType = typeResolver.resolve(SomeClass.class);\nMemberResolver memberResolver = new MemberResolver(typeResolver);\nmemberResolver.setMethodFilter(new Filter\u003cRawMethod\u003e() {\n    @Override public boolean include(RawMethod element) {\n        return \"someMethod\".equals(element.getName());\n    }\n});\nAnnotationConfiguration annConfig = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_BUT_DONT_INHERIT);\nResolvedTypeWithMembers someTypeWithMembers = memberResolver.resolve(someType, annConfig, null);\nResolvedMethod someMethod = someTypeWithMembers.getMemberMethods()[0];\nMarker marker = someMethod.get(Marker.class);  // marker != null\nMarkerA markerA = someMethod.get(MarkerA.class); // markerA != null\n```\n\n##### Resolve `SomeSubclass#someMethod()`'s Annotations\n\n```java\n\n// setup removed for brevity; same as above only using SomeSubclass instead of SomeClass\n\nAnnotationConfiguration annConfig = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_BUT_DONT_INHERIT);\nResolvedTypeWithMembers someSubclassTypeWithMembers = memberResolver.resolve(someSubclassType, annConfig, null);\nResolvedMethod someMethod = someSubclassTypeWithMembers.getMemberMethods()[0];\nMarker marker = someMethod.get(Marker.class);  // marker == null\nMarkerA markerA = someMethod.get(MarkerA.class); // markerA == null\nOverride override = someMethod.get(Override.class); // override == null (RetentionPolicy = SOURCE)\n```\n\n##### Resolve `SomeSubclass#someMethod()`'s Annotations including @Inherited\n\n```java\n\n// setup removed for brevity; same as above\n\nAnnotationConfiguration annConfig = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_AND_INHERIT_IF_INHERITED);\nResolvedTypeWithMembers someSubclassTypeWithMembers = memberResolver.resolve(someSubclassType, annConfig, null);\nResolvedMethod someMethod = someSubclassTypeWithMembers.getMemberMethods()[0];\nMarker marker = someMethod.get(Marker.class);  // marker == null\nMarkerA markerA = someMethod.get(MarkerA.class); // markerA != null\nOverride override = someMethod.get(Override.class); // override == null (RetentionPolicy = SOURCE)\n```\n\n##### Resolve `SomeSubclass#someMethod()`'s Annotations including all super class's Annotations\n\n```java\n\n// setup removed for brevity; same as above\n\nAnnotationConfiguration annConfig = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_AND_INHERIT);\nResolvedTypeWithMembers someSubclassTypeWithMembers = memberResolver.resolve(someSubclassType, annConfig, null);\nResolvedMethod someMethod = someSubclassTypeWithMembers.getMemberMethods()[0];\nMarker marker = someMethod.get(Marker.class);  // marker != null\nMarkerA markerA = someMethod.get(MarkerA.class); // markerA != null\nOverride override = someMethod.get(Override.class); // override == null (RetentionPolicy = SOURCE)\n```\n\n#### Using Annotation \"mix-ins\"\n\nTypes with the same method signature, field definition or constructor signature but which aren't explicitly related to one another (i.e., _extend_ each other or _implement_ the same interface) can have their annotations \"mixed in\" to others' resolved types.  For example, using the `SomeClass` from above, let's add another class definition.\n\n```java\npublic class SomeOtherClass {\n    public void someMethod() { }\n}\n```\n\nThe `someMethod` signature on `SomeOtherClass` is the same as `SomeClass` however `SomeOtherClass` does not extend from `SomeClass`.  Member resolution for `SomeOtherClass`, like we've done above, will (of course) result in no Annotations.\n\n```java\n\n// setup removed for brevity; similar to above but using SomeOtherClass\n\nAnnotationConfiguration annConfig = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_AND_INHERIT);\nResolvedTypeWithMembers someOtherClassTypeWithMembers = memberResolver.resolve(someOtherClassType, annConfig, null);\nResolvedMethod someMethod = someOtherClassTypeWithMembers.getMemberMethods()[0];\nMarker marker = someMethod.get(Marker.class);  // marker == null, of course\nMarkerA markerA = someMethod.get(MarkerA.class); // markerA == null, of course\n```\n\nWe can augment the annotations returned by `SomeOtherClass` with \"mix-ins\"\n\n```java\n// setup removed for brevity; same as above, using SomeOtherClass\n\n// MIX-IN -\u003e take SomeClass and apply to SomeOtherClass\nAnnotationOverrides annOverrides = AnnotationOverrides.builder().add(SomeOtherClass.class, SomeClass.class).build();\n\nResolvedTypeWithMembers someOtherTypeWithMembers = memberResolver.resolve(someOtherType, annConfig, annOverrides);\nResolvedMethod someMethod = someOtherTypeWithMembers.getMemberMethods()[0];\nMarker marker = someMethod.get(Marker.class);  // marker != null\nMarkerA markerA = someMethod.get(MarkerA.class); // markerA != null\n```\n\nNow the `ResolvedMethod` for `SomeOtherClass` also contains the `Marker` and `MarkerA` annotations!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffasterxml%2Fjava-classmate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffasterxml%2Fjava-classmate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffasterxml%2Fjava-classmate/lists"}