Can I discover a Java class' declared inner classes using reflection? - java

In Java, is there any way to use the JDK libraries to discover the private classes implemented within another class? Or do I need so use something like asm?

Class.getDeclaredClasses() is the answer.

I think this is what you're after: Class.getClasses().

package com.test;
public class A {
public String str;
public class B {
private int i;
}
}
package com.test;
import junit.framework.TestCase;
public class ReflectAB extends TestCase {
public void testAccessToOuterClass() throws Exception {
final A a = new A();
final A.B b = a.new B();
final Class[] parent = A.class.getClasses();
assertEquals("com.test.A$B", parent[0].getName());
assertEquals("i" , parent[0].getDeclaredFields()[0].getName());
assertEquals("int",parent[0].getDeclaredFields()[0].getType().getName());
//assertSame(a, a2);
}
}

Related

Pass Arguments between classes in Java " different packages "

I need to pass an argument between two classes in different packages.
For example, I have an int a in class A in package AA.. I need to pass it to class B in package BB which will change the value of a and pass it back to class A.
Either Use fully qualified class name or import it in another program . E.g if you want to create an object of class A which is in AA package in class B which is in different package, use
AA.A obj = new AA.A();
Now call the method which you want to pass value to, using this obj reference variable.
The above code did not work for me. I had to change the import in package B to make it work.
package BB;
import AA.A;
public class B {
public int change_a(int a){
return a+1;
}
}
You should be passing arguments like this
package AA;
import BB.B;
public class A {
int a = 5;
private void play() {
B b = new B();
// Here we are passing the int argument to a method in different class and different package
int new_a = b.change_a(a);
System.out.println("a after the change is "+ new_a);
}
public static void main(String[] args){
new A().play();
}
}
And your class B
package BB;
import BB.A;
public class B {
public int change_a(int a){
return a+1;
}
}

package access class |(different between public and protected)

if i have a pacakage access class somthing like this:
package AA;
class A {
// ...
}
which is only accessed by classes on package AA. What is the difference between declaring on this class a methods as a protected or public?
Isn't it is the same because the class only accessed from its pacakge ?
Package AA might have a public class B that extends A.
In that case, a class C from a different package may create an instance of B and call any public methods of A for that instance.
If, however, you define methods of A as protected, C would have to be a sub-class of B in order to call those methods.
package AA;
class A
{
public void foo() {}
protected void bar() {}
}
package AA;
public class B extends A
{
}
package BB;
public class C extends B
{
public void func ()
{
super.bar (); // OK, since bar is protected and C extends B
// which extends A
}
public static void main (String[] args)
{
B b = new B();
b.foo(); // OK, since foo is public
b.bar(); // doesn't compile, since bar is protected
}
}
It makes difference when using reflection, like Class.getMethods()

Need to make a Class A which can be instaceated only from G

i Have a class G which will make instance of the classes Like A B C D each classes are in different packages,
While making instance of the A B C D each has different factory methods because arguments are different.
and no other classes can call the factory method of these A B C D classes.
Is any way to do this?
Lets Assume that you have
CLASS B
package com.b;
import com.g.ClassG;
public class ClassB {
private ClassB(int arg1,String arg2){
}
public static ClassB getInstance(Object object) throws Exception {
if(object instanceof ClassG) {
return new ClassB(1, "Shree");
}else {
throw new Exception("instance creation is Only supported for ClassG");
}
}
}
CLASS A
package com.a;
import com.g.ClassG;
public class ClassA {
private ClassA(int arg1){
}
public static ClassA getInstance(Object object) throws Exception {
if(object instanceof ClassG) {
return new ClassA(1);
}else {
throw new Exception("instance creation is Only supported for ClassG ");
}
}
}
Then If you write your class G as below
CLASS G
package com.g;
import com.a.ClassA;
import com.b.ClassB;
public final class ClassG {
public static void main(String args[]) throws Exception {
ClassG gObject = new ClassG();
ClassA aObject = getClassAInstance(gObject);
ClassB bObject = getClassBInstance(gObject);
}
private static ClassB getClassBInstance(ClassG gObject) throws Exception {
return ClassB.getInstance(gObject);
}
private static ClassA getClassAInstance(ClassG gObject) throws Exception {
return ClassA.getInstance(gObject);
}
}
I think above solution would be sufficient for you .
restriction of instance creation is put in factory method
Class G is final hence There would not be any way to create ClassA and ClassB instances except Class G
Let me know your feedback on this
The proper way to do this is to make these classes only have package-private constructors, and only the factories be public.
Packages are the only real way in Java to specify access permissions for related classes.
You'd have to put them all in the same package, though.
One hacky workaround could be to have your factory methods take a G instance as a parameter (and check that it is not null), and make it impossible to create G instances from any other place then G itself.
public class G {
private G (){} // no one can make G instances
public static A makeA(){
return A.publicFactoryThatNeedsG( new G(), theRealParameters);
}
}
Very ugly.
In particular, ties A,B,C,D to G.

