如何在其子类中访问类的私有变量?

这是我在接受采访时被问到的问题:我有A级私人成员,B级扩展A.我知道一个class级的私人成员无法访问,但问题是:我需要访问A类的私人成员B类,而不是在B类中创建具有相同值的变量。

面试官要么测试你对访问修饰符的了解,要么是你改变现有类的方法,或两者​​兼而有之。

我会列出它们(公共的,私有的,受保护的,包私有的)以及每个的解释。 然后继续说A类需要被修改以允许通过添加setter和getter,或者通过更改成员的访问修饰符来访问B类中的那些成员。 或者B类可以使用reflection。 最后,谈谈每种方法的优缺点。

reflection? 省略import,这应该有效:

public class A { private int ii = 23; } public class B extends A { private void readPrivateSuperClassField() throws Exception { Class clazz = getClass().getSuperclass(); Field field = clazz.getDeclaredField("ii"); field.setAccessible(true); System.out.println(field.getInt(this)); } public static void main(String[] args) throws Exception { new B().readPrivateSuperClassField(); } } 

如果你在调用readPrivateSuperClassField();之前做了类似的事情,它将无法工作readPrivateSuperClassField();

 System.setSecurityManager(new SecurityManager() { @Override public void checkMemberAccess(Class clazz, int which) { if (clazz.equals(A.class)) { throw new SecurityException(); } else { super.checkMemberAccess(clazz, which); } } }); 

而且还有其他条件,反思方法不起作用。 有关详细信息,请参阅SecurityManager和AccessibleObject 的API文档 。 感谢CPerkins指出这一点。

我希望他们只是测试你的知识,而不是寻找这些东西的真实应用;-)虽然我认为像这样的丑陋黑客在某些边缘情况下是合法的。

架构坏了。 私人会员是私人会员,因为您不希望他们在课堂和朋友之外访问。

您可以使用朋友黑客,访问者,推广会员或#define private public (heh)。 但这些都是短期解决方案 – 您可能不得不在某个阶段重新审视破碎的架构。

通过使用A的私人成员的公共访问者(getter和setter)……

您无法从父类访问私有成员。 您已使其受保护或具有可访问它们的受保护/公共方法。

编辑 :你可以使用reflection。 但这不是常见的,也不是打破封装的好主意。

嵌套类可以访问其封闭类的所有私有成员 – 包括字段和方法。 因此,子类inheritance的公共或受保护嵌套类可以间接访问超类的所有私有成员。

 public class SuperClass { private int a = 10; public void makeInner() { SubClass in = new SubClass(); in.inner(); } class SubClass { public void inner() { System.out.println("Super a is " + a); } } public static void main(String[] args) { SuperClass.SubClass s = new SuperClass().new SubClass(); s.inner(); } } 

如果我正确理解了这个问题,你可以将private更改为protected 。 受保护的变量可供子类访问,但其行为类似于私有变量。

通过使用setter和getter,你可以访问它

来自JLS§8.3。 现场声明 :

子类可以访问超类的私有字段 – 例如,如果两个类都是同一个类的成员。 然而,私有字段永远不会被子类inheritance。

我写的示例代码:

 public class Outer { class InnerA { private String text; } class InnerB extends InnerA { public void setText(String text) { InnerA innerA = this; innerA.text = text; } public String getText() { return ((InnerA) this).text; } } public static void main(String[] args) { final InnerB innerB = new Outer().new InnerB(); innerB.setText("hello world"); System.out.println(innerB.getText()); } } 

InnerA.text的可访问性的解释在这里是JLS§6.6.1。 确定可访问性 :

否则,成员或构造函数被声明为private,并且当且仅当它发生在包含成员或构造函数声明的顶级类(第7.6节)的主体内时才允许访问。

你可以使用A类的setter和getter。这就像你使用A类的对象一样。

你有没有想过让它们受到保护 ? 只是为了确保你知道这个选项,如果你当时原谅我提出这个琐事;)

  • 私有成员无法在派生类中访问
  • 如果要访问意味着可以使用getter和setter方法。
 class A { private int a; void setA(int a) { this.a=a; } int getA() { return a; } } Class B extends A { public static void main(String[] arg) { B obj= new B(); obj.setA(10); System.out.println("The value of A is:"+obj.getA()); } } 

私人将被隐藏,直到您获得正确的访问权限。 例如编写父项的程序员的Getters或setter。 如果它们不可见,那么接受它们只是私有而且无法访问的事实。 你为什么要这么做?

我不了解Java,但在某些语言中, 嵌套类型可以这样做:

  class A { private string someField; class B : A { void Foo() { someField = "abc"; } } } 

否则,使用访问器方法或protected字段(尽管它们经常被滥用)。

私有成员可以通过无法更改变量的方式在子类中访问,但您可以以只读方式访问该变量。

显然,使它们受到保护,或添加setter / getter是首选技术。 反思是绝望的选择。

