java2 day01

代码规范

编码要求:

  0:写代码:

  1):明确需求,我要做什么!!!

  2):整理思路,我要怎么一步一步去实现功能.

  3):按照思路去编写代码.

  4):功能写完,一定要测试.

  5):总结,该功能是怎么做出来的,下一次遇到,我该怎么迅速的解决.

定义标识符:

   不能是关键字,保留字.

   数字不能作为开始.

   起一个有意义的英文单词,如果是多个单词组成,使用驼峰表示法,以后的每一个单词首字母大写.

--------------------------------------

包名:全部使用小写字母组成.

   package  公司域名倒写.项目模块名.组件名;

   域名:   520it.com

   package com._520it.pss.util;

   平时上课:以知识点的名称来取代模块名.

类名: 使用名词,首字母大写.

   如:Employee,      EmployeeAdvanceSetting

   不要使用Java中自带类的类名,比如:不能起名String,System.

  XxxDemo:Xxx的演示程序,XxxTest:Xxx的测试程序,XxxMock:Xxx的模拟程序.

   Xxx表示一个对象或者模块.

接口名:使用名称/副词.首字母大写.

   一般的,有的公司习惯以I作为前缀.

   如:IEmployeeDAO,IEmployeeService.  

方法名:表示功能,使用动词,首字母小写.

   比如:save,delete,login,saveEmployee.

变量名:表示状态,使用名词,首字母小写.

   比如:username,email,password.  

常量名:使用final修饰的变量. publicstatic final 修饰.

   全部使用大写字母组成,多个单词之间使用下划线分割.

   Integer: MAX_VALUE/MIN_VALUE.

反射


Class类和Object有什么关系:

   Object:表示一切对象.

   Class: 表示一切类.

--------------------------------------------------------------

什么是反射:在运行时期,动态的去获取类中的成员信息(包,父类,接口,修饰符,类名,构造器,字段,方法等).

Eclipse中的outline(大纲视图),就是通过反射编写,目的:呈现出该类中所有的成员信息.

反射的API:

   Class:描述一切的类.

   Constructor:描述一切的构造器.

   Method: 描述一切的方法.

------------------------------------------------

使用反射:创建对象,调用方法:

反射操作性能较低,---->Java中的框架都是基于反射编写.-->反射是框架的基石.

Eclipse中的Outline就是反射的一种体现

Class类和Class实例

Class  类:用来表示所有的类(类,枚举,接口,注解),是所有类的类型.

Class实例:表示在JVM中运行的一份份字节码文件.

-------------------------------------------------------------

Class类可以表示所有类,那到底当前的Class类表示哪一个类呢,是表示String,还是ArrayList呢?

为了解决该问题,SUN公司给Class类提供了一个泛型,用来表示当前所表示的是哪一个类.

   若当前描述String类:     此时Class<String> clz.

   若当前描述ArrayList类:  此时Class<ArrayList> clz.

-------------------------------------------------------------

表示Class对象的三种方式:

   1):类型.class;      表示一份字节码

   2):对象.getClass(); 获取该对象的真实类型

   3):使用Class.forName(StringclassName):根据类的全限定名来获取Class对象

-------------------------------------------------------------

同一个类在JVM中就只有一份字节码.

九大内置的Class实例和数组的Class实例

基本数据类型不是对象,也没有全限定名,那如何获取Class实例呢?

8大基本数据类型和void关键字都可以表示为Class的实例.

  如: Class clz1 = int.class;    Class clz2 = boolean.class;

  问题: int和Integer是同一种数据类型吗?

  在包装类中都有一个叫TYPE的常量,返回对应基本类型的Class对象.


表示数组的Class对象:


如果:多个数组具有相同的元素类型并且维数也相同,此时才共享同一份字节码.

     和元素没有关系.

获取构造器

Class类描述了所有的类的成员(构造器,方法等)--->Class类具有获取某一个类的构造器的方法.

-----------------------------------------------------------------------------------------

步骤:

    1):获取被操作的类的字节码对象.

    2):获取构造器

-----------------------------------------------------------------------------------------

Class类获取构造器方法:

Constructor类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器

publicConstructor<?>[] getConstructors():该方法只能获取当前Class所表示类的public修饰的构造器

publicConstructor<?>[] getDeclaredConstructors():获取当前Class所表示类的所有的构造器,和访问权限无关

publicConstructor<T> getConstructor(Class<?>... parameterTypes):获取当前Class所表示类中指定的一个public的构造器

      参数:parameterTypes表示:构造器参数的Class类型

      如:public User(String name)

        Constructor c =  clz.getConstructor(String.class);

publicConstructor<T> getDeclaredConstructor(Class<?>... parameterTypes):获取当前Class所表示类中指定的一个的构造器

package _02_constructor;

import java.lang.reflect.Constructor;

public class Constructor_Demo {

