Class.asSubclass浅谈

部署运行你感兴趣的模型镜像
  1. public <U> Class<? extends U> asSubclass(Class<U> clazz)  

这是java.lang.Class中的一个方法,作用是将调用这个方法的class对象转换成由clazz参数所表示的class对象的某个子类。举例来说,

  1. List<String> strList = new ArrayList<String>();  
  2. Class<? extends List> strList_cast = strList.getClass().asSubclass(List.class);  

 

上面的代码将strList.getClass()获取的class对象转换成Class<? extends List>,这么做似乎没有什么意义,因为我们很清楚strList.getClass()获取的class对象就是ArrayList,它当然是List.class的一个子类;


但有些情况下,我们并不能确知一个class对象的类型,典型的情况是Class.forName()获取的class对象:

Class.forName()的返回类型是Class<?>,但这显然太宽泛了,假设我们需要List.class类型的class对象,但我们传递给Class.forName的参数是未知的(可能是"java.lang.String",也可能是"java.util.ArrayList"),这时我们就可以用到asSubclass()这个方法了,如下:

  1. Class.forName("xxx.xxx.xxx").asSubclass(List.class).newInstance();  


 当xxx.xxx.xxx是List的子类时,正常执行,当不是List的子类时,抛出ClassCastException,这时我们可以做些别的处理;如果我们查看Class.asSubclass()在JDK中的中的引用的话,会发现这种用法有很多。

这里有必要说下 instanceof 关键字,它的用法用于判断一个Object是否是某个超类或者接口的一个子类或者实现类(不一定是直接超类或者直接接口),如下:

  1. interface IFace {  
  2.       
  3. }  
  4.   
  5. class IFaceImpl implements IFace {  
  6.       
  7. }  
  8.   
  9. class IFaceImplExt extends IFaceImpl {  
  10.       
  11. }  
  12.   
  13. System.out.println(new IFaceImpl() instanceof IFace); // true  
  14. System.out.println(new IFaceImplExt() instanceof IFace); // true  



asSubclass用于窄化未知的Class类型的范围,而instanceof用于判断一个对象引用是否是一个超类或者接口的子类/实现类,如果试图将instanceof用于Class类型的判断会引起编译错误。

  1. // both will cause compliration error  
  2. System.out.println(IFaceImpl.class instanceof IFace);  
  3. System.out.println(IFaceImplExt.class instanceof IFace.class);  

 

转载:http://jasonhan-sh-hotmail-com.iteye.com/blog/1838413

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

