在Java中调用同类中的方法静态方法能否调用类成员变量呢?为什么?

trackbacks-0
前言:这属于 java 的基础知识,你可以不了解,也可以不拿它当一回事,代码也一样能敲的顺畅;这是很久之前,我从 C++ 转 java 刚入门那会的看法,那会我坚持自己的理念:&&&&重实践,讲运用,轻理论。当然,对同一样事物,在不同阶段也会有不一样的看法,这理念在某个时段已经不适合我,早就被抛弃了。不扯淡了,直接进入主题。java 中的变量大致分为 成员变量 和 局部变量 两大类。成员变量:&&&&在类体里面定义的变量称为成员变量;&&&&如果该成员变量有 static 关键字修饰,则该成员变量称为 静态变量 或 类变量;&&&&如果该成员变量没有 static 关键字修饰,则该成员变量被称为 非静态变量 或 实例变量。局部变量:&&&&形参、方法内定义的变量、代码块中定义的变量,都属于局部变量。类变量 (静态变量)&&&&1. 可以向前引用&&&&2. 变量属于类本身&&&&3. 类变量不依赖类的实例,类变量只在初始化时候在栈内存中被分配一次空间,无论类的实例被创建几次,都不再为类变量分配空间&&&&4. 通过类的任意一个实例来访问类变量,底层都将将其转为通过类本身来访问类变量,它们的效果是一样的&&&&5. 一旦类变量的值被改变,通过类或类的任意一个实例来访问类变量,得到的都将是被改变后的值&&&&6. 将在类的初始化之前初始化实例变量(非静态变量)&&&&1. 不能向前引用,如果向前引用,则称为非法向前引用,这是不允许的&&&&2. 变量属于类的实例对象&&&&3. 随着类的实例被创建而分配内存空间非静态代码块&&&&直接由 { } 包起来的代码,称为非静态代码块静态代码块&&&&直接由 static {&} 包起来的代码,称为静态代码块类变量(静态变量)、实例变量(非静态变量)、静态代码块、非静态代码块 的初始化时机&&&&由 static 关键字修饰的(如:类变量[静态变量]、静态代码块)将在类被初始化创建实例对象之前被初始化,而且是按顺序从上到下依次被执行;&&&&没有 static 关键字修饰的(如:实例变量[非静态变量]、非静态代码块)初始化实际上是会被提取到类的构造器中被执行的,但是会比类构造器中的&&&&代码块优先执行到,其也是按顺序从上到下依次被执行。- 以上是本人在翻完 PDF 后的个人笔记和理解以及见解,不见得百分百对,以下附上本人测试示例代码,会更有说服性示例代码
&1&2/**&3&*&-----------------------------------------&4&*&&#64;文件:&Statical.java&5&*&&#64;作者:&fancy&6&*&&#64;邮箱:&fancydeepin&#64;yeah.net&7&*&&#64;时间:&&8&*&&#64;描述:&TEST&9&*&-----------------------------------------<span style="color: #&*/<span style="color: #public&class&Statical&{<span style="color: #<span style="color: #&/**<span style="color: #&&&&&*&静态代码块<span style="color: #&&&&&*&类变量(静态变量)可以向前引用(即:先引用,再定义)<span style="color: #&&&&&*/<span style="color: #&&&&static&{<span style="color: #&&&&&&&&name&=&"fancydeepin";&//&name&的定义在使用之后<span style="color: #&&&&&&&&System.out.println("---&&&静态代码块被执行&&&&---");<span style="color: #&&&&}<span style="color: #&/**<span style="color: #&&&&&*&类变量(静态变量)在类的初始化之前初始化,无论类的实例将被创建多少个<span style="color: #&&&&&*&类变量(静态变量)都将只在初始化时候在栈内存上分配一次空间<span style="color: #&&&&&*&凡&static&修饰的,都将按位置被顺序执行,所以,<span style="color: #&&&&&*&name&的值最终输出&fancy&而不是上面的&fancydeepin<span style="color: #&&&&&*/<span style="color: #&&&&public&static&String&name&=&"fancy";&//类变量(静态变量)<span style="color: #&&&&private&String&mail&=&"myEmail";&//实例变量(非静态变量),定义时指定初始值,会比在构造器赋予值更早执行<span style="color: #&&&&<span style="color: #&&&&public&Statical() {<span style="color: #&&&&&&&&mail&=&"fancydeepin&#64;yeah.net";<span style="color: #&&&&&&&&System.out.println("---&&构造器代码块被执行&&---");<span style="color: #&&&&}<span style="color: #&/**<span style="color: #&&&&&*&非静态代码块<span style="color: #&&&&&*&实际上,非静态代码块在类初始化创建实例时,将会被提取到类的构造器中,<span style="color: #&&&&&*&但是,非静态代码块会比构造器中的代码块优先被执行<span style="color: #&&&&&*&所以,mail&最终输出的是类构造器中给定的值,也就是&fancydeepin&#64;yeah.net<span style="color: #&&&&&*&而不是&&#,更不是&myEmail<span style="color: #&&&&&*/<span style="color: #&&&&{<span style="color: #&&&&&&&&mail&=&"<span style="color: #&#";<span style="color: #&&&&&&&&System.out.println("---&&非静态代码块被执行&&---");<span style="color: #&&&&}<span style="color: #&&&&<span style="color: #&&&&//&getting&and&setting&<span style="color: #
测试类示例代码
&1&2&&&&& /**&3&&&&&&&&&*&类变量(静态变量)在类被初始化创建实例之前被初始化&4&&&&&&&&&*/&5&&&&&&&&System.out.println("-----------------&&&#64;1&&----------------");&6&&&&&&&&System.out.println("name&---&&&"&+&Statical.name);&//&&#64;1&7&&&&&&&&System.out.println("-----------------&&&#64;1&&----------------");&8&&&&&&&/**&9&&&&&&&&&*&创建类的实例对象<span style="color: #&&&&&&&&&*/<span style="color: #&&&&&&&&System.out.println("-----------------&&&#64;6&&----------------");<span style="color: #&&&&&&&&Statical&statical&=&new&Statical();&//&&#64;6<span style="color: #&&&&&&&&System.out.println("-----------------&&&#64;6&&----------------");<span style="color: #&&&&&&& /**<span style="color: #&&&&&&&&&*&通过实例来访问类变量,底层将转化成通过类本身来访问类变量<span style="color: #&&&&&&&&&*/<span style="color: #&&&&&&&&System.out.println("-----------------&&&#64;2&&----------------");<span style="color: #&&&&&&&&System.out.println("name&---&&&"&+&statical.name);&//&&#64;2<span style="color: #&&&&&&&&System.out.println("-----------------&&&#64;2&&----------------");<span style="color: #&&&&&&&/**<span style="color: #&&&&&&&&&*&如果类变量的值被改变,再访问类变量,将得到被改变后的值<span style="color: #&&&&&&&&&*/<span style="color: #&&&&&&&&Statical.name&=&"fancydeepin";<span style="color: #&&&&&&&&<span style="color: #&&&&&&&&System.out.println("-----------------&&&#64;3&&----------------");<span style="color: #&&&&&&&&System.out.println("name&---&&&"&+&statical.name);&//&&#64;3<span style="color: #&&&&&&&&System.out.println("-----------------&&&#64;3&&----------------");<span style="color: #&&&&&&&&<span style="color: #&&&&&&&&System.out.println("-----------------&&&#64;4&&----------------");<span style="color: #&&&&&&&&System.out.println("name&---&&&"&+&Statical.name);&//&&#64;4<span style="color: #&&&&&&&&System.out.println("-----------------&&&#64;4&&----------------");<span style="color: #&&&&&&&/**<span style="color: #&&&&&&&&&*&非静态代码块&和&构造器&被执行的时机<span style="color: #&&&&&&&&&*/<span style="color: #&&&&&&&&System.out.println("-----------------&&&#64;5&&----------------");<span style="color: #&&&&&&&&System.out.println("mail&---&&&"&+&statical.getMail());&//&&#64;5<span style="color: #&&&&&&&&System.out.println("-----------------&&&#64;5&&----------------");<span style="color: #
后台输出结果
-----------------&&&#64;<span style="color: #&&-------------------&&&静态代码块被执行&&&&---name&---&&&fancy-----------------&&&#64;<span style="color: #&&---------------------------------&&&#64;<span style="color: #&&-------------------&&非静态代码块被执行&&------&&构造器代码块被执行&&--------------------&&&#64;<span style="color: #&&---------------------------------&&&#64;<span style="color: #&&----------------name&---&&&fancy-----------------&&&#64;<span style="color: #&&---------------------------------&&&#64;<span style="color: #&&----------------name&---&&&fancydeepin-----------------&&&#64;<span style="color: #&&---------------------------------&&&#64;<span style="color: #&&----------------name&---&&&fancydeepin-----------------&&&#64;<span style="color: #&&---------------------------------&&&#64;<span style="color: #&&----------------mail& ---&&&fancydeepin&#64;yeah.net-----------------&&&#64;<span style="color: #&&----------------
为了能更好的看出后台的输出是哪一行代码执行的结果,我用了 &#64;和数字来做了标记,希望大家不要看晕了哈 ^_^最后针对输出结果简单说一下:&#64;1 说明,静态(类变量、静态代码块)属于类本身,不依赖于类的实例&#64;6 说明,在创建类的实例对象的时候,非静态代码块比构造器代码块更早的执行&#64;3 4&说明,当类变量的值改变后,再通过类或类的实例来访问类变量,得到的将是被改变后的值&#64;5 说明,非静态(实例变量、非静态代码块)的地位是相等的,它们将按顺序被执行,但会比构造器中的代码块更早的执行 &&
阅读(10383)
&re: java 中的 成员变量、局部变量、静态变量、类变量、非静态变量、实例变量、向前引用、非法向前引用、静态代码块、非静态代码块 执行时机[未登录]
类变量只被加载到方法区,而不是栈内存&&&&&&
&re: java 中的 成员变量、局部变量、静态变量、类变量、非静态变量、实例变量、向前引用、非法向前引用、静态代码块、非静态代码块 执行时机
请问一个问题类的成员变量,不能够在类中使用 这是为什么呢比如class Test{
private List list = new ArrayList();
list.add(&abc&);// 在这里是不能使用 list变量的 原因是什么呢?
&re: java 中的 成员变量、局部变量、静态变量、类变量、非静态变量、实例变量、向前引用、非法向前引用、静态代码块、非静态代码块 执行时机[未登录]
&#64;colorain它是需要在方法中执行的。&&&&&&
随笔分类(8)
随笔档案(104)
积分与排名
阅读排行榜问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
《thinking in java》中有这么一段话:
正如前面所提到的,如果没能为类访问权限指定一个访问修饰符,它就会缺省得到包访问权限。这意味着该类的对象可以由包内任何其他类来创建,但包外则是不行的。(一定要记住,相同目录下的所有不具有明确package声明的文件,都被视作是该目录下缺省包的一部分。)然而,如果该类的某个static成员是public的话,则客户端程序员仍旧可以调用该static成员,尽管他们并不能生成该类的对象
其中最后一句话该怎么理解? 如果一个类是默认的包访问控制权限,那么这个类只能在包中被访问,而客户端程序员一定是在一个新的包中试图访问该对象,按照我的理解是不应该访问到该类的,所以尽管其中有public static成员变量,也是无法访问的。
我的理解有什么问题吗?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
单看这句话完全是错误的!
没有任何办法(即使通过反射)可以在包外访问一个具有包访问控制权限的类的public static成员。
为了避免翻译问题,我专门去翻了英文原版,恍然大悟:结合上下文,作者在前面给出了一个单例的例子,而这句话还是接着那个例子说的
If you don?t want anyone else to have access to that class,
you can make all the constructors private
//: c05:Lunch.java
// Demonstrates class access specifiers. Make a class
// effectively private with private constructors:
class Soup {
private Soup() {}
// (1) Allow creation via static method:
public static Soup makeSoup() {
return new Soup();
// (2) Create a static object and return a reference
// upon request.(The "Singleton" pattern):
private static Soup ps1 = new Soup();
public static Soup access() {
return ps1;
public void f() {}
class Sandwich { // Uses Lunch
void f() { new Lunch(); }
// Only one public class allowed per file:
public class Lunch {
void test() {
// Can't do this! Private constructor:
//! Soup priv1 = new Soup();
Soup priv2 = Soup.makeSoup();
Sandwich f1 = new Sandwich();
Soup.access().f();
后面单拎出来这个函数来讲,该类的某个static成员是public的话指代的也是这部分内容
public static Soup access() {
return ps1;
The class Soup shows how to prevent direct creation of a class
by making all the constructors private.
上下文非常明确,不能生成该类的对象不是因为题主想当然的一定是在一个新的包中试图访问,而是在同一个包,因为构造函数被定义为私有而无法创建实例
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
为什么public的不能访问呢。。。。就是字面上的意思啊。。。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
这应该只是java的一个语法吧。。。。
有包访问权限的对象可以由包内任何其他类来创建,但在包外则不行。
具体java里面是怎么处理这个,可能就需要去看Jvm规范的。。。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
一个是类的访问权限,一个是类中变量的访问权限。
先能访问到类,才能访问类中的变量,所以是一层包含一层的关系,外层可见才有可能见到内部。
同步到新浪微博
分享到微博?
Hi,欢迎来到 SegmentFault 技术社区!⊙▽⊙ 在这里,你可以提出编程相关的疑惑,关注感兴趣的问题,对认可的回答投赞同票;大家会帮你解决编程的问题,和你探讨技术更新,为你的回答投上赞同票。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:java中成员变量与局部变量区别分析
投稿:shichen2014
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了java中成员变量与局部变量区别,较为详细的分析了java中成员变量与局部变量的功能、用法与区别,具有一定参考借鉴价值,需要的朋友可以参考下
本文实例分析了java中成员变量与局部变量区别。分享给大家供大家参考。具体分析如下:
成员变量:在这个类里定义的私有变量,属于这个类。
创建以及使用成员变量
代码如下:public class Person {
&&& String S
&&& double H
&&& public static void main(String arges[])
&&&&&&& Person p=new Person();
&&&&&&& p.name="小黄";
&&&&&&& p.Sex="男";
&&&&&&& p.age=20;
&&&&&&& p.Height=1.7;
&&&&&&& System.out.println("姓名:"+p.name+",性别"+p.Sex+",年龄:"+p.age+",年龄:"+p.Height);
成员变量初始化过程
一、类的初始化
对于类的初始化:类的初始化一般只初始化一次,类的初始化主要是初始化静态成员变量。
类的编译决定了类的初始化过程。
编译器生成的class文件主要对定义在源文件中的类进行了如下的更改:
1)先按照静态成员变量的定义顺序在类内部声明成员变量。
2)再按照原java类中对成员变量的初始化顺序进行初始化。
一个java类和编译后的class对应的转换如下:
代码如下:public class Person{
  public static String name="张三";
  static{
&&&&&& age=20;
    System.out.println("初始化age");
  public static S
  static{
    address="北京市";
    age=34;
  public static void main(String[] args) {
&&&&&&&&&&&&&&&&&& System.out.println(name);
&&&&&&&&&&&&&&&&&& System.out.println(age);
&&&&&&&&&&&&&&&&&& System.out.println(address);
&&&&&&&& }
当java源代码转换成一个class文件后,其转换成类似下面的代码:
代码如下:public class Person{
  public static S
  public static S
  static{
    name="张三";
    age=20;
    System.out.println("初始化age");
    address="北京市";
    age=34;
  public static void main(String[] args) {
&&&&&&&&&&&&&&&&&& System.out.println(name);
&&&&&&&&&&&&&&&&&& System.out.println(age);
&&&&&&&&&&&&&&&&&& System.out.println(address);
&&&&&&&& }
初始化顺序依据转换后对应的class类成员变量的初始化顺序依次执行,所以所有的静态成员变量都是先声明,后执行赋值的,而且赋值的顺序也是依照源代码对静态成员变量初始化的顺序进行的,注意:定义一个成员变量并直接初始化与在静态代码块中进行初始化是等价的,都是依据它们在源代码中定义的顺序进行的。
局部变量:在方法体里创建,在方法体外访问不到这个变量。
局部变量的创建与使用(局部变量必须赋值,成员变量可以不赋值)
代码如下:public class Person {
&&& public static void main(String arges[])
&&&&&&& String name="小黄";
&&&&&&& String Sex="男";
&&&&&&& int age=20;
&&&&&&& double Height=1.70;
&&&&&&& System.out.println("姓名:"+name+",性别"+Sex+",年龄:"+age+",年龄:"+Height);
代码如下:public class PassTest {
&public static void main(String args[]) {
& StringBuffer a = new StringBuffer("a");
& StringBuffer b = new StringBuffer("b");
& a(a, b);
& System.out.println(a);
& System.out.println(b);
& PassTest p = new PassTest();
&static void a(StringBuffer a, StringBuffer b) {
& a = a.append(b);
按照局部变量的使用范围来说 结果应该是 a b 但是 实际上输出的确实 ab b 请问为什么&#63;
传递参数引用的问题吧.引用的话,传递的应该是相同引用的副本.
a方法里边b=a是改变副本b引用=a,但是对main里的b没有影响.
a = a.append(b); 主要是a.append(b);这句改变了a引用指向的值,因为main里的a也是指向同一对象,所以输出为ab b
如果a = a.append(b);改为 a = new StringBuffer("ab"); 将输出a b
再看下面两段程序:
代码如下:public class Variable
void test()
&& int j=8;
&& if(j==i)
&&& System.out.println("相等");
&&& System.out.println("不相等");
public static void main(String[] args)
&& Variable v=new Variable();
&& v.test();
代码如下:public class Variable
&& void test()
&& int j=8;
&& if(j==i)
&&& System.out.println("相等");
&&& System.out.println("不相等");
public static void main(String[] args)
&& Variable v=new Variable();
&& v.test();
第一个程序很正常,编译时不会出错。第二个程序编译时会提示如下错误:
D:Programjavatest&javac Variable.java
Variable.java:9: 可能尚未初始化变量 i
&&&&&&&&&&&&&&& if(j==i)
&&&&&&&&&&&&&&&&&&&&& ^
之所以会出现这样的错误是因为:成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值
类体分为两部分。变量定义部分所定义的变量被称为类的成员变量,在方法体中定义的变量和方法的参数都被称为局部变量
局部变量和成员变量的区别
局部变量描述的是这个方法体内的属性,而成员变量描述的是这个对象里的属性。
成员变量可以被public、protected、default、private、static、final修饰符修饰,局部变量只能被final修饰符修饰。
成员变量在堆里进行创建,局部变量在栈里进行创建。
局部变量是系统默认值,局部变量没有系统默认值,必须手动赋值
希望本文所述对大家的java程序设计有所帮助。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具}

我要回帖

更多关于 java反射调用静态方法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信