添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

InputStream is = getClass().getClassLoader().getResourceAsStream("helloworld.properties");

getClass() :取得当前对象所属的Class对象

getClassLoader() :取得该Class对象的类装载器

类装载器负责从Java字符文件将字符流读入内存,并构造Class类对象,所以通过它可以得到一个文件的输入流。

装载类的过程非常简单:查找类所在位置,并将找到的Java类的字节码装入内存,生成对应的Class对象。

Java的类装载器专门用来实现这样的过程, JVM并不止有一个类装载器 ,事实上,如果你愿意的话,你可以让JVM拥有无数个类装载器,当然这除了测试JVM外,我想不出还有其他的用途。

Class.getClassLoader()的一个小陷阱:
Integer.class.getClassLoader().getResource("*********");
抛出空指针异常,定位为getClassLoader()返回null
*
类装载器自身也是一个类,它也需要被装载到内存中来,* 那么这些类装载器由谁来装载呢?
它就是神龙见首不见尾的Bootstrap ClassLoader. 为什么说它神龙见首不见尾呢,因为你根本无法在Java代码中抓住哪怕是它的一点点的尾巴,尽管你能时时刻刻体会到它的存在,因为 java的运行环境所需要的所有类库,都由它来装载, 而它本身是C++写的程序,可以独立运行, 可以说是JVM的运行起点

在Bootstrap完成它的任务后,会生成一个AppClassLoader(实际上之前系统还会使用扩展类装载器ExtClassLoader,它用于装载Java运行环境扩展包中的类),这个类装载器才是我们经常使用的,可以调用ClassLoader.getSystemClassLoader() 来获得,我们假定程序中没有使用类装载器相关操作设定或者自定义新的类装载器,那么我们编写的所有java类通通会由它来装载,值得尊敬吧。AppClassLoader查找类的区域就是耳熟能详的Classpath,也是初学者必须跨过的门槛,有没有灵光一闪的感觉,我们按照它的类查找范围给它取名为类路径类装载器。还是先前假定的情况,当Java中出现新的类,AppClassLoader首先在类传递给它的父类类装载器,也就是Extion ClassLoader,询问它是否能够装载该类,如果能,那AppClassLoader就不干这活了,同样Extion ClassLoader在装载时,也会先问问它的父类装载器。我们可以看出类装载器实际上是一个树状的结构图,每个类装载器有自己的父亲,类装载器在装载类时,总是先让自己的父类装载器装载(多么尊敬长辈),如果父类装载器无法装载该类时,自己就会动手装载,如果它也装载不了,那么对不起,它会大喊一声:Exception,class not found。有必要提一句,当由直接使用类路径装载器装载类失败抛出的是NoClassDefFoundException异常。如果使用自定义的类装载器loadClass方法或者ClassLoader的findSystemClass方法装载类,如果你不去刻意改变,那么抛出的是ClassNotFoundException。
这里jdk告诉我们:如果一个类是通过bootstrap 载入的,那我们通过这个类去获得classloader的话,有些jdk的实现是会返回一个null的,比如说我用 new Object().getClass().getClassLoader()的话,会返回一个null,这样的话上面的代码就会出现NullPointer异常.所以保险起见最好还是使用\ 自己写的类来获取classloader(”this.getClass().getClassLoader()“),这样一来就不会有问题。