package main.core; import main.lang.Nullable; import main.util.Assert; import main.util.LinkedMultiValueMap; import main.util.MultiValueMap; import main.util.ReflectionUtils; import java.util.*; public final class CollectionFactory { private static final Set<Class<?>> approximableCollectionTypes = Set.of( // Standard collection interfaces Collection.class, List.class, Set.class, SortedSet.class, NavigableSet.class, // Common concrete collection classes ArrayList.class, LinkedList.class, HashSet.class, LinkedHashSet.class, TreeSet.class, EnumSet.class); private static final Set<Class<?>> approximableMapTypes = Set.of( // Standard map interfaces Map.class, MultiValueMap.class, SortedMap.class, NavigableMap.class, // Common concrete map classes HashMap.class, LinkedHashMap.class, LinkedMultiValueMap.class, TreeMap.class, EnumMap.class); private CollectionFactory() { } /** * Determine whether the given collection type is an approximable type, * i.e. a type that {@link #createApproximateCollection} can approximate. * @param collectionType the collection type to check * @return {@code true} if the type is approximable */ public static boolean isApproximableCollectionType(@Nullable Class<?> collectionType) { return (collectionType != null && approximableCollectionTypes.contains(collectionType)); } /** * Create the most approximate collection for the given collection. * <p><strong>Warning</strong>: Since the parameterized type {@code E} is * not bound to the type of elements contained in the supplied * {@code collection}, type safety cannot be guaranteed if the supplied * {@code collection} is an {@link EnumSet}. In such scenarios, the caller * is responsible for ensuring that the element type for the supplied * {@code collection} is an enum type matching type {@code E}. As an * alternative, the caller may wish to treat the return value as a raw * collection or collection of {@link Object}. * @param collection the original collection object, potentially {@code null} * @param capacity the initial capacity * @return a new, empty collection instance * @see #isApproximableCollectionType * @see java.util.LinkedList * @see java.util.ArrayList * @see java.util.EnumSet * @see java.util.TreeSet * @see java.util.LinkedHashSet */ @SuppressWarnings({"rawtypes", "unchecked"}) public static <E> Collection<E> createApproximateCollection(@Nullable Object collection, int capacity) { if (collection instanceof EnumSet enumSet) { Collection<E> copy = EnumSet.copyOf(enumSet); copy.clear(); return copy; } else if (collection instanceof SortedSet sortedSet) { return new TreeSet<>(sortedSet.comparator()); } else if (collection instanceof LinkedList) { return new LinkedList<>(); } else if (collection instanceof List) { return new ArrayList<>(capacity); } else { return new LinkedHashSet<>(capacity); } } /** * Create the most appropriate collection for the given collection type. * <p>Delegates to {@link #createCollection(Class, Class, int)} with a * {@code null} element type. * @param collectionType the desired type of the target collection (never {@code null}) * @param capacity the initial capacity * @return a new collection instance * @throws IllegalArgumentException if the supplied {@code collectionType} * is {@code null} or of type {@link EnumSet} */ public static <E> Collection<E> createCollection(Class<?> collectionType, int capacity) { return createCollection(collectionType, null, capacity); } /** * Create the most appropriate collection for the given collection type. * <p><strong>Warning</strong>: Since the parameterized type {@code E} is * not bound to the supplied {@code elementType}, type safety cannot be * guaranteed if the desired {@code collectionType} is {@link EnumSet}. * In such scenarios, the caller is responsible for ensuring that the * supplied {@code elementType} is an enum type matching type {@code E}. * As an alternative, the caller may wish to treat the return value as a * raw collection or collection of {@link Object}. * @param collectionType the desired type of the target collection (never {@code null}) * @param elementType the collection's element type, or {@code null} if unknown * (note: only relevant for {@link EnumSet} creation) * @param capacity the initial capacity * @return a new collection instance * @throws IllegalArgumentException if the supplied {@code collectionType} is * {@code null}; or if the desired {@code collectionType} is {@link EnumSet} and * the supplied {@code elementType} is not a subtype of {@link Enum} * @since 4.1.3 * @see java.util.LinkedHashSet * @see java.util.ArrayList * @see java.util.TreeSet * @see java.util.EnumSet */ @SuppressWarnings("unchecked") public static <E> Collection<E> createCollection(Class<?> collectionType, @Nullable Class<?> elementType, int capacity) { Assert.notNull(collectionType, "Collection type must not be null"); if (LinkedHashSet.class == collectionType || Set.class == collectionType || Collection.class == collectionType) { return new LinkedHashSet<>(capacity); } else if (ArrayList.class == collectionType || List.class == collectionType) { return new ArrayList<>(capacity); } else if (LinkedList.class == collectionType) { return new LinkedList<>(); } else if (TreeSet.class == collectionType || NavigableSet.class == collectionType || SortedSet.class == collectionType) { return new TreeSet<>(); } else if (EnumSet.class.isAssignableFrom(collectionType)) { Assert.notNull(elementType, "Cannot create EnumSet for unknown element type"); return EnumSet.noneOf(asEnumType(elementType)); } else if (HashSet.class == collectionType) { return new HashSet<>(capacity); } else { if (collectionType.isInterface() || !Collection.class.isAssignableFrom(collectionType)) { throw new IllegalArgumentException("Unsupported Collection type: " + collectionType.getName()); } try { return (Collection<E>) ReflectionUtils.accessibleConstructor(collectionType).newInstance(); } catch (Throwable ex) { throw new IllegalArgumentException( "Could not instantiate Collection type: " + collectionType.getName(), ex); } } } /** * Determine whether the given map type is an approximable type, * i.e. a type that {@link #createApproximateMap} can approximate. * @param mapType the map type to check * @return {@code true} if the type is approximable */ public static boolean isApproximableMapType(@Nullable Class<?> mapType) { return (mapType != null && approximableMapTypes.contains(mapType)); } /** * Create the most approximate map for the given map. * <p><strong>Warning</strong>: Since the parameterized type {@code K} is * not bound to the type of keys contained in the supplied {@code map}, * type safety cannot be guaranteed if the supplied {@code map} is an * {@link EnumMap}. In such scenarios, the caller is responsible for * ensuring that the key type in the supplied {@code map} is an enum type * matching type {@code K}. As an alternative, the caller may wish to * treat the return value as a raw map or map keyed by {@link Object}. * @param map the original map object, potentially {@code null} * @param capacity the initial capacity * @return a new, empty map instance * @see #isApproximableMapType * @see java.util.EnumMap * @see java.util.TreeMap * @see java.util.LinkedHashMap */ @SuppressWarnings({"rawtypes", "unchecked"}) public static <K, V> Map<K, V> createApproximateMap(@Nullable Object map, int capacity) { if (map instanceof EnumMap enumMap) { EnumMap copy = new EnumMap(enumMap); copy.clear(); return copy; } else if (map instanceof SortedMap sortedMap) { return new TreeMap<>(sortedMap.comparator()); } else if (map instanceof MultiValueMap) { return new LinkedMultiValueMap(capacity); } else { return new LinkedHashMap<>(capacity); } } /** * Create the most appropriate map for the given map type. * <p>Delegates to {@link #createMap(Class, Class, int)} with a * {@code null} key type. * @param mapType the desired type of the target map * @param capacity the initial capacity * @return a new map instance * @throws IllegalArgumentException if the supplied {@code mapType} is * {@code null} or of type {@link EnumMap} */ public static <K, V> Map<K, V> createMap(Class<?> mapType, int capacity) { return createMap(mapType, null, capacity); } /** * Create the most appropriate map for the given map type. * <p><strong>Warning</strong>: Since the parameterized type {@code K} * is not bound to the supplied {@code keyType}, type safety cannot be * guaranteed if the desired {@code mapType} is {@link EnumMap}. In such * scenarios, the caller is responsible for ensuring that the {@code keyType} * is an enum type matching type {@code K}. As an alternative, the caller * may wish to treat the return value as a raw map or map keyed by * {@link Object}. Similarly, type safety cannot be enforced if the * desired {@code mapType} is {@link MultiValueMap}. * @param mapType the desired type of the target map (never {@code null}) * @param keyType the map's key type, or {@code null} if unknown * (note: only relevant for {@link EnumMap} creation) * @param capacity the initial capacity * @return a new map instance * @throws IllegalArgumentException if the supplied {@code mapType} is * {@code null}; or if the desired {@code mapType} is {@link EnumMap} and * the supplied {@code keyType} is not a subtype of {@link Enum} * @since 4.1.3 * @see java.util.LinkedHashMap * @see java.util.TreeMap * @see org.springframework.util.LinkedMultiValueMap * @see java.util.EnumMap */ @SuppressWarnings({"rawtypes", "unchecked"}) public static <K, V> Map<K, V> createMap(Class<?> mapType, @Nullable Class<?> keyType, int capacity) { Assert.notNull(mapType, "Map type must not be null"); if (LinkedHashMap.class == mapType || Map.class == mapType) { return new LinkedHashMap<>(capacity); } else if (LinkedMultiValueMap.class == mapType || MultiValueMap.class == mapType) { return new LinkedMultiValueMap(); } else if (TreeMap.class == mapType || SortedMap.class == mapType || NavigableMap.class == mapType) { return new TreeMap<>(); } else if (EnumMap.class == mapType) { Assert.notNull(keyType, "Cannot create EnumMap for unknown key type"); return new EnumMap(asEnumType(keyType)); } else if (HashMap.class == mapType) { return new HashMap<>(capacity); } else { if (mapType.isInterface() || !Map.class.isAssignableFrom(mapType)) { throw new IllegalArgumentException("Unsupported Map type: " + mapType.getName()); } try { return (Map<K, V>) ReflectionUtils.accessibleConstructor(mapType).newInstance(); } catch (Throwable ex) { throw new IllegalArgumentException("Could not instantiate Map type: " + mapType.getName(), ex); } } } /** * Create a variant of {@link java.util.Properties} that automatically adapts * non-String values to String representations in {@link Properties#getProperty}. * <p>In addition, the returned {@code Properties} instance sorts properties * alphanumerically based on their keys. * @return a new {@code Properties} instance * @since 4.3.4 * @see #createSortedProperties(boolean) * @see #createSortedProperties(Properties, boolean) */ @SuppressWarnings("serial") public static Properties createStringAdaptingProperties() { return new SortedProperties(false) { @Override @Nullable public String getProperty(String key) { Object value = get(key); return (value != null ? value.toString() : null); } }; } /** * Create a variant of {@link java.util.Properties} that sorts properties * alphanumerically based on their keys. * <p>This can be useful when storing the {@link Properties} instance in a * properties file, since it allows such files to be generated in a repeatable * manner with consistent ordering of properties. Comments in generated * properties files can also be optionally omitted. * @param omitComments {@code true} if comments should be omitted when * storing properties in a file * @return a new {@code Properties} instance * @since 5.2 * @see #createStringAdaptingProperties() * @see #createSortedProperties(Properties, boolean) */ public static Properties createSortedProperties(boolean omitComments) { return new SortedProperties(omitComments); } /** * Create a variant of {@link java.util.Properties} that sorts properties * alphanumerically based on their keys. * <p>This can be useful when storing the {@code Properties} instance in a * properties file, since it allows such files to be generated in a repeatable * manner with consistent ordering of properties. Comments in generated * properties files can also be optionally omitted. * <p>The returned {@code Properties} instance will be populated with * properties from the supplied {@code properties} object, but default * properties from the supplied {@code properties} object will not be copied. * @param properties the {@code Properties} object from which to copy the * initial properties * @param omitComments {@code true} if comments should be omitted when * storing properties in a file * @return a new {@code Properties} instance * @since 5.2 * @see #createStringAdaptingProperties() * @see #createSortedProperties(boolean) */ public static Properties createSortedProperties(Properties properties, boolean omitComments) { return new SortedProperties(properties, omitComments); } /** * Cast the given type to a subtype of {@link Enum}. * @param enumType the enum type, never {@code null} * @return the given type as subtype of {@link Enum} * @throws IllegalArgumentException if the given type is not a subtype of {@link Enum} */ @SuppressWarnings("rawtypes") private static Class<? extends Enum> asEnumType(Class<?> enumType) { Assert.notNull(enumType, "Enum type must not be null"); if (!Enum.class.isAssignableFrom(enumType)) { throw new IllegalArgumentException("Supplied type is not an enum: " + enumType.getName()); } return enumType.asSubclass(Enum.class); } } 翻译成中文进行解释
最新发布
11-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值