	/**
	 * @param args
	 * @throws Exception 
	 * @throws NoSuchMethodException 
	 * @throws Exception 
	 */
	public static void main(String[] args) throws  Exception{
		//Class clz = Person.class;
		//Person p1 = new Person();
		//clz = p1.getClass();
		Class clz = Person.class;
		Constructor c1 = clz.getConstructor();
		System.out.println(c1);
		c1 = clz.getConstructor(String.class);
		System.out.println(c1);
		c1 = clz.getDeclaredConstructor(String.class,int.class);
		System.out.println(c1);
		System.out.println("-------------------");
		//这里只能获取public的构造方法
		Constructor[] c2 = clz.getConstructors();
		for (Constructor constructor : c2) {
			System.out.println(constructor);
		}
		System.out.println("-------------------");
		//这里可以获得全部的构造方法,跟访问修饰符无关
		c2 = clz.getDeclaredConstructors();
		for (Constructor constructor : c2) {
			System.out.println(constructor);
		}
		System.out.println("-------------------");
		
	}

}

class Person{
	public Person(){
		System.out.println("这是无参构造方法");
	}
	public Person(String name){
		System.out.println(name);
	}
	private Person(String name,int age){
		System.out.println(name+"---"+age);
	}
}

调用构造器创建对象

步骤:

    1):获取被操作的类的字节码对象.

    2):获取构造器

    3):调用构造器中创建对象的方法.

-------------------------------------------------------------

Constructor<T>类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器

常用方法:

publicT newInstance(Object... initargs):如调用带参数的构造器,只能使用该方式.

     参数:initargs:表示调用构造器的实际参数

     返回:返回创建的实例,T表示Class所表示类的类型

如果:一个类中的构造器是外界可以直接访问,同时没有参数.,那么可以直接使用Class类中的newInstance方法创建对象.

 public Object newInstance():相当于new 类名();

调用私有的构造器:

setAccessible(true)
package _03_newinstance;

import java.lang.reflect.Constructor;

public class NewInstance_Demo {

	/**
	 * @param args
	 * @throws Exception 
	 * @throws NoSuchMethodException 
	 */
	public static void main(String[] args) throws NoSuchMethodException, Exception {
		Class clz = Person.class;
		//无参的构造器创建对象
		Constructor c1 = clz.getConstructor();
		c1.newInstance();
		System.out.println("-------------------");
		//有参的公共构造器对象
		c1=clz.getConstructor(String.class);
		c1.newInstance("haha");
		System.out.println("-------------------");
		//创建私有的构造器对象
		c1= clz.getDeclaredConstructor(String.class,int.class);
		c1.setAccessible(true);
		c1.newInstance("luffy",18);
		System.out.println("-------------------");
		//另外无参的公共的,就是可以直接访问的无参构造器可以这样访问
		Person.class.newInstance();
	}

}
class Person{
	public Person(){
		System.out.println("这是无参构造器");
	}
	public Person(String name){
		System.out.println("hello  "+name);
	}
	private Person(String name,int age){
		System.out.println(name+"---"+age);
	}
}

获取方法

操作步骤:

  1):获取方法所在类的字节码对象.

  2):获取方法

-----------------------------------------------------------------

Class类中常用方法:

public Method[]getMethods():获取包括自身和继承过来的所有的public方法

public Method[]getDeclaredMethods():获取自身所有的方法(不包括继承的,和访问权限无关

public MethodgetMethod(String methodName,

                        Class<?>...parameterTypes):表示调用指定的一个公共的方法(包括继承的)

       参数:

               methodName: 表示被调用方法的名字

              parameterTypes:表示被调用方法的参数的Class类型如String.class

public MethodgetDeclaredMethod(String name,

                            Class<?>...parameterTypes):表示调用指定的一个本类中的方法(不包括继承的)

        参数:

               methodName: 表示被调用方法的名字

              parameterTypes:表示被调用方法的参数的Class类型如String.class

package _04_getandnewmethod;

import java.lang.reflect.Method;

public class Demo1 {

	/**
	 * @param args
	 * @throws Exception 
	 * @throws NoSuchMethodException 
	 */
	public static void main(String[] args) throws NoSuchMethodException, Exception {
		Class clz = Person.class;
		Method[] m1 = clz.getMethods();
		for (Method m : m1) {
			System.out.println(m);
		}
		System.out.println("-------------------");
		Method m2 = clz.getMethod("sayHello", String.class);
		System.out.println(m2);
		System.out.println("-------------------");
		Method m3 = clz.getDeclaredMethod("sayBye", String.class,int.class);
		System.out.println(m3);
	}

}

class Person{
	Person(){
		System.out.println("默认构造方法");
	}
	public void sayHello(String name){
		System.out.println("hello  "+name);
	}
	private void sayBye(String name,int age){
		System.out.println(age+" OUT "+name);
	}

}
使用反射调用方法

操作步骤:

   1):获取方法所在类的字节码对象.

   2):获取被调用的方法.

   3):使用Method类中的invoke方法来调用.

--------------------------------------------------------------

如何使用反射调用一个方法:

在Method类中有方法:

public Objectinvoke(Object obj,Object... args):表示调用当前Method所表示的方法

      参数:

            obj: 表示被调用方法底层所属对象

                 Method m =clz.getMethod("sayHi",String.class);

            args:表示调用方法是传递的实际参数

      返回:

            底层方法的返回结果