Classes sharing the same super class instance

I have a very simple question.
Can 2 classes share the same Super class instance? I know the answer is no, because super is the instance itself, but I was really there was some workaround...
public class Parent{
private final int parentId;
private static final HashMap<Integer,Parent> parentMap = new HashMap<Integer,Parent>();
private Parent(int i){
parentId = i;
parentMap.put(i,this);
}
public static Parent newInstance(int i)
{
if(parentMap.containsKey(i))
return parentMap.get(i);
return new Parent(i);
}
}
/* Other class */
public class ExtendedParent extends Parent{
public ExtendedParent(int i){
super(i);//I should use the factory at this point...
}
public static main(String[] args){
/*What I am trying to achieve*/
Parent p1 = new ExtendedParent(1);
Parent p2 = new ExtendedParent(1);
if(p1.equals(p2))
System.out.println("This is what i aim to get!!!!");
}
}
Remade the code to demonstrate my problem clearly.
Can someone help me out? =D
Thanks in advance!
I see two alternatives:
Make the relevant parent's attributes and methods static, so that they are shared among all descendants.
Replace the parent class with an interface and share an attribute of the original parent class between subclass instances.
Make ExtendedParent instances forward calls to a Parent instance they keep as a member. And methods that should not only forward the calls, add the additional processing that distinguishes ExtendedParent from Parent.
You can use inner class. You can even make several distinct types share same parent class object.This would not be inheritance, but the result will be exactly what you are looking for:
public class Test {
private final String text;
Test(String text) {
this.text = text;
}
public static void main(String[] args) throws Exception {
Test t = new Test("Text");
A a = t.new A();
B b = t.new B();
a.printA();
b.printB();
}
class B {
public void printB() {
System.out.println(text);
}
}
class A {
public void printA() {
System.out.println(text);
}
}
}

Why is javac not complaining about more than one public class per file?

Here's my sample class, that compiles (and runs) with version 1.6.0_14 of Java:
import java.util.List;
import java.util.ArrayList;
public class Sample {
List<InnerSample> iSamples;
public Sample() {
iSamples = new ArrayList<InnerSample>();
iSamples.add(new InnerSample("foo"));
iSamples.add(new InnerSample("bar"));
}
public static void main(String[] args) {
System.out.println("Testing...");
Sample s = new Sample();
for (InnerSample i : s.iSamples) {
System.out.println(i.str);
}
}
public class InnerSample {
String str;
public InnerSample(String str) {
this.str = str;
}
}
}
I know that you're supposed to only have one public class per file in Java, but is this more of a convention than a rule?
You're not allowed to have more than one top-level class per file. InnerSample is an inner class.
This is an example of what is prohibited in a single file:
public class Sample {
}
public class Sample2 {
}
See JLS ยง7.6.
You cannot have more than one top level public class.
Nested/inner classes/interfaces/enums/#annotations don't count.
In your example, InnerSample is an "inner" class. An inner class MUST be inside another class (and thus, inside the outer class' source file).
Because it is an inner public class

Categories

Resources