java获取子类 转

 

获取子类

package com.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ClassLoaderUtil {
	  
	    public synchronized static void loadClassesFromPath(String specPath) {  
	        if (!isLoad) {  
	            try {
	                URL resource = ClassLoaderUtil.class.getResource(specPath);  
	                URI uri = resource.toURI(); 
	                if(String.valueOf(uri).indexOf("jar!")>0){
	                	resource = ClassLoaderUtil.class.getProtectionDomain().getCodeSource().getLocation();
	                	uri = resource.toURI();
	                }
	                String property = new File(uri).getPath();
	                String[] paths = property.split(";");  
	                for (String path : paths) {  
	                    File file = new File(path);  
	                    if (file.isFile() && path.endsWith(".jar")) {  
	                        listClassesInZip(file,specPath);  
	                    } else if (file.isDirectory()) {  
	                        listClassesInDirectory(path.substring(0,path.length()-specPath.length()) + File.separatorChar, file);  
	                    }  
	                }  
	            } catch (URISyntaxException e) {  
//	                JOptionPane.showMessageDialog(null, ExceptionUtil.getExceptionMessage(e));  
	            }  
	        }  
	    }  
	  
	    private synchronized static void listClassesInDirectory(String rootPath, File file) {  
	        File[] subFiles = file.listFiles();  
	        for (File subFile : subFiles) {  
	            if (subFile.canRead()) {  
	                if (subFile.isFile()) {  
	                    String path = subFile.getPath();  
	                    if (path.endsWith(".class")) {  
	                        try {  
	                            String className = getClassName(path.substring(rootPath.length()));  
	                            CLASSES.add(Class.forName(className));  
	                        } catch (Throwable e) {  
	                        }  
	                    } else if (path.endsWith(".jar")) {  
	                        listClassesInZip(subFile,"/");  
	                    }  
	                } else if (subFile.isDirectory()) {  
	                    listClassesInDirectory(rootPath, subFile);  
	                }  
	            }  
	        }  
	    }  
	  
	    private synchronized static void listClassesInZip(File jarFile,String specPath) {  
	        ZipInputStream in = null;  
	        try {  
	            in = new ZipInputStream(new FileInputStream(jarFile));  
	            ZipEntry ze = null;  
	            while ((ze = in.getNextEntry()) != null) {  
	                if (ze.isDirectory()) {  
	                    continue;  
	                } else {  
	                    try {  
	                        String name = ze.getName();  
	                        if (!name.endsWith(".class"))  
	                            continue;  
	                        if(specPath.substring(1).length()>0 && name.indexOf(specPath.substring(1))<0)
	                        	continue;
	                        String className = getClassName(name);
	                        CLASSES.add(Class.forName(className));  
	                    } catch (Throwable e) {  
	                    }  
	                }  
	            }  
	        } catch (Throwable e) {  
	        } finally {  
	            if (in != null) {  
	                try {  
	                    in.close();  
	                } catch (IOException e) {  
	                }  
	            }  
	        }  
	    }  
	  
	    private static String getClassName(String path) {  
	        return path.replace('/', '.').replace('\\', '.').replaceAll(".class", "");  
	    }  
	  
	    public static List<Class<?>> getSubClasses(Class<?> clazz) {  
	        List<Class<?>> subClasses = SUB_CLASSES_MAP.get(clazz);  
	        if (subClasses == null) {  
	            subClasses = new ArrayList<Class<?>>(10);  
	            for (Class<?> tmpClass : CLASSES) {  
	                if (clazz.isAssignableFrom(tmpClass) && !tmpClass.isAssignableFrom(clazz)) {  
	                    subClasses.add(tmpClass);  
	                }  
	            }  
	            SUB_CLASSES_MAP.put(clazz, subClasses);  
	        }  
	        return Collections.unmodifiableList(subClasses);  
	    }  
	  
	    public static final List<Class<?>> CLASSES = new ArrayList<Class<?>>(200);  
	  
	    private static final Map<Class<?>, List<Class<?>>> SUB_CLASSES_MAP = new HashMap<Class<?>, List<Class<?>>>();  
	  
	    private static boolean isLoad;  
	  
	    
	}  

 

### Java中父类和子类之间的类型换 #### 1. 父类强制换为子类的概念 在Java中,父类可以被看作是一种通用的类型,而子类则具有更具体的特性。当需要将一个父类对象视为其具体实现的子类时,则需要用到**强制类型换**。这种换的本质是从一种较宽泛的类型(父类)化为更加特定的类型(子类),但由于子类可能拥有更多的属性或方法,因此该操作需显式声明并满足一定条件。 如果尝试将任意父类实例直接换成某个不匹配的子类,程序会抛出`ClassCastException`异常[^1]。 #### 2. 强制类型换的前提条件 只有当实际创建的对象确实是目标子类的一个实例时,才能成功完成从父类到子类型。换句话说,假设存在如下定义: ```java class Animal {} class Dog extends Animal {} Animal a = new Dog(); Dog d = (Dog)a; // 正确,因为a实际上指向的是Dog类型的对象 ``` 但如果试图执行下面这样的语句就会失败: ```java Animal b = new Cat(); Dog e = (Dog)b; // 运行期错误:Cat无法换为Dog ``` 这是因为虽然语法允许编译器接受这段代码,但在运行时刻发现b并不属于Dog或者它的任何派生类别之一[^1]。 #### 3. 使用instanceof关键字验证安全性 为了避免潜在的风险,在实施向下造型之前通常建议先利用`instanceof`运算符来确认待化实体确实兼容于预期的目标类型。例如: ```java if(a instanceof Dog){ Dog dogA = (Dog)a; } else{ System.out.println("Cannot cast to Dog"); } ``` 这样不仅可以防止不必要的崩溃还能提高应用程序健壮性[^3]。 #### 4. 子类向父类自动提升(向上造型) 值得注意的是,不同于由祖先回溯至后代所需的手动干预措施,反之情况下的调整往往无需额外努力即可达成——即所谓的"隐含升格".这意味着只要某项资源继承自另一方就足以让后者接纳前者作为成员加入其中. 举例说明: ```java public class Parent { } public class Child extends Parent { } Child childInstance=new Child(); Parent parentReference=childInstance;//No explicit casting needed here. ``` 此处展示了一个简单的例子,展示了如何不需要特别处理就能使子类成为父类的一部分[^4]。 ### 示例代码 以下是综合以上知识点的一段示范代码片段: ```java // 定义父类Person class Person { String name; public void speak() { System.out.println("I am a person."); } } // 定义子类Student 继承自Person class Student extends Person { int grade; @Override public void speak() { super.speak(); System.out.println("And I'm studying in Grade "+grade+"."); } public static void main(String[] args) { // 创建student对象并通过person引用访问 Person pRef = new Student(); // 尝试调用speak(),由于多态行为,实际上是调用了Student版本的方法 pRef.speak();// 输出"I am a person." 和"And I'm studying..." // 如果想明确获取student特有的字段比如年级数,则需要进行强 if(pRef instanceof Student){ ((Student)pRef).grade=7; System.out.println(((Student)pRef).grade); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值