只是向面试官展示,如果“访问”意味着读取访问,而IF类A生成XML或JSON等,您可以序列化A并解析有趣的字段。

  Class A { private int i; int getValue() { return i; } } class B extends A { void getvalue2() { A a1= new A(); sop(a1.getValue()); } } 

要访问子类中父类的私有变量,可以使用protected或将getter和setter添加到父类中的私有变量。

您不能直接从外部直接访问类的任何私有变量。

您可以使用gettersetter访问私有成员。

如何访问子类中的超类私有成员:

  1. 如果您想要包访问,只需将私有字段更改为protected。 它允许访问相同的包子类。
  2. 如果您有私有字段,那么只需提供一些Accessor方法(getter),您就可以在子类中访问它们。
  3. 你也可以使用内部类

     public class PrivateInnerClassAccess { private int value=20; class InnerClass { public void accessPrivateFields() { System.out.println("Value of private field : " + value); } } public static void main(String arr[]) { PrivateInnerClassAccess access = new PrivateInnerClassAccess(); PrivateInnerClassAccess.InnerClass innerClass = access.new InnerClass(); innerClass.accessPrivateFields(); } } 

    4,你也可以使用reflection,例如

      public class A { private int value; public A(int value) { this.value = value; } } public class B { public void accessPrivateA()throws Exception { A a = new A(10); Field privateFields = A.class.getDeclaredField("value"); privateFields.setAccessible(true); Integer value = (Integer)privateFields.get(a); System.out.println("Value of private field is :"+value); } public static void main(String arr[]) throws Exception { B b = new B(); b.accessPrivateA(); } } 

直接我们无法访问它。 但是使用Setter和Getter我们可以访问,

代码是:

 class AccessPrivate1 { private int a=10; //private integer private int b=15; int getValueofA() { return this.a; } int getValueofB() { return this.b; } } public class AccessPrivate{ public static void main(String args[]) { AccessPrivate1 obj=new AccessPrivate1(); System.out.println(obj.getValueofA()); //getting the value of private integer of class AccessPrivate1 System.out.println(obj.getValueofB()); //getting the value of private integer of class AccessPrivate1 } } 

您可以在代码中使用Accessor (getter和setter方法)。

通过使用setter方法,您可以在refection的帮助下使用else,您可以通过设置该成员说a – 从类中取一个并设置a.setAccessible(true)来使用类的私有成员;

您可能希望将其更改为受保护。 请参考这个

https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

如果这是你必须做的事情,只是为了做到这一点你可以使用reflection。 它将为您提供类中定义的所有变量的列表 – 公共,私有或受保护。 这确实有它的开销,但是,它是让你使用私有变量的东西。 有了这个,你可以在任何一个类中使用它。 它不必只是一个子类请参考下面的示例。 这可能有一些编译问题,但你可以得到基本的想法,它的工作原理

 private void getPropertiesFromPrivateClass(){ Field[] privateVariablesArray = PrivateClassName.getClass().getDeclaredFields(); Set propertySet = new HashSet(); Object propertyValue; if(privateVariablesArray.length >0){ for(Field propertyVariable :privateVariablesArray){ try { if (propertyVariable.getType() == String.class){ propertyVariable.setAccessible(true); propertyValue = propertyVariable.get(envtHelper); System.out.println("propertyValue"); } } catch (IllegalArgumentException illegalArgumentException) { illegalArgumentException.printStackTrace(); } catch (IllegalAccessException illegalAccessException) { illegalAccessException.printStackTrace(); } } 

希望这会有所帮助。 快乐学习:)

下面是访问子类对象中超类的私有成员的示例。

我正在使用构造函数来做同样的事情。

下面是超类Fruit

 public class Fruit { private String type; public Fruit() { } public Fruit(String type) { super(); this.type = type; } public String getType() { return type; } public void setType(String type) { this.type = type; } } 

下面是inheritance自Fruit的Guava子类

 public class Guava extends Fruit{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Guava(String name,String type) { super(type); this.name=name; } } 

下面是我们创建子类对象并显示超类成员的主要function。

 public class Main { public static void main(String[] args) { Guava G1=new Guava("kanpuria", "red"); System.out.println(G1.getName()+" "+G1.getType()); } } 

请注意,子类可以访问超类的私有字段(例如,如果两个类都是同一个类的成员),但是,私有字段永远不会被子类inheritance。

简单!!!

 public class A{ private String a; private String b; //getter and setter are here } 

 public class B extends A{ public B(String a, String b){ //constructor super(a,b)//from here you got access with private variable of class A } } 

谢谢

修饰符是您添加到这些定义以更改其含义的关键字。 Java语言有各种各样的修饰符,包括以下内容:

  • Java Access Modifiers
  • 非访问修饰符

要使用修饰符,请在类,方法或变量的定义中包含其关键字。 修饰符位于语句的其余部分之前。

这里有更多信息:

http://tutorialcorejava.blogspot.in/p/java-modifier-types.html