static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
static成员变量的初始化顺序按照定义的顺序进行初始化。
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会在类加载时执行一次。
使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。
因此,如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。
另外类的private方法会隐式地被指定为final方法。
对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。
static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变。
如果对临界资源加上互斥锁,当一个线程在访问该临界资源时,其他线程便只能等待。
在Java中,每一个对象都拥有一个锁标记(monitor),也称为监视器,多线程同时访问某个对象时,线程只有获取了该对象的锁才能访问。
a)当一个线程正在访问一个对象的synchronized方法,那么其他线程不能访问该对象的其他synchronized方法。这个原因很简单,因为一个对象只有一把锁,当一个线程获取了该对象的锁之后,其他线程无法获取该对象的锁,所以无法访问该对象的其他synchronized方法。
b)当一个线程正在访问一个对象的synchronized方法,那么其他线程能访问该对象的非synchronized方法。这个原因很简单,访问非synchronized方法不需要获得该对象的锁,假如一个方法没用synchronized关键字修饰,说明它不会使用到临界资源,那么其他线程是可以访问这个方法的,
c)如果一个线程A需要访问对象object1的synchronized方法fun1,另外一个线程B需要访问对象object2的synchronized方法fun1,即使object1和object2是同一类型),也不会产生线程安全问题,因为他们访问的是不同的对象,所以不存在互斥问题。
synchronized代码块类似于以下这种形式:
synchronized(synObject){
}
当在某个线程中执行这段代码块,该线程会获取对象synObject的锁,从而使得其他线程无法同时访问该代码块。
synObject可以是this,代表获取当前对象的锁,也可以是类中的一个属性,代表获取该属性的锁。
synchronized代码块使用起来比synchronized方法要灵活得多。因为也许一个方法中只有一部分代码只需要同步,如果此时对整个方法用synchronized进行同步,会影响程序执行效率。而使用synchronized代码块就可以避免这个问题,synchronized代码块可以实现只对需要同步的地方进行同步。对于synchronized方法或者synchronized代码块,当出现异常时,JVM会自动释放当前线程占用的锁,因此不会由于异常导致出现死锁现象。
每个类也会有一个锁,它可以用来控制对static数据成员的并发访问。
并且如果一个线程执行一个对象的非static synchronized方法,另外一个线程需要执行这个对象所属类的static synchronized方法,此时不会发生互斥现象,因为访问static synchronized方法占用的是类锁,而访问非static synchronized方法占用的是对象锁,所以不存在互斥现象。
反射就是把Java类中的各种成份影射成一个个的Java对象。例:一个类有:成员变量,方法,构造方法等,包等等信息,利用反射技术可以对一个类进行剖析,把各个组成部分影射成一个个对象。
(1)Class类—可获取类和类的成员信息
(2)Field类—可访问类的属性
(3)Method—可调用类的方法
(4)Constructor—可调用类的构造方法
(1)导入java.lang.reflect.*
(2)获得需要操作的类的Java.lang.Class对象
(3)调用Class的方法获取Field,Method等对象
(4)使用反射API进行操作(设置属性,调用方法)
(1)Class类是Java反射机制的起源和入口
(2)Class类的实例化对象代表一个正在运行的Java类或接口
·每个类都有自己的Class对象
·用于获取与类相关的各种信息
·提供了获取类信息的相关方法
·Class类继承至Object类
(3)Class类存放类的结构信息
·类名;·父类,接口;·方法,构造方法,属性;·注释
(1)方法一:
//方法1:对象.getClass()
Student stu=new Student();
Class clazz=stu.getClass();
(2)方法二:
//方法2:类.class
Class clazz= Student.class;
Class clazz=String.class;
方法三:
//方法3:Class.forName()
clazz=Class.forName("java.lang.String");
clazz=Class.forName("java.util.Date");
(a)获取类的Class对象:
Class clazz=Class.forName(“java.lang.Object”);
(b)获取Filed对象:
Filed fileds[]=clazz.getDeclaredFileds();
(c)获取Method对象:
Method methods[]=clazz.getDeclaredMethods();
(d)获取Constructor对象:
Constructor constructos[]= clazz.getDeclaredConstructor();
(1)方法一:
使用Class的newInstance()方法,仅适用于无参构造方法
Class clazz=Class.forName(“org.Student”);
Object obj=clazz.newInstance();
(2)方法二:
方法二:调用Constructor的newInstance()方法,适用所有构造方法
Contructor cons=clazz.negtDeclaredConstructor(Class<?>…parameterTypes);
Object obj=cons.newInstance(Object..initargs):
原文:https://www.cnblogs.com/needoffer/p/10770908.html