java026反射机制中(绝对路径和相对路径)反射构造器

Java读取Properties文件
Java读取Properties文件的方法有六种方法
但是最常用的还是通过java.lang.Class类的getResourceAsStream(String name)方法来实现,如下可以这样调用:(相对路径读取)

InputStream in = getClass().getResourceAsStream("资源Name");

或者下面这种也常用:(绝对路径读取)

InputStream in = new BufferedInputStream(new FileInputStream(filepath));

load ( InputStream inStream),从输入流中读取属性列表(键和元素对)。通过对指定的文件(比如说上面的 xx.properties 文件)进行装载来获取该文件中的所有键 - 值对。以供 getProperty ( String key) 来搜索。
getProperty ( String key),用指定的键在此属性列表中搜索属性

一,反射无参构造器:通过无参构造器实例化对象
根据相对路径访问
java读取配置文件报错Properties$LineReader.readLine(Unknown Source)
这个是properties文件路径问题,Java寻找文件的相对路径是相对于某个执行的Class路径而言的,比如你的类文件放到classes目录下,那么Java执行下面语句时就到classes目录下找。

在这里插入图片描述
如何排这个异常:
1,检查你的属性是否初始化,如果没有,会报空指针异常
2,看properties格式是否正确,一般系统自带的类格式是java.lang.String这种形式
自己写的类是zyy00.Teacher这种格式
3,看properties是否加载上了

String className=pro.getProperty("className");

让className代表xx.properties

className=zyy00.Teacher

4,看tostring是否重写了,如果没有,会输出类的地址,需要被重写
重写tostring
在这里插入图片描述

@Override
	public String toString() {
		return "Teacher [name=" + name + ", age=" + age + "]";
	}

所以正确代码如下:

package zyy00;
import java.lang.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Properties;
class Person{
	 public void f1(){
		 System.out.println("父类");
	 }
 } 
class Teacher extends Person{
	String name="张洋洋";
	@Override
	public String toString() {
		return "Teacher [name=" + name + ", age=" + age + "]";
	}
	int age=20;
	 Teacher(){
		this.name=name;
		this.age=age;
	}
	 
	public void f2(){
		System.out.println("子类");
	}
}
public class Test {
	public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
	   Properties pro=new Properties();//需要导包
	 // InputStream ss=new FileInputStream("E:\\workspace\\zyy00\\src\\xx.properties");
	   //绝对路径访问
	   InputStream in=Test.class.getClassLoader().getResourceAsStream("xx.properties");// 通过classLoader 获取资源 
	   //相对路径访问
	   pro.load(in);
	   String className=pro.getProperty("className");
	   Class clz=Class.forName(className);//动态加载
	   Object obj=clz.newInstance();
	   System.out.println(obj);
	}
	}


结果:
在这里插入图片描述
根据绝对路径访问:
1,先找到xx.properties的绝对路径
在这里插入图片描述
2,把路径复制到字节输入流里面

 InputStream ss=new FileInputStream("E:\\workspace\\zyy00\\src\\xx.properties");

注意:如果输入的路径不对,就会报错。

package zyy00;
import java.lang.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Properties;
class Person{
	 public void f1(){
		 System.out.println("父类");
	 }
 } 
class Teacher extends Person{
	String name="张洋洋";
	@Override
	public String toString() {
		return "Teacher [name=" + name + ", age=" + age + "]";
	}
	int age=20;
	 Teacher(){
		this.name=name;
		this.age=age;
	}
	 
	public void f2(){
		System.out.println("子类");
	}
}
public class Test {
	public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
	   Properties pro=new Properties();//需要导包
	  InputStream ss=new FileInputStream("E:\\workspace\\zyy00\\src\\xx.properties");
	   //绝对路径访问
	  // InputStream in=Test.class.getClassLoader().getResourceAsStream("xx.properties");// 通过classLoader 获取资源 
	   //相对路径访问
	   pro.load(ss);
	   String className=pro.getProperty("className");
	   Class clz=Class.forName(className);//动态加载
	   Object obj=clz.newInstance();
	   System.out.println(obj);
	}
	}


注意:new和newInstance的区别:
new是一个关键字,可以说是一个指令;
newInstance()是一个方法,Class对象的一个方法。
2》
new主要作用是在内存中生成一个实例,而这个类可以没有提前加载到内从中;
newInstance()主要作用是在内存中生成一个实例,而这个方法在使用前必须得保证:
①这个类被加载到内存中,
②这个类已经被连接,
而完成以上两个过程的是Class.forName()方法。
3》
new关键字的使用一般比较呆板的写入到程序中;
newInstance()方法一般用于框架中,工厂模式中等等。
4》
new关键字可以调用类的有参的public构造方法;
newInstance()方法只能调用类的无参构造方法。
二,反射有参构造器:通过有参构造器实例化对象
在这里插入图片描述
当无法找到某一特定方法时,就会抛出该异常!
1:对应的JAVA类中没有对应的属性,也就是说在页面的书写中对应的属性和JAVA类中定义的不一致,可能少的字母等
2:页面点的属性和JAVA类中的是一致的,并且对应的SET方法也是完全没问题的,在页面赋值的时候类型和类中定义的不匹配,比如:定义的是数字类型的赋的值却是字符串类型的等
但是这个错误的原因是构造器没有被public修饰
把构造函数当作创建对象的一个普通函数好了,和其他的函数一样,加public表示外部可以实例化该对象,如果是private,则只能自己实例化自己。
public 全部可见调用
protected 子类可调用
private 本类可调用
在这里插入图片描述
三,反射所有构造器:
通过class.getConstructors()和class.getDeclaredConstructors获取所有构造器
通过class.getConstructor()和class.getDeclaredConstructor获取默认构造函数
通过class.getConstructor(args…)和class.getDeclaredConstructor(args…)获取带参数的构造器
通过constructor.getDeclaringClass()获取构造器所属的类
实例化:
通过constructor.newInstance()以默认构造器进行对象实例化
通过constructor.newInstance(args…)以指定构造器进行对象实例

猜你喜欢

转载自blog.csdn.net/weixin_44699728/article/details/89814850