调用私有方法:

  在调用私有方法之前:应该设置该方法为可访问的

又因为Method是AccessibleObject子类,所以Method中具有该方法.

m.setAccessible(true);

--------------------------------------------------------------

使用反射来调用静态方法和数组参数方法:

  如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null

 对于数组类型的引用类型的参数,底层会自动解包,为了解决该问题,我们使用Object的一维数组把实际参数包装起来.

   使用反射调用方法时:王道做法:

   Method对象.invoke(底层对象,newObeject[ 实际参数 ]);

package _04_getandnewmethod;

import java.lang.reflect.Method;
import java.util.Arrays;

public class InvokeDemo1 {

	/**
	 * @param args
	 * @throws Exception 
	 * @throws NoSuchMethodException 
	 */
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws NoSuchMethodException, Exception {
		Class clz = Person2.class;
		
		Object obj = clz.newInstance();
		//调用public void method1(String name)
		Method mm1 = clz.getMethod("method1", String.class);
		mm1.invoke(obj, "wiii");
		System.out.println("-------------------");
		Method mm2 = clz.getDeclaredMethod("method2",String.class,int.class);
		mm2.setAccessible(true);
		mm2.invoke(obj,"xyz",23);
		//静态方法的调用 invoke的时候使用的是null 然后是一个Object数组的一个包裹(这里可以有效的解决引用类型的问题)
		Method mm3 = clz.getMethod("method3", int[].class);
		//mm3.invoke(null, new int[]{1,2,3,45,5});  
		mm3.invoke(null, new Object[]{new int[]{1,2,3,4,5}});
	}

}
class Person2{
	Person2(){
		
	}
	public void method1(String name){
		System.out.println("hello "+name);
	}
	private void method2(String name,int age){
		System.out.println(name+"---"+age);
	}
	public static void method3(int...nums){
		System.out.println(Arrays.toString(nums));
	}
}

使用反射获取字段

1.找到字段所在类的字节码

2.获取字段

public Field[]getFields():获取当前Class所表示类中所有的public的字段,包括继承的字段.

public FieldgetField(String fieldName):获取当前Class所表示类中该fieldName名字的public字段,包括继承的字段.

public Field[] getDeclaredFields():获取当前Class所表示类中所有的字段,不包括继承的字段.

public Field[] getDeclaredField(Stringname):获取当前Class所表示类中该fieldName名字的字段,不包括继承的字段.

给某个类中的字段设置值和获取值:

1,找到被操作字段所在类的字节码

2,获取到该被操作的字段对象

3,设置值/获取值

Field类常用方法:

 void setXX(Object obj, XX value):为基本类型字段设置值,XX表示基本数据类型

 void set(Object obj, Object value):表示为引用类型字段设置值

  参数:

      obj:   表示字段底层所属对象,若该字段是static的,该值应该设为null

      value: 表示将要设置的值

-------------------------------------------------------------------------------------

 XX getXX(Object obj) :获取基本类型字段的值,XX表示基本数据类型

 Object get(Object obj) :表示获取引用类型字段的值

   参数:

      obj:   表示字段底层所属对象,若该字段是static的,该值应该设为null

   返回:返回该字段的值.


反射相关的其他API

Class类中:

  int getModifiers():获得修饰符

  String getName():返回类的全限定名

  Package getPackage():获得该类的包

  String getSimpleName():获得类的简单名字

  Class getSuperclass():获得类的父类

  boolean isArray():判断该Class实例是否是数组

  boolean isEnum() :判断该Class实例是否是枚举

Constructor,Method的信息:

   去查阅相应类的API即可.


单例模式



classpath文件

环境变量:

---------------------------------------------------

     PATH:告诉电脑去哪里去找javac/java等工具.

CLASSPATH:告诉JVM从哪里去找字节码文件.

在Eclipse项目/工程下有一个叫:.classpath的文件.


加载资源路径

package properties;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class demo1 {

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		//method1(); 绝对路径获取文件
		//method3(); 当前加载类的类路径 也就是是demo1.class的同一个路径
		
		
		//下面的代码是classpath的根路径
		String fileName = "db.properties";
		Properties pro = new Properties();
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		InputStream in = loader.getResourceAsStream(fileName);
		
		pro.load(in);
		String username = pro.getProperty("username");
		String password = pro.getProperty("password");
		System.out.println("用户名是:"+username+",密码是:"+password);
	}

	private static void method3() throws IOException {
		String fileName = "db.properties";
		Properties pro = new Properties();
		InputStream in = demo1.class.getResourceAsStream(fileName);
		
		
		pro.load(in);
		String username = pro.getProperty("username");
		String password = pro.getProperty("password");
		System.out.println("用户名是:"+username+",密码是:"+password);
	}

	private static void method1() throws FileNotFoundException, IOException {
		String fileName = "/Users/luffy/Desktop/javase/day18/resources/db.properties";
		Properties pro = new Properties();
		InputStream in = new FileInputStream(fileName);
		pro.load(in);
		String username = pro.getProperty("username");
		String password = pro.getProperty("password");
		System.out.println("用户名是:"+username+",密码是:"+password);
	}

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值