InputStream is = getClass().getClassLoader().getResourceAsStream("helloworld.properties");getClass():取得当前对象所属的Class对象getClassLoader():取得该Class对象的类装载器类装载器负责从Java字符文件将字符流读入内存,并构造Class类对象,所以通过它可以得到一 public static void main(String[] args) { URL url = YamlUtil. class .get ClassLoader ().getResource(""); System.out.println(url); 通过上面的结果,可以看到get ClassLoader ().getResource()定位到项目的target/cla. * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. package org.apache.catalina.startup; import java .io.File; import java .io.IOException; import java .lang.reflect.InvocationTargetException; import java .lang.reflect.Method; import java .net.MalformedURLException; import java .net.URL; import java .util.ArrayList; import java .util.List; import java .util.regex.Matcher; import java .util.regex.Pattern; import org.apache.catalina.Globals; import org.apache.catalina.security.Security Class Load; import org.apache.catalina.startup. ClassLoader Factory.Repository; import org.apache.catalina.startup. ClassLoader Factory.RepositoryType; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; * Bootstrap loader for Catalina. This application constructs a class loader * for use in loading the Catalina internal class es (by accumulating all of the * JAR files found in the "server" directory under "catalina.home"), and * starts the regular execution of the container. The purpose of this * roundabout approach is to keep the Catalina internal class es (and any * other class es they depend on, such as an XML parser) out of the system * class path and therefore not visible to application level class es. * @author Craig R. McClanahan * @author Remy Maucherat public final class Bootstrap { private static final Log log = LogFactory.getLog(Bootstrap. class ); * Daemon object used by main. private static Bootstrap daemon = null; private static final File catalinaBaseFile; private static final File catalinaHomeFile; private static final Pattern PATH_PATTERN = Pattern.compile("(\".*?\")|(([^,])*)"); static { // Will always be non-null //System.getProperty("user.dir"),获取当前目录 //由于是在$CATALINA_HOME\bin下运行的Bootstrap,所以userDir为$CATALINA_HOME\bin String userDir = System.getProperty("user.dir"); // Home first //Globals是存放全局常量的类 //Globals.CATALINA_HOME_PROP = "catalina.home" //catalina.home在运行Bootstrap时已设置(Tomcat的根目录) String home = System.getProperty(Globals.CATALINA_HOME_PROP); File homeFile = null; //获取Tomcat的绝对路径 if (home != null) { File f = new File(home); try { homeFile = f.getCanonicalFile(); } catch (IOException ioe) { homeFile = f.getAbsoluteFile(); if (homeFile == null) { // First fall-back. See if current directory is a bin directory // in a normal Tomcat install File bootstrapJar = new File(userDir, "bootstrap.jar"); if (bootstrapJar.exists()) { File f = new File(userDir, ".."); try { homeFile = f.getCanonicalFile(); } catch (IOException ioe) { homeFile = f.getAbsoluteFile(); if (homeFile == null) { // Second fall-back. Use current directory File f = new File(userDir); try { homeFile = f.getCanonicalFile(); } catch (IOException ioe) { homeFile = f.getAbsoluteFile(); //设置catalinaHomeFile catalinaHomeFile = homeFile; System.setProperty( Globals.CATALINA_HOME_PROP, catalinaHomeFile.getPath()); // Then base String base = System.getProperty(Globals.CATALINA_BASE_PROP); //设置catalinaBaseFile if (base == null) { catalinaBaseFile = catalinaHomeFile; } else { File baseFile = new File(base); try { baseFile = baseFile.getCanonicalFile(); } catch (IOException ioe) { baseFile = baseFile.getAbsoluteFile(); catalinaBaseFile = baseFile; System.setProperty( Globals.CATALINA_BASE_PROP, catalinaBaseFile.getPath()); // -------------------------------------------------------------- Variables * Daemon reference. private Object catalinaDaemon = null; protected ClassLoader commonLoader = null; protected ClassLoader catalinaLoader = null; protected ClassLoader sharedLoader = null; // -------------------------------------------------------- Private Methods private void init ClassLoader s() { try { //创建commonLoader commonLoader = create ClassLoader ("common", null); if( commonLoader == null ) { // no config file, default to this loader - we might be in a 'single' env. commonLoader=this.get Class ().get ClassLoader (); //创建catalinaLoader、sharedLoader catalinaLoader = create ClassLoader ("server", commonLoader); sharedLoader = create ClassLoader ("shared", commonLoader); } catch (Throwable t) { handleThrowable(t); log.error(" Class loader creation threw exception", t); System.exit(1); private ClassLoader create ClassLoader (String name, ClassLoader parent) throws Exception { //CatalinaProperties解析$CATALINA_HOME\conf\catalina.properties, //并将catalina.properties内的属性存为系统属性 //catalina.properties内common.loader="${catalina.base}/lib", //"${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar" //读取common.loader String value = CatalinaProperties.getProperty(name + ".loader"); if ((value == null) || (value.equals(""))) return parent; //将${catalina.base},${catalina.home}替换为Tomcat的绝对路径 value = replace(value); List<Repository> repositories = new ArrayList<>(); String[] repositoryPaths = getPaths(value); for (String repository : repositoryPaths) { // Check for a JAR URL repository try { @SuppressWarnings("unused") URL url = new URL(repository); repositories.add( new Repository(repository, RepositoryType.URL)); continue; } catch (MalformedURLException e) { // Ignore // Local repository if (repository.endsWith("*.jar")) { repository = repository.substring (0, repository.length() - "*.jar".length()); repositories.add( new Repository(repository, RepositoryType.GLOB)); } else if (repository.endsWith(".jar")) { repositories.add( new Repository(repository, RepositoryType.JAR)); } else { repositories.add( new Repository(repository, RepositoryType.DIR)); // ClassLoader Factory依据repositories的内容创建 ClassLoader return ClassLoader Factory.create ClassLoader (repositories, parent); * System property replacement in the given string. * @param str The original string * @return the modified string protected String replace(String str) { // Implementation is copied from ClassLoader LogManager.replace(), // but added special processing for catalina.home and catalina.base. String result = str; int pos_start = str.indexOf("${"); if (pos_start >= 0) { StringBuilder builder = new StringBuilder(); int pos_end = -1; while (pos_start >= 0) { builder.append(str, pos_end + 1, pos_start); pos_end = str.indexOf('}', pos_start + 2); if (pos_end < 0) { pos_end = pos_start - 1; break; String propName = str.substring(pos_start + 2, pos_end); String replacement; if (propName.length() == 0) { replacement = null; } else if (Globals.CATALINA_HOME_PROP.equals(propName)) { replacement = getCatalinaHome(); } else if (Globals.CATALINA_BASE_PROP.equals(propName)) { replacement = getCatalinaBase(); } else { replacement = System.getProperty(propName); if (replacement != null) { builder.append(replacement); } else { builder.append(str, pos_start, pos_end + 1); pos_start = str.indexOf("${", pos_end + 1); builder.append(str, pos_end + 1, str.length()); result = builder.toString(); return result; * Initialize daemon. public void init() throws Exception { //创建commonLoader、catalinaLoader、sharedLoader init ClassLoader s(); //为当前线程设置 ClassLoader Thread.currentThread().setContext ClassLoader (catalinaLoader); //设置Security Class Load。具体作用还不清楚。。。 Security Class Load.security Class Load(catalinaLoader); // Load our startup class and call its process() method if (log.isDebugEnabled()) log.debug("Loading startup class "); //通过反射实例化Catalina Class <?> startup Class = catalinaLoader.load Class ("org.apache.catalina.startup.Catalina"); Object startupInstance = startup Class .newInstance(); // Set the shared extensions class loader if (log.isDebugEnabled()) log.debug("Setting startup class properties"); String methodName = "setParent ClassLoader "; Class <?> paramTypes[] = new Class [1]; paramTypes[0] = Class .forName(" java .lang. ClassLoader "); Object paramValues[] = new Object[1]; paramValues[0] = sharedLoader; //通过反射设置Catalina的parent ClassLoader Method method = startupInstance.get Class ().getMethod(methodName, paramTypes); method.invoke(startupInstance, paramValues); //将实例化的Catalina赋值给catalinaDaemon catalinaDaemon = startupInstance; * Load daemon. private void load(String[] arguments) throws Exception { // Call the load() method //调用catalinaDaemon的load方法,并传递参数"start" String methodName = "load"; Object param[]; Class <?> paramTypes[]; if (arguments==null || arguments.length==0) { paramTypes = null; param = null; } else { paramTypes = new Class [1]; paramTypes[0] = arguments.get Class (); param = new Object[1]; param[0] = arguments; Method method = catalinaDaemon.get Class ().getMethod(methodName, paramTypes); if (log.isDebugEnabled()) log.debug("Calling startup class " + method); method.invoke(catalinaDaemon, param); * getServer() for configtest private Object getServer() throws Exception { String methodName = "getServer"; Method method = catalinaDaemon.get Class ().getMethod(methodName); return method.invoke(catalinaDaemon); // ----------------------------------------------------------- Main Program * Load the Catalina daemon. public void init(String[] arguments) throws Exception { init(); load(arguments); * Start the Catalina daemon. public void start() throws Exception { if( catalinaDaemon==null ) init(); //调用catalinaDaemon的start方法 Method method = catalinaDaemon.get Class ().getMethod("start", ( Class [] )null); method.invoke(catalinaDaemon, (Object [])null); * Stop the Catalina Daemon. public void stop() throws Exception { Method method = catalinaDaemon.get Class ().getMethod("stop", ( Class [] ) null); method.invoke(catalinaDaemon, (Object [] ) null); * Stop the standalone server. public void stopServer() throws Exception { Method method = catalinaDaemon.get Class ().getMethod("stopServer", ( Class []) null); method.invoke(catalinaDaemon, (Object []) null); * Stop the standalone server. public void stopServer(String[] arguments) throws Exception { Object param[]; Class <?> paramTypes[]; if (arguments==null || arguments.length==0) { paramTypes = null; param = null; } else { paramTypes = new Class [1]; paramTypes[0] = arguments.get Class (); param = new Object[1]; param[0] = arguments; Method method = catalinaDaemon.get Class ().getMethod("stopServer", paramTypes); method.invoke(catalinaDaemon, param); * Set flag. public void setAwait(boolean await) throws Exception { //通过反射,设置catalinaDaemon的await Class <?> paramTypes[] = new Class [1]; paramTypes[0] = Boolean.TYPE; Object paramValues[] = new Object[1]; paramValues[0] = Boolean.valueOf(await); Method method = catalinaDaemon.get Class ().getMethod("setAwait", paramTypes); method.invoke(catalinaDaemon, paramValues); public boolean getAwait() throws Exception Class <?> paramTypes[] = new Class [0]; Object paramValues[] = new Object[0]; Method method = catalinaDaemon.get Class ().getMethod("getAwait", paramTypes); Boolean b=(Boolean)method.invoke(catalinaDaemon, paramValues); return b.booleanValue(); * Destroy the Catalina Daemon. public void destroy() { // FIXME * Main method and entry point when starting Tomcat via the provided * scripts. * @param args Command line arguments to be processed public static void main(String args[]) { if (daemon == null) { // Don't set daemon until init() has completed //***2.1*** Bootstrap bootstrap = new Bootstrap(); try { //***2.2*** bootstrap.init(); } catch (Throwable t) { handleThrowable(t); t.printStackTrace(); return; //***2.3*** daemon = bootstrap; } else { // When running as a service the call to stop will be on a new // thread so make sure the correct class loader is used to prevent // a range of class not found exceptions. Thread.currentThread().setContext ClassLoader (daemon.catalinaLoader); //***2.4*** try { String command = "start"; if (args.length > 0) { command = args[args.length - 1]; if (command.equals("startd")) { args[args.length - 1] = "start"; daemon.load(args); daemon.start(); } else if (command.equals("stopd")) { args[args.length - 1] = "stop"; daemon.stop(); } else if (command.equals("start")) { //***2.5*** daemon.setAwait(true); //***2.6*** daemon.load(args); //***2.7*** daemon.start(); } else if (command.equals("stop")) { daemon.stopServer(args); } else if (command.equals("configtest")) { daemon.load(args); if (null==daemon.getServer()) { System.exit(1); System.exit(0); } else { log.warn("Bootstrap: command \"" + command + "\" does not exist."); } catch (Throwable t) { // Unwrap the Exception for clearer error reporting if (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); handleThrowable(t); t.printStackTrace(); System.exit(1); * Obtain the name of configured home (binary) directory. Note that home and * base may be the same (and are by default). public static String getCatalinaHome() { return catalinaHomeFile.getPath(); * Obtain the name of the configured base (instance) directory. Note that * home and base may be the same (and are by default). If this is not set * the value returned by {@link #getCatalinaHome()} will be used. public static String getCatalinaBase() { return catalinaBaseFile.getPath(); * Obtain the configured home (binary) directory. Note that home and * base may be the same (and are by default). public static File getCatalinaHomeFile() { return catalinaHomeFile; * Obtain the configured base (instance) directory. Note that * home and base may be the same (and are by default). If this is not set * the value returned by {@link #getCatalinaHomeFile()} will be used. public static File getCatalinaBaseFile() { return catalinaBaseFile; // Copied from ExceptionUtils since that class is not visible during start private static void handleThrowable(Throwable t) { if (t instanceof ThreadDeath) { throw (ThreadDeath) t; if (t instanceof VirtualMachineError) { throw (VirtualMachineError) t; // All other instances of Throwable will be silently swallowed // Protected for unit testing protected static String[] getPaths(String value) { List<String> result = new ArrayList<>(); Matcher matcher = PATH_PATTERN.matcher(value); while (matcher.find()) { String path = value.substring(matcher.start(), matcher.end()); path = path.trim(); if (path.startsWith("\"") && path.length() > 1) { path = path.substring(1, path.length() - 1); path = path.trim(); if (path.length() == 0) { continue; result.add(path); return result.toArray(new String[result.size()]); class Gobang extends JFrame implements Runnable, ActionListener final static int Player=1; final static int AI =-1; ClassLoader cl = this.get Class ().get ClassLoader (); Toolkit tk = Toolkit.getDefaultToolkit(); int length=14, game_state, winner, check, step; int grid[][] = new int[length][length]; int locX, locY /* 囱竚 */, count /* 硈囱计 */, x, y /* 既竚 */, displace_x=0, displace_y=0 /* 簿秖 */, direction; ArrayList steps = new ArrayList(); /* 癘魁囱˙ */ JPopupMenu control_menu = new JPopupMenu(); /* 龄匡虫 */ JMenuItem[] command = new JMenuItem[4]; String[] command_str={"囱", "郎", "弄郎", "秨"}; int[][] dir = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} }; boolean[] dir2 = new boolean[8]; boolean turn; String message; final JDialog dialog = new JDialog(this, "叫匡", true); Font font=new Font("new_font", Font.BOLD, 20); Grid grids[][] = new Grid[length][length]; Image white= tk.getImage(cl.getResource("res/white.png")); Image black= tk.getImage(cl.getResource("res/black.png")); Image title= tk.getImage(cl.getResource("res/title.png")); Image temp; JPanel boardPanel, bigpanel; JRadioButton[] choice = new JRadioButton[2]; final static int Start =0; final static int Select =1; final static int Playing =2; final static int End =3; final static int nil=-1; /* 礚よ */ final static int oblique_1 =0; /* オ */ final static int oblique_2 =1; /* オ */ final static int horizontal =2; /* 绢 */ final static int vertical=3; /*  */ Gobang() super("き囱"); boardPanel = new JPanel(); boardPanel.setLayout(new GridLayout(length, length, 0, 0)); boardPanel.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); for(int i=0; i<length; i++) for(int j=0; j<length; j++)
InputStream is = get Class ().get ClassLoader ().getResourceAsStream("helloworld.properties"); get Class ():取得当前 对象 所属的 Class 对象 get ClassLoader ():取得该 Class 对象 的类装载器 类装载器负责从 Java 字符文件将 字符流 读入 内存 ,并构造 Class 对象 ,所以通过它可以得到一个文件的输入流。 装载类的过程非常简单:查找类所在位置,并将找到的 Java 类的字节码装入 内存 ,生成对应的Cl
InputStream is = get Class ().get ClassLoader ().getResourceAsStream("helloworld.properties");中get Class ()和get ClassLoader ()都是什么意思呀. get Class ():取得当前 对象 所属的 Class 对象 ...
get Class ().getResource()与get ClassLoader ().getResource()的区别 文章目录get Class ().getResource()与get ClassLoader ().getResource()的区别简介测试结果Resources资源目录最终的问题总结 项目中我们经常要获取资源路径,我们会使用类名.get Class ().getResource()和get ClassLoader ().getResource()。这两个经常乱用,用着用着就迷了, 有些时候路径获取的
一文理解 class .get ClassLoader ().getResourceAsStream(file)和 class .getResourceAsStream(file)区别
为什么是 class path而不是src,因为当web项目运行时,IDE编译器会把src下的一些资源文件移至WEB-INF/ class es, class Path目录其实就是这个 class es目录。这个目录下放的一般是web项目运行时的 class 文件、资源文件(xml,properties...); 另外,在使用spring......
get ClassLoader ()与get Class ()的简单理解: 每一个 class 对象 都有一个get ClassLoader ()方法,得到是谁把我从. class 文件加载到 内存 中变成 Class 对象 的 而get Class ()方法是获得调用该方法的 对象 的类 什么是类加载? 我们都知道,每个. java 文件可以经过 java c指令编译成. class 文件,里面包含着 java 虚拟机的机器指令。当我们需要使用一个 java 类时,虚拟机会加载它的. class 文件,创建对应的 java 对象 。将. class 调入虚拟机的过程,称之为加载。 loading :加载。通过类的完全限定名找到. class 字节码文件,同时创建一个 对象 。...
文章目录一、 ClassLoader 的作用二、 ClassLoader 层次结构三、 Class 加载时调用类加载器的顺序 一、 ClassLoader 的作用 我们都知道 java 程序写好以后是以. java (文本文件)的文件存在磁盘上,然后,我们通过(bin/ java c.exe)编译命令把. java 文件编译成. class 文件(字节码文件),并存在磁盘上。 但是程序要运行,首先一定要把. class 文件加载...
Tomcat启动时报: org.apache.catalina.core.AprLifecycleListener.init An incompatible version 错